2015-11-15 58 views
0

我试图使用C#中的套接字发出HTTP请求/响应。 GET请求出现在下面。空http响应正文

StringBuilder sb = new StringBuilder(); 
sb.AppendFormat("GET http://{0}/ HTTP/1.1\r\n", hostname); 
sb.AppendFormat("Host: {0}\r\n", hostname); 
sb.Append("Connection: keep-alive\r\n"); 
sb.Append(@"Accept:text/html,*/*"); 
sb.Append("\r\n\r\n"); 

其中主机是像 'mit.edu' 或 'facebook.com' 或 'google.com' 或其他任何东西。由于一些奇怪的原因,我只有一个状态行(带有200个状态码)和标题作为http响应。但在响应没有邮件正文:attached srceenshot of my console app

下面是与插座进行所有操作,让http请求的方法:

public static void DoHttpGetRequest(String hostname, Int16 port = 80) { 
     IPHostEntry ipHostEntry = Dns.GetHostEntry(hostname); 
     IPAddress ipAdress = ipHostEntry.AddressList[0]; 
     IPEndPoint ipEndPoint = new IPEndPoint(ipAdress, port); 

     Socket socket = new Socket(ipAdress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); 

     socket.Connect(ipEndPoint); 

     String request = CreateRequest(hostname); 

     Byte[] byteRequest = Encoding.UTF8.GetBytes(request); 
     Byte[] byteResponse = new Byte[1000]; 

     int bytesSent = socket.Send(byteRequest); 
     int bytesReceive = socket.Receive(byteResponse); 

     Console.WriteLine(request); 
     Console.WriteLine(); 
     Console.WriteLine(Encoding.UTF8.GetString(byteResponse, 0, bytesReceive)); 

     socket.Shutdown(SocketShutdown.Both); 
     socket.Close(); 
} 

我首先想到的是,插座没有收到全来自服务器的响应。在这种情况下,我仍然不知道如何解决问题。

那么发生了什么事?错误在哪里?

+0

不知道你在这里打电话给什么样的服务,但如果它给你的http代码200这意味着好,那么它一定做了一些事情。可能是服务器端的问题? 你是否拥有这项服务?有没有机会查看@日志或从那里跟踪代码? –

+0

@Tendious,thanx为您的答案。服务不是我的。我为很多不同的服务运行了很多次代码。有senate.gov,ex.ua,mit.edu,google.com,fs.to和其他等。所有这些请求得到了他们的代码200OK或302Found或301和没有消息正文的回应。所以我不确定它是关于服务器端的问题。 – Yevtukhoff

回答

1

不要期望在单个接收中获得完整的响应。你所做的是接收数据,直到你有完整的响应头(这也可能需要几个接收调用),然后解析头以找出响应的时间长度,然后读取必要的响应数据接听电话。而且,由于您正在执行HTTP/1.1请求,您还必须处理分块响应。

我建议更好地使用HTTP库来处理所有问题。如果你坚持全部通过自己阅读the specification of HTTP并据此实施。 它也有助于环顾stackoverflow处理类似的请求,因为对于尝试首次实现HTTP的用户而言,这个问题非常典型,对于套接字,TCP和HTTP的工作原理还不够了解。

+0

RFC 2616已弃用(“*过时:7230,7231,7232,7233,7234,7235 *”)。对于接班人请阅读这里:http://www.w3.org/Protocols/和这里https://tools.ietf。org/html/rfc2616 – alk

+0

@alk:我知道,但指向单个RFC比指向几个更容易。这些RFC规范中的差异很小,任何浏览器的方式都不同于旧规范和新规范。 –

0

我想你应该保持打开更长的时间。插入一个

Thread.Wait(5000); 

可能有所帮助。然后你可以做第二个socket。接受Steffen的建议。也许你可以尝试以下(等到服务器关闭连接):

while (socket.Connected) do 
{ 
    int bytesReceive = socket.Receive(byteResponse); 
} 

但我没有测试这个。它更容易使用System.Net.Http.HttpClient

0

我需要做的一切就是接收数据与多个接收呼叫,直到收到所有的响应信息。

do 
{     
    bytesReceive = socket.Receive(byteResponse, byteResponse.Length, 0); 
    response += Encoding.UTF8.GetString(byteResponse, 0, bytesReceive); 
} 
while (bytesReceive > 0); 

感谢大家的帮助!