空 http 响应 body
Empty http response body
我正在尝试使用 C# 中的套接字制作 HTTP request/response。 GET 请求出现在下方。
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");
其中 hostname 类似于 'mit.edu' 或 'facebook.com' 或 'google.com' 或其他任何内容。出于某种奇怪的原因,我只有一个 status-line(带有 200 状态代码)和 headers 作为 http 响应。但是响应中没有消息body: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();
}
我的第一个想法是套接字没有收到来自服务器的完整响应。在这种情况下,我仍然不知道如何解决问题。
所以这是怎么回事?哪里错了?
不要指望在一次接收中得到完整的响应。您要做的是接收数据,直到获得完整的响应 header(这也可能需要多次接收调用),然后解析 header 以找出响应的长度,然后读取必要的数据的响应也可能需要多个接收呼叫。由于您正在执行 HTTP/1.1 请求,因此您还必须处理分块响应。
我建议最好使用 HTTP 库来处理所有问题。如果您坚持自己完成所有操作,请阅读 the specification of HTTP 并相应地实施。
环顾 Whosebug 以寻找类似的请求也很有帮助,因为您遇到的这个问题对于第一次尝试实现 HTTP 但对套接字、TCP 和 HTTP 的工作原理了解不够的人来说非常典型。
我认为你应该让套接字打开更长时间。插入一个
Thread.Wait(5000);
可能会有帮助。然后您可以按照 Steffen 的建议进行第二个 socket.Receive。也许您可以尝试以下操作(等到服务器关闭连接):
while (socket.Connected) do
{
int bytesReceive = socket.Receive(byteResponse);
}
但是我没有测试这个。使用 System.Net.Http.HttpClient
更容易
我需要做的就是通过多次接收调用接收数据,直到收到所有响应信息。
do
{
bytesReceive = socket.Receive(byteResponse, byteResponse.Length, 0);
response += Encoding.UTF8.GetString(byteResponse, 0, bytesReceive);
}
while (bytesReceive > 0);
感谢大家的帮助!
我正在尝试使用 C# 中的套接字制作 HTTP request/response。 GET 请求出现在下方。
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");
其中 hostname 类似于 'mit.edu' 或 'facebook.com' 或 'google.com' 或其他任何内容。出于某种奇怪的原因,我只有一个 status-line(带有 200 状态代码)和 headers 作为 http 响应。但是响应中没有消息body: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();
}
我的第一个想法是套接字没有收到来自服务器的完整响应。在这种情况下,我仍然不知道如何解决问题。
所以这是怎么回事?哪里错了?
不要指望在一次接收中得到完整的响应。您要做的是接收数据,直到获得完整的响应 header(这也可能需要多次接收调用),然后解析 header 以找出响应的长度,然后读取必要的数据的响应也可能需要多个接收呼叫。由于您正在执行 HTTP/1.1 请求,因此您还必须处理分块响应。
我建议最好使用 HTTP 库来处理所有问题。如果您坚持自己完成所有操作,请阅读 the specification of HTTP 并相应地实施。 环顾 Whosebug 以寻找类似的请求也很有帮助,因为您遇到的这个问题对于第一次尝试实现 HTTP 但对套接字、TCP 和 HTTP 的工作原理了解不够的人来说非常典型。
我认为你应该让套接字打开更长时间。插入一个
Thread.Wait(5000);
可能会有帮助。然后您可以按照 Steffen 的建议进行第二个 socket.Receive。也许您可以尝试以下操作(等到服务器关闭连接):
while (socket.Connected) do
{
int bytesReceive = socket.Receive(byteResponse);
}
但是我没有测试这个。使用 System.Net.Http.HttpClient
更容易我需要做的就是通过多次接收调用接收数据,直到收到所有响应信息。
do
{
bytesReceive = socket.Receive(byteResponse, byteResponse.Length, 0);
response += Encoding.UTF8.GetString(byteResponse, 0, bytesReceive);
}
while (bytesReceive > 0);
感谢大家的帮助!