如何通过TcpClient获取页面?

我正在尝试通过TCP流向页面发送GET请求。

这是我的代码的样子:

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"); 

当我调用此代码时,它总是冻结等待来自服务器的响应。

我究竟做错了什么?

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

certificate:

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

l正在填充请求的第一行。

删除keep-alive标头并添加:

 Connection: close 

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

  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) { } } }