C#連線socket代理並轉發訊息
阿新 • • 發佈:2018-12-02
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;
}