using System;
using System.Net;
using System.Net.Sockets;
using System.Text;/*
* zahmed
* Date 23 Jan 2004
* Socks 5 RFC is available at http://www.faqs.org/rfcs/rfc1928.html.
*/
namespace ConProxy
{
public class ConnectionException : ApplicationException
{
public ConnectionException(string message)
: base(message)
{
}
} /// <summary>
/// Provides sock5 functionality to clients (Connect only).
/// </summary>
public class SocksProxy
{ private SocksProxy() { } #region ErrorMessages
private static string[] errorMsgs = {
"Operation completed successfully.",
"General SOCKS server failure.",
"Connection not allowed by ruleset.",
"Network unreachable.",
"Host unreachable.",
"Connection refused.",
"TTL expired.",
"Command not supported.",
"Address type not supported.",
"Unknown error."
};
#endregion
public static Socket ConnectToSocks5Proxy(string proxyAdress, ushort proxyPort, string destAddress, ushort destPort,
string userName, string password)
{
IPAddress destIP = null;
IPAddress proxyIP = null;
byte[] request = new byte[257];
byte[] response = new byte[257];
ushort nIndex; try
{
proxyIP = IPAddress.Parse(proxyAdress);
}
catch (FormatException)
{ // get the IP address
proxyIP = Dns.GetHostByAddress(proxyAdress).AddressList[0];
} // Parse destAddress (assume it in string dotted format "212.116.65.112" )
try
{
destIP = IPAddress.Parse(destAddress);
}
catch (FormatException)
{
// wrong assumption its in domain name format "www.microsoft.com"
} IPEndPoint proxyEndPoint = new IPEndPoint(proxyIP, proxyPort); // open a TCP connection to SOCKS server...
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
s.Connect(proxyEndPoint); nIndex = 0;
request[nIndex++] = 0x05; // Version 5.
request[nIndex++] = 0x02; // 2 Authentication methods are in packet...
request[nIndex++] = 0x00; // NO AUTHENTICATION REQUIRED
request[nIndex++] = 0x02; // USERNAME/PASSWORD
// Send the authentication negotiation request...
s.Send(request, nIndex, SocketFlags.None); // Receive 2 byte response...
int nGot = s.Receive(response, 2, SocketFlags.None);
if (nGot != 2)
throw new ConnectionException("Bad response received from proxy server."); if (response[1] == 0xFF)
{ // No authentication method was accepted close the socket.
s.Close();
throw new ConnectionException("None of the authentication method was accepted by proxy server.");
} byte[] rawBytes; if (/*response[1]==0x02*/true)
{//Username/Password Authentication protocol
nIndex = 0;
request[nIndex++] = 0x05; // Version 5. // add user name
request[nIndex++] = (byte)userName.Length;
rawBytes = Encoding.Default.GetBytes(userName);
rawBytes.CopyTo(request, nIndex);
nIndex += (ushort)rawBytes.Length; // add password
request[nIndex++] = (byte)password.Length;
rawBytes = Encoding.Default.GetBytes(password);
rawBytes.CopyTo(request, nIndex);
nIndex += (ushort)rawBytes.Length; // Send the Username/Password request
s.Send(request, nIndex, SocketFlags.None);
// Receive 2 byte response...
nGot = s.Receive(response, 2, SocketFlags.None);
if (nGot != 2)
throw new ConnectionException("Bad response received from proxy server.");
if (response[1] != 0x00)
throw new ConnectionException("Bad Usernaem/Password.");
}
// This version only supports connect command.
// UDP and Bind are not supported. // Send connect request now...
nIndex = 0;
request[nIndex++] = 0x05; // version 5.
request[nIndex++] = 0x01; // command = connect.
request[nIndex++] = 0x00; // Reserve = must be 0x00 if (destIP != null)
{// Destination adress in an IP.
switch (destIP.AddressFamily)
{
case AddressFamily.InterNetwork:
// Address is IPV4 format
request[nIndex++] = 0x01;
rawBytes = destIP.GetAddressBytes();
rawBytes.CopyTo(request, nIndex);
nIndex += (ushort)rawBytes.Length;
break;
case AddressFamily.InterNetworkV6:
// Address is IPV6 format
request[nIndex++] = 0x04;
rawBytes = destIP.GetAddressBytes();
rawBytes.CopyTo(request, nIndex);
nIndex += (ushort)rawBytes.Length;
break;
}
}
else
{// Dest. address is domain name.
request[nIndex++] = 0x03; // Address is full-qualified domain name.
request[nIndex++] = Convert.ToByte(destAddress.Length); // length of address.
rawBytes = Encoding.Default.GetBytes(destAddress);
rawBytes.CopyTo(request, nIndex);
nIndex += (ushort)rawBytes.Length;
} // using big-edian byte order
byte[] portBytes = BitConverter.GetBytes(destPort);
for (int i = portBytes.Length - 1; i >= 0; i--)
request[nIndex++] = portBytes[i]; // send connect request.
s.Send(request, nIndex, SocketFlags.None);
s.Receive(response); // Get variable length response...
if (response[1] != 0x00)
throw new ConnectionException(errorMsgs[response[1]]);
// Success Connected...
return s;
}
}
}
调用的时候先用这个类去初始化socket,然后就可以用这个socket通讯了,用的是socket5的代理,你可以自己改成socket4的
解决方案 »
- InstallShield for VS 2010 LE 不支持汉字信息?
- JStree Ztree TreeView树控件的使用问题。
- 为什么我的电脑上的VS2005 不会有错误提示框
- 小妹请教treeview添加节点后直接变成编辑状态。
- varchar为什么不能存这个?'2009-8-13 22:56:52'
- gridview删除,怎么出现outofindex的问题啊
- DragDrop问题,求段代码拖放textBox文字到另一个textBox中
- 怎么样获得路径啊?
- 帮忙解决一下!
- 外企高薪招聘!!外企高薪招聘!!dotnet高级工程师
- 请教FILE.DELETE的问题
- 急!!在vs2005下新建reporting service 出现乱码 ---
WebProxy loProxy = WebRequest.GetSystemWebProxy();
不过默认情况下HttpWebRequest不用设置都会自动使用系统的代理
myRequest.Proxy =.......这里怎么写?.......