2010-03-30 66 views
1

我遇到奇怪的行为通过socket做的HTTP请求时,此请求: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) 

最后两个步骤可以重复几次。所以我想问一下为什么会导致socket的模式改变?而在这种情况下,它不是一个大问题,但是当我使用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

小的一点,但示例URL应使用RFC2606保留域之一[http://www.rfc-editor.org/rfc/rfc2606.txt],如example.com - 保证永远不会指向活的域名如果有人在任何地方做任何事情复制/粘贴示例代码 – Gareth 2010-03-30 07:43:46

+0

行动,我很抱歉,换成正确的:)我的问题呢? – hoodoos 2010-03-30 07:45:23

回答

2

套接字变得只要有插座发送缓冲区的空间所取代。 OS不能真正知道你的应用程序是否有更多的数据要发送,但知道它的内部结构,比如套接字缓冲区。您必须明确添加/删除套接字以写入fd_set,select(2)(启用/禁用事件epoll(4))。这通常用状态机来处理,如在libevent中那样。此外,轮询最适合非阻塞插座。

希望这会有所帮助。

+0

谢谢你! =)我实际上想到了缓冲自己的事情,但很高兴在这里看到一位专家! – hoodoos 2010-04-02 11:39:24

+0

如果我有问题,有什么方法可以与您联系吗? :) – hoodoos 2010-04-02 11:41:44

+0

我在c#上写我的解决方案,并使用阻塞套接字,但从循环读取缓冲区循环套接字。我想这不是最好的解决方案,但如果与使用线程的异步调用进行比较,它仍然表现出优异的性能。我可以在一个线程中处理500个套接字,并且在循环时间上没有宝贵的开销。而我的处理器感觉非常好,平均只有10%的负载:)我希望直接从套接字发送/接收,但我不想自己实现SSL,我使用SSLStream。如果您有任何建议,我很乐意听到他们! – hoodoos 2010-04-02 11:50:53