/// <summary>
/// 使用Socks5代理服务器连接网络
/// </summary>
class SockProxy
{
bool m_RequireAuthorize = false;
string m_user = string.Empty;
string m_pass = string.Empty;
/// <summary>
/// default is false
/// </summary>
public bool RequireAuthorize
{
get { return m_RequireAuthorize; }
set { m_RequireAuthorize = value; }
}
public string Username
{
get { return m_pass; }
set { m_pass = value; }
}
public string Password
{
get { return m_user; }
set { m_user = value; }
}
public bool ConnectProxyServer(string strRemoteHost, int iRemotePort, Socket sProxyServer)
{
//构造Socks5代理服务器第一连接头(无用户名密码)
byte[] bySock5Send = new Byte[10];
bySock5Send[0] = 5;
bySock5Send[1] = 1;
bySock5Send[2] = RequireAuthorize ? (byte)2 : (byte)0;
//发送Socks5代理第一次连接信息
sProxyServer.Send(bySock5Send, 3, SocketFlags.None);
byte[] bySock5Receive = new byte[10];
int iRecCount = sProxyServer.Receive(bySock5Receive, bySock5Receive.Length, SocketFlags.None);
//用户验证
if (bySock5Receive[1] == 2 && !RequireAuthorize)
{
throw new Exception("代理服务器需要进行身份确认。");
}
else if (bySock5Receive[1] == 2)
{
//构造Socks5代理服务器第一连接头(无用户名密码)
byte[] bUser = Encoding.Default.GetBytes(Username);
byte[] bPass = Encoding.Default.GetBytes(Password);
int dl = 3 + bUser.Length + bPass.Length;
bySock5Send = new Byte[dl];
bySock5Send[0] = 5;
bySock5Send[1] = (byte)bUser.Length;
Array.Copy(bUser, 0, bySock5Send, 2, bUser.Length);
bySock5Send[2 + bUser.Length] = (byte)bPass.Length;
Array.Copy(bPass, 0, bySock5Send, 3 + bUser.Length, bPass.Length);
//发送Socks5代理第一次连接信息
sProxyServer.Send(bySock5Send, dl, SocketFlags.None);
bySock5Receive = new byte[100];
iRecCount = sProxyServer.Receive(bySock5Receive, bySock5Receive.Length, SocketFlags.None);
}
if (iRecCount < 2)
{
sProxyServer.Close();
throw new Exception("不能获得代理服务器正确响应。");
}
if (bySock5Receive[0] != 5 || (bySock5Receive[1] != 0 && bySock5Receive[1] != 2))
{
sProxyServer.Close();
throw new Exception("代理服务其返回的响应错误。");
}
if (bySock5Receive[1] == 0)
{
bySock5Send[0] = 5;
bySock5Send[1] = 1;
bySock5Send[2] = 0;
bySock5Send[3] = 1;
IPAddress ipAdd = Dns.Resolve(strRemoteHost).AddressList[0];
string strIp = ipAdd.ToString();
string[] strAryTemp = strIp.Split(new char[] { '.' });
bySock5Send[4] = Convert.ToByte(strAryTemp[0]);
bySock5Send[5] = Convert.ToByte(strAryTemp[1]);
bySock5Send[6] = Convert.ToByte(strAryTemp[2]);
bySock5Send[7] = Convert.ToByte(strAryTemp[3]);
bySock5Send[8] = (byte)(iRemotePort / 256);
bySock5Send[9] = (byte)(iRemotePort % 256);
sProxyServer.Send(bySock5Send, bySock5Send.Length, SocketFlags.None);
iRecCount = sProxyServer.Receive(bySock5Receive, bySock5Receive.Length, SocketFlags.None);
if (bySock5Receive[0] != 5 || bySock5Receive[1] != 0)
{
sProxyServer.Close();
throw new Exception("第二次连接Socks5代理返回数据出错。");
}
return true;
}
else
{
if (bySock5Receive[1] == 2)
throw new Exception("代理服务器需要进行身份确认。");
else
return false;
}
return false;
}
public Socket GetSocket(string strIpAdd, int iPort)
{
IPAddress hostadd = IPAddress.Parse(strIpAdd);//Dns.Resolve(strIpAdd).AddressList[0];
IPEndPoint EPhost = new IPEndPoint(hostadd, iPort);
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
s.Connect(EPhost);
return s;
}
}
//用法示例:
private void Form1_Load(object sender, EventArgs e)
{
string proxyHost = "10.32.32.51";// "10.4.8.1";//
int proxyProt = 1080;
byte[] b;
int rl = 0;
string sr;
SockProxy p = new SockProxy();
{//如果不需要密码验证,略去这段代码
p.RequireAuthorize = true;
p.Username = "jerry";
p.Password = "456321";
}
Socket sRH = p.GetSocket(proxyHost, proxyProt);
p.ConnectProxyServer("10.32.9.16", 9160, sRH);
b = Encoding.Default.GetBytes("GET /WAP/Default.aspx HTTP/1.0");
sRH.Send(b);
b = new byte[4096];
rl = sRH.Receive(b);
sr = Encoding.Default.GetString(b, 0, rl);
MessageBox.Show(sr);
}