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;

        }

猜你喜欢

转载自blog.csdn.net/qq_25744257/article/details/84299695