【问题标题】:http request message boundarieshttp请求消息边界
【发布时间】:2011-03-04 18:19:17
【问题描述】:

我正在编写一个客户端,通过常规的 http multipart/form-data 将文件上传到 megaupload。现在,重点不是 megaupload 本身,而是他们的网络服务器的行为。

Curl 可以毫无问题地上传,而我的客户端则不能,即使发送完全相同的请求(用 wireshark 嗅探)——但它在等待响应时卡住了,最终在 30 分钟后超时。

在使用了原始套接字和 strace 一段时间后,事实证明两者之间的唯一区别是 curl 仅通过一次调用 sendto(2) 发送标头块,然后其他调用 sendto( 2)。另一方面,我的客户端使用 write(2) 分别发送每个标头。

现在,sendto 和 write 应该是等价的,如果 send 没有指定任何标志,但它没有。事实上,我使它与 write 一起工作,但仅通过在单个调用中发送标头块。每隔一个写入调用序列都会导致请求等待等待。

所以问题是:这怎么可能? Tcp 不保留消息边界,它是一种流协议。

我唯一能想到的是,每次写入/发送系统调用都会发送一个数据包,而远程服务器正在嗅探原始数据包并谎称自己是 apache。

想法?还是我是个白痴,这是兼容 http 服务器的正常行为? 它肯定是第一个对我如此行事的网络服务器。

【问题讨论】:

    标签: http tcp webserver httpclient


    【解决方案1】:

    http 协议包含一些机制,因此客户端/服务器可以确定消息边界。 对于上传的数据(POST、PUT),需要内容长度请求标头或分块编码。 content-length 让服务器确切地知道要从套接字接收多少字节。一旦收到这些字节,它将向另一个方向发送。这实际上是这里的消息边界。 Chunked-encoding 也告诉服务器有多少字节;分几块。

    对于响应,内容长度(或分块编码)是可选的。这也告诉客户端需要多少字节;这是持久连接工作所必需的。如果无法确定内容长度,服务器只是关闭套接字,那么客户端就知道它有整个响应:)

    【讨论】:

    • 我知道,但这不是我问的根本
    • 那么也许你应该澄清你的确切问题:) 你问的是http消息边界,我给了你一个试图解释http消息边界的答案。一端的 send/sendto 等与另一端的 recv 等之间没有一一对应的关系。
    【解决方案2】:

    问题指向http和tcp的区别。我认为所有 http 请求标头都应该在一个 tcp 消息中。尝试访问 Web 服务器的调试错误日志

    【讨论】:

      猜你喜欢
      • 2013-06-21
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      • 2012-03-22
      • 2017-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多