sock代理工作原理大致如下:
1。[需要代理方]向服务器发出请求信息;
2。[代理方]应答;
3。[需要代理方]接到应答后发送向[代理方]发送目的ip和端口;
4。[代理方]与目的连接;
5。[代理方]将[需要代理方]发出的信息传到目的方,将目的方发出的信息传到[需要代理方];
6。代理完成。
sock4的TCP代理工作流程:
1。我们首先还是连接服务器,然后发送数据给服务器。由于是无用户密码验证,我们需要发送9个字节的数据,展开写为 04 01 + 目标端口(2字节) + 目标IP(4字节) + 00,其中目标端口和目标IP就是我们真正要连接的服务器端口和服务器地址;
2。代理服务器返回8字节的数据,我们只要判断第二字节是否为90即可,若是90连接成功,否则失败.剩下的操作和不存在代理服务器一样,可直接用发送\接受数据。
1 通过端口号连接代理服务器
System.Net.Sockets.Socket VSocket = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
VSocket..Connect(_proxyHost, _proxyPort);
2 发送字节数据给服务器验证,这里是socket4连接,返回第二字节为90代表连接成功
internal virtual void SendCommand(NetworkStream proxy, byte command, string destinationHost, int destinationPort, string userId)
{
if (userId == null)
userId = "";
byte[] destIp = GetIPAddressBytes(destinationHost);
byte[] destPort = GetDestinationPortBytes(destinationPort);
byte[] userIdBytes = ASCIIEncoding.ASCII.GetBytes(userId);
byte[] request = new byte[9 + userIdBytes.Length];
// set the bits on the request byte array
request[0] = SOCKS4_VERSION_NUMBER;
request[1] = command;
destPort.CopyTo(request, 2);
destIp.CopyTo(request, 4);
userIdBytes.CopyTo(request, 8);
request[8 + userIdBytes.Length] = 0x00; // null (byte with all zeros) terminator for userId
// send the connect request
proxy.Write(request, 0, request.Length);
// wait for the proxy server to respond
WaitForData(proxy);
byte[] response = new byte[8];
// read the resonse from the network stream
proxy.Read(response, 0, 8);
// evaluate the reply code for an error condition
if (response[1] != SOCKS4_CMD_REPLY_REQUEST_GRANTED)
HandleProxyCommandError(response, destinationHost, destinationPort);
}
3 组装http请求头发送给代理服务器。
var str="GET http://10.100.110.144/ HTTP/1.1\r\nAccept: text/html, application/xhtml+xml, */*\r\nAccept-Language: zh-CN\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko\r\nAccept-Encoding: gzip, deflate\r\nHost: 10.100.110.144\r\nDNT: 1\r\nProxy-Connection: Keep-Alive\r\n\r\n"
VSocket.Send(str);
4 获取返回信息
Restr = Receive(VSocket);
private string Receive(Socket socketSend)
{
string str = "";
while (true)
{
byte[] buffer = new byte[10000];
//实际接收到的字节数
int r = socketSend.Receive(buffer);
str+= Encoding.Default.GetString(buffer, 0, r - 1);
if (r< 10000)
{
break;
}
}
return str;
}