http请求消息边界

时间:2011-03-04 18:19:17

标签: http tcp webserver httpclient

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

Curl可以上传没有任何问题,而我的客户端不能,即使发送完全相同的请求(用wireshark嗅探) - 但它等待响应,并最终在30分钟后超时。

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

现在,sendto和write应该是等价的,如果send没有指定任何标志,那么它不会。事实上,我使用write,但只能通过一次调用发送头块。每隔一个写入调用序列都会导致请求停滞不前。

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

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

想法?或者我是一个白痴,这是一个兼容的http服务器的正常行为? 它肯定是第一个对我这样做的网络服务器。

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

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