2011-03-04 89 views
1

我在写一个客户端,通过常规http multipart/form-data将文件上传到megaupload。现在,重点本身不是互联星空,而是他们的网络服务器的行为。http请求消息的边界

即使发送完全相同的请求(用wireshark进行嗅探),curl可以毫无问题地上传,但我的客户却无法发送 - 但它一直等待响应,最终在30分钟后超时。

玩过原始套接字和strace一段时间后,原来两者之间的唯一区别是curl发送的头部块只有一个调用sendto(2),然后剩下的其他调用sendto (2)。另一方面,我的客户用写(2)分别发送每个头。

现在,sendto和write应该是等效的,如果send没有指定任何标志,并且它没有。事实上,我使用写入工作,但只能通过一次调用发送头部块。每个其他的写入调用序列都会导致请求被阻止等待。

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

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

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

回答

0

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

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

+0

我知道,但这不是我问**的所有**。 – oscar 2011-04-04 09:19:23

+0

那么那么也许你应该澄清你的确切问题:)你问了关于http消息的界限,我给了你一个答案,试图解释http消息的界限。一端的send/sendto等和另一端的recv等之间没有一对一的对应关系。 – seand 2011-04-04 20:31:34

0

这个问题指出了http和tcp之间的区别。我认为所有的http请求头应该在一个tcp消息中。尝试访问网络服务器的调试错误日志