2012-08-25 48 views
4

我想通过TCP流向页面发送GET请求。如何通过TcpClient获取页面?

这里是我的代码如下所示:

public class SocketLevelWebClient 
{ 
    public string SendWebRequest(string url, string request) 
    { 
     using(TcpClient tc = new TcpClient()) 
     { 
      tc.Connect(url, 80); 

      using (NetworkStream ns = tc.GetStream()) 
      { 
       using (System.IO.StreamWriter sw = new System.IO.StreamWriter(ns)) 
       { 
        using (System.IO.StreamReader sr = new System.IO.StreamReader(ns)) 
        { 
         sw.Write(request); 
         sw.Flush(); 
         return sr.ReadToEnd(); 
        } 
       } 
      } 
     } 
    } 

和请求本身:

  SocketLevelWebClient wc = new SocketLevelWebClient(); 
      var r=wc.SendWebRequest("www.youtube.com",@"GET http://www.youtube.com/ HTTP/1.1 
Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, */* 
Accept-Language: en-US 
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E) 
Accept-Encoding: gzip, deflate 
Connection: Keep-Alive 
Host: www.youtube.com"+"\r\n\r\n"); 

当我把这个代码,它总是冻结等待服务器的响应。

我在做什么错?

+0

任何你不能使用HttpWebRequest的原因? – usr

+1

因为我想了解TcpClient是如何工作的,并且用它下载网页似乎对我来说是个好主意 –

+0

您不发送'Content-Length',也不使用'ReadToEnd',使用响应头来确定响应的长度。 –

回答

6

问题是ReadToEnd仅在流结束时返回。不幸的是,服务器保持TCP连接处于活动状态。因此ReadToEnd永远不会检测到真正的结束已经到达。

证明:

     sw.Write(request); 
         sw.Flush(); 
         var l = sr.ReadLine(); 

l被填充与该请求的第一行。

卸下keep-alive头和添加:

Connection: close 

或者使用响应Content-Length头正确读取(二进制)。

1
A simple example is this: 

    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
    using System.Threading.Tasks; 
    using System.IO; 
    using System.Net; 
    using System.Net.Sockets; 
    using System.Web; 
    using System.Data; 
    using System.Collections; 
    using System.Collections.Specialized; 
    using System.Windows.Forms; 

    //Some "using" may not be needed 
    static public TcpListener listener = new TcpListener(IPAddress.Any, 8080); 

    static void Main(string[] args) 
      { 
      listener.Start(); 
      TcpClient client = listener.AcceptTcpClient(); 
      StreamReader sr = new StreamReader(client.GetStream()); 
      sr.ReadLine(); 
      } 



**For asynchronous Connection:** 


static void Main(string[] args) 
    { 
     client_listener(); 
    } 
async static public void client_listener() 
     { 
      while (true) 
      { 
       listener.Start(); 
       TcpClient client = await listener.AcceptTcpClientAsync(); 
       StreamReader sr = new StreamReader(client.GetStream()); 
       try 
       { 
        await sr.ReadLineAsync(); 
       } 
       catch(Exception e) 
       { 
       } 
     } 
} 
相关问题