通过套接字执行HTTP请求时遇到奇怪的行为,请求:
POST https://example.com:443/service/XMLSelect HTTP/1.1
Content-Length: 10926
Host: example.com
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 1.0.3705)
Authorization: Basic XXX
SOAPAction: http://example.com/SubmitXml
稍后我会根据给定的内容长度提出请求。 之后我收到了类似的内容:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/xml;charset=utf-8
Transfer-Encoding: chunked
Date: Tue, 30 Mar 2010 06:13:52 GMT
所以这里的一切似乎都很好。我从网络流中读取所有内容并成功接收响应。但我正在进行轮询的套接字切换它的模式是这样的:
write ( i write headers and request here )
read ( after headers sent i begin to receive response )
write ( STRANGE BEHAVIOUR HERE. WHY? here i send nothing really )
read ( here it switches to read back again )
最后两个步骤可以重复几次。所以我想问一下套接字模式改变的原因是什么?在这种情况下,它不是一个大问题,但是当我在我的请求中使用gzip压缩(不知道它是如何相关的)并要求服务器像这样向我发送gzip响应时:
POST https://example.com:443/service/XMLSelect HTTP/1.1
Content-Length: 1076
Accept-Encoding: gzip
Content-Encoding: gzip
Host: example.com
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 1.0.3705)
Authorization: Basic XXX
SOAPAction: http://example.com/SubmitXml
我收到这样的回复:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Encoding: gzip
Content-Type: text/xml;charset=utf-8
Transfer-Encoding: chunked
Date: Tue, 30 Mar 2010 07:26:33 GMT
2000
�
我收到一个块大小和GZIP标题,一切都没问题。这就是我可怜的小插座发生的事情:
write ( i write headers and request here )
read ( after headers sent i begin to receive response )
write ( STRANGE BEHAVIOUR HERE. And it finally sits here forever waiting for me to send something! But if i refer to HTTP I don't have to send anything more! )
它与什么有关?它要我发送什么?它是远程Web服务器的问题还是我错过了什么?
PS所有实际的服务引用和登录/密码都替换为假的:)
答案 0 :(得分:2)
当套接字发送缓冲区中有空间时,套接字变为可写。操作系统无法确切知道您的应用程序是否有更多数据要发送,但知道其内部结构,如套接字缓冲区。您必须为fd_set
(select(2)
启用/禁用EPOLLOUT
事件)的显式添加/删除套接字epoll(4)
。这通常使用状态机来处理,就像在libevent中一样。此外,轮询最适合使用非阻塞套接字。
希望这有帮助。