1. 程式人生 > >C#連線socket代理並轉發訊息

C#連線socket代理並轉發訊息

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;

        }