2010-03-30 106 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