2017-08-05 23 views
6

Bir proxy'ye bağlanıyorum ve connect komutuyla bazı özel başlıklar gönderiyorum. Bu bir şarttır. 200 yanıtım var. Daha sonra, bir get isteği yapmak için aynı bağlantıyı kullanmaya çalışıyorum ("GET {0}" için ekli kodu arayın) fakat her zaman "bağlantıyı kapatan" biten bir hata alıyorum (tam hatayı doğru olarak hatırlayamıyorum). aslında https: \ www.somesecuresite.com gibi bir websit için tünel gerekiyor. Breviaty için bazı parçalar hariç tutulmuştur.HTTP tünellemesi yapılırken bağlantı nasıl açık tutulur

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

Sunucu bir "Bağlantı: canlı tut" başlığıyla yanıt veriyor mu? Değilse o zaman muhtemelen bunu desteklemiyor .. –

+1

Ayrıca bunu elle yaptığınızı ve 'System.Net.WebRequest' kullanmıyor olmanın bir nedeni var mı? –

+1

[This] (https://stackoverflow.com/questions/19155201/http-keep-alive-timeout) yardımcı olabilir. – Shanky

cevap

10

Http Bağlantısı nedeniyle belirli bir süre sonra otomatik kapanma bağlantısının doğası yakın olsun, sen yine sunucudan sunucuya bağlıdır bağlantı için autclosing süresini artırarak yaklaşık dışında yapabileceği pek bir şey yoktur. sonunda bağlantı süresi biter.

FTP Bağlantısı Eğer cehennem gerektiren bir veri yüklemek veya yüklemek istiyorsanız, sadece aynı nedenden ötürü daha iyi bir FTP bağlantısı kullanın.

6

Başlıklarınızın niteliğine bağlı olarak,kullanarak custom authorization headers gönderebilirsiniz. WebSocket aynı bağlantı tam dubleks haberleşme (veri indirme ve yükleme ikisi) izin vermelidir kullanılacak tasarlandığı için

, bir HTTP bağlantısı daha uygundur.

İlgili konular