C# socket 에이전트를 연결하고 메시지 전달

3837 단어 c#
sock 프록시 작업 원리는 대체로 다음과 같다.[에이전트 필요] 서버에 요청 메시지 보내기;이.[대리측] 응답;삼.[에이전트 필요] 응답을 받고 [에이전트] 발송 목적 IP와 포트로 보내기;사.[에이전트] 목적과 연결;오.[대리인] [대리인 필요]가 보낸 정보를 목적자에게 전달하고 목적자가 보낸 정보를 [대리인 필요]에게 전달한다.육.대리 완성.
sock4의 TCP 에이전트 워크플로우: 1.우리는 우선 서버를 연결한 후에 데이터를 서버에 발송한다.사용자 암호 인증이 없기 때문에 우리는 9바이트의 데이터를 보내서 0401+목표 포트(2바이트)+목표 IP(4바이트)+00로 써야 한다. 그 중에서 목표 포트와 목표 IP는 우리가 진정으로 연결하고자 하는 서버 포트와 서버 주소이다.이.프록시 서버는 8바이트의 데이터를 되돌려줍니다. 우리는 2바이트가 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
Accept: text/html, application/xhtml+xml, */*\r
Accept-Language: zh-CN\r
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko\r
Accept-Encoding: gzip, deflate\r
Host: 10.100.110.144\r
DNT: 1\r
Proxy-Connection: Keep-Alive\r
\r
" 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;

        }

이렇게 하면 성능이 매우 낭비되니, 아래의 이런 작법으로 바꾸어라
        private string Receive(Socket socketSend)
        { 
            string recvStr = "";
            byte[] recvBytes = new byte[1024];
            int bytes;
            do
            {
                bytes = socketSend.Receive(recvBytes, recvBytes.Length, 0); // 
                recvStr += Encoding.UTF8.GetString(recvBytes, 0, bytes);   // 
            } while (bytes == 1024); 
            return recvStr; 
        }

1 순환 밖에서 수조 수신 데이터 성명
2 수신 그룹 길이로 문자열로 변환

좋은 웹페이지 즐겨찾기