2017-08-05 66 views
6

我连接到代理服务器,并使用connect命令发送一些自定义标头。这是一项要求。我收到了200个回复。然后,我尝试使用相同的连接来执行获取请求(搜索附加代码“GET {0}”),但我总是得到一个错误,最终导致“连接关闭”(不能准确回忆确切的错误)。从本质上讲,我需要通过隧道访问https:\ www.somesecuresite.com这样的网站。 breviaty被排除某些部分。如何在进行HTTP隧道时保持连接打开

using (TcpClient client = new TcpClient(proxy, proxyPort)) 
      { 
       using (NetworkStream stream = client.GetStream()) 
       { 
        string EncodedData = encodeUIDPWD(UserName, Password); 
        #region Establish Tcp tunnel 

        string reqString = "CONNECT {0}:{1} HTTP/1.1\r\nProxy-Authorization:Basic " + EncodedData + "\r\nHost: {2}:{3}\r\n"; 
        reqString += "Proxy-Connection: keep-alive\r\n"; 
        reqString += "Connection: keep-alive\r\n"; 
        reqString += "Header1: " + header1 + "\r\n"; 
        reqString += "Header2: " + header2 + "\r\n"; 
        reqString += "None: " + None + "\r\n\r\n"; 

        string rString = String.Format(reqString, myUri.Host, myUri.Port, myUri.Host, myUri.Port); 
        #endregion 
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; 
        string reqConnectResult = await DoRequest(myUri, stream, rString); 

        lines.AddRange(reqConnectResult.Split(new string[] { Environment.NewLine }, StringSplitOptions.None).ToList()); 

        if (!lines[0].Contains("200")) 
        { 
         //Error code gets caterd for here e.g 503 etc 
        } 
        else 
        { 
         foreach (string line in lines) 
         { 
          if (line.Contains("X-ProxyMesh-IP: ")) 
          { 
           ip = line.Replace("X-ProxyMesh-IP: ", string.Empty); 
          } 
         } 

         string reqString1 = "GET {0} HTTP/1.1\r\nHost: {1}:{2}\r\n"; 
         reqString1 += "Proxy-Connection: keep-alive\r\n"; 
         reqString1 += "Connection: keep-alive\r\n\r\n"; 

         string rString1 = string.Format(reqString1, myUri.PathAndQuery, myUri.Host, myUri.Port); 
         string reqPageResult = await DoRequest(myUri, stream, rString1); 


         lines.AddRange(reqPageResult.Split(new string[] { Environment.NewLine }, StringSplitOptions.None).ToList()); 
         response.Content = new StringContent(lines.ToString()); 

         if (lines[0].Contains("200")) 
         { 
          return new Tuple<bool, HttpResponseMessage>(true, response); 
         } 
         else 
         { 
          return new Tuple<bool, HttpResponseMessage>(false, response); 
         } 
        } 
       } 
      } 

private async Task<string> DoRequest(Uri myUri, NetworkStream stream, string reqString) 
{ 

    byte[] tunnelRequest = Encoding.UTF8.GetBytes(reqString); 

    await stream.WriteAsync(tunnelRequest, 0, tunnelRequest.Length); 
    await stream.FlushAsync(); 


    using (var memory = new MemoryStream()) 
    { 
     await stream.CopyToAsync(memory); 

     memory.Position = 0; 
     var data = memory.ToArray(); 

     //Basically just gets the header part. 
     int bm = BinaryMatch(data, Encoding.ASCII.GetBytes("\r\n\r\n")); 
     var index = bm + 4; 
     if (bm == -1) 
     { 
      index = 0; 
     } 

     var headers = Encoding.ASCII.GetString(data, 0, index); 
     memory.Position = index; 

     Console.WriteLine(headers); 
     if (headers.IndexOf("Content-Encoding: gzip") > 0) 
     { 
      using (GZipStream decompressionStream = new GZipStream(memory, CompressionMode.Decompress)) 
      using (var decompressedMemory = new MemoryStream()) 
      { 
       decompressionStream.CopyTo(decompressedMemory); 
       decompressedMemory.Position = 0; 
       string s = (Encoding.UTF8.GetString(decompressedMemory.ToArray())); 
       Console.WriteLine(s); 

       return headers + s; 
      } 
     } 
     else 
     { 
      string s = (Encoding.UTF8.GetString(data, index, data.Length - index)); 
      Console.WriteLine(s); 

      return headers + s; 
     } 
    } 
}   
+1

服务器是否以“Connection:keep-alive”的标题响应?如果不是,那么它可能不支持它.. –

+1

还有什么原因,你是这样做手动和不使用'System.Net.WebRequest'? –

+1

[This](https://stackoverflow.com/questions/19155201/http-keep-alive-timeout)可能会有所帮助。 – Shanky

回答

10

HTTP连接由于经过特定的时间自动关闭连接的性质接近,没有太多可以从增加autclosing持续时间连接这又依赖于服务器到服务器办分开。最终在连接时间结束。

FTP连接如果你想上传或下载需要很多时间的数据,最好使用FTP连接,它只存在于相同的原因。

6

根据您的标题的性质,您可以考虑使用WebSockets,因为您可以发送custom authorization headers

由于在相同的连接应该允许全双工通信(数据下载和上传)时使用WebSocket,所以它比HTTP连接更合适。