2010-04-21 34 views
2

我對這個問題有另一個問題,但我沒有正確地問,所以在這裏我再次去!奇怪的發送()問題(使用Wireshark日誌)

我發送的文件是通過大塊發送的。現在,我正在用不同的數字來計算該塊的大小,以查看哪種大小最有效。

在本地主機上測試時,任何塊大小似乎都正常工作。但是當我通過網絡測試它時,最大塊大小似乎是8191字節。如果我嘗試更高,轉移變得極其痛苦,緩慢。

爲了說明會發生什麼,當我使用8191字節的塊大小以及使用8192字節的塊大小時,以下是Wireshark日誌的前100行:(發送方爲192.168.0.102,接收方是192.168.0.100)

8191:http://pastebin.com/E7jFFY4p

8192:http://pastebin.com/9P2rYa1p

注意如何在8192日誌中,線路33上,接收器需要很長的時間到ACK的數據。這在103行和132行再次發生。我相信這個延遲是問題的根源。

請注意,我沒有修改SO_SNDBUF選項,也沒有修改TCP_NODELAY選項。

所以我的問題是,爲什麼我在發送8192字節塊文件時延遲應答,當使用8191字節的塊時,一切正常?

+0

你能展示一些代碼嗎?這可能會讓我們知道發生了什麼。另外,你的代碼是否在雙方運行?或者只是連接的一側? – Pretzel 2010-04-22 21:02:25

+0

我加了一些相關章節的僞代碼。 – Meta 2010-04-23 00:00:18

回答

1

我想通了!首先由我自己,再經過一些挖掘,我發現這一點: http://support.microsoft.com/kb/823764

什麼是實際發生的情況是,因爲Winsock的分配的發送緩衝區是默認情況下(我的機器上)正好8192個字節,當我把緩衝區中的字節數量(實際上完全填滿了它),下一個send()將給出WSAEWOULDBLOCK。然後,一旦字節被確認,我將只收到下一個FD_WRITE。

但是與此同時,由於延遲的ACK算法,接收機沒有發送ACK。這使得傳輸陷入200毫秒的死鎖,之後接收機器最終確認數據,然後允許發送功能接收FD_WRITE。

當然,所有這一切都不會發生,當我使用8191字節,因爲我沒有填滿整個緩衝區,因此下一個send()沒有阻塞。這意味着Winsock將始終保持發送數據,以便延遲的ACK算法從未在接收端踢入(除了最後一個數據包,如果它是奇數數據包)。

希望這可以幫助其他人解決我遇到的同樣問題。

0

檢查您的網卡和交換機上的「流量控制」設置。如果它打開,它可能是你的問題的原因。

爲了正確解剖您需要在傳輸的兩端運行wireshark。

+0

我在兩臺機器上都關閉了流量控制的情況下再次嘗試。同樣的結果。我將嘗試在Wireshark上再次進行測試併發布日誌。 – Meta 2010-04-23 14:55:47