HTTP 1.1 请求消息无法获取最后一个字节块,同时通过套接字获取结果

本文关键字:获取 结果 套接字 字节 消息 请求 HTTP 最后一个 | 更新日期: 2023-09-27 18:31:19

这是我的暂存代码:

using System;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace SocketsDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Uri uri;
            if (args.Any()) uri = new Uri(args[0]);
            else uri = new Uri("http://odetocode.com/Articles/473.aspx"); //http://www.odetocode.com
            var result = GetResource(uri);
            Console.WriteLine(result);
            Console.ReadLine();
        }
        private static string GetResource(Uri uri)
        {
            var host = uri.Host;
            var resource = uri.PathAndQuery;
            var hostEntry = Dns.GetHostEntry(host);
            var socket = CreateSocket(hostEntry);
            SendRequest(socket, host, resource);
            return GetResponse(socket);
        }
        private static Socket CreateSocket(IPHostEntry hostEntry)
        {
            const int HTTP_PORT = 80;
            var endPoint = new IPEndPoint(hostEntry.AddressList[0], HTTP_PORT);
            var socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            socket.Connect(endPoint);
            return socket.Connected ? socket : null;
        }
        private static void SendRequest(Socket socket, string host, string resource)
        {
            var requestMessage = String.Format(
                "GET {0} HTTP/1.1'r'n" +
                "HOST: {1}'r'n" +
                "'r'n", resource, host);
            var requestBytes = Encoding.ASCII.GetBytes(requestMessage);
            socket.Send(requestBytes);
        }
        private static string GetResponse(Socket socket)
        {
            int bytesCount = 0;
            var buffer = new byte[256];
            var result = new StringBuilder();
            do
            {
                bytesCount = socket.Receive(buffer);
                result.Append(Encoding.ASCII.GetString(buffer, 0, bytesCount));
            } while (bytesCount > 0);
            return result.ToString();
        }
    }
}

当我将SendRequest方法中请求消息的 HTTP 部分更改为 HTTP/1.0 时 - 一切正常。但是当我尝试在HTTP/1.1上重复此操作时,此块do { .. } while (bytesCount > 0)在181周期上挂起。看起来服务器或客户端无法处理最后一个字节块。谁能解释一下这背后的原因,以及我如何通过对现有代码的最小更改来修复它。

HTTP 1.1 请求消息无法获取最后一个字节块,同时通过套接字获取结果

这是http的保持活动"功能"。服务器在发送消息后不会断开连接,让您等待进一步的数据。

您必须解析 HTTP 标头。如果有 Transfer-Encoding: chunked ,则必须解析收到的块,直到收到 0 字节的块。

如果它不是作为块发送的,则必须解析 Content-Length 标头以查看要读取的总字节数。

HTTP/

1.0 不支持块,一些客户端不支持保持连接活动,因此对于 HTTP/1.0,默认服务器行为应该是保持活动状态off,而对于 HTTP/1.1,默认值为 on

见 http://en.wikipedia.org/wiki/Chunked_transfer_encoding