2010-06-08 26 views
6

我們有一個應用程序服務器,在網絡發生擁塞時(在客戶端站點),觀察到發送TCP窗口大小爲0的報頭。誰將TCP窗口大小設置爲0,Indy或Windows?

我們想知道它是Indy還是負責調整TCP窗口大小從標稱64K調整到可用吞吐量的底層Windows層。
而且我們可以在它變爲0時採取行動(沒有任何事情發送,用戶等待=>不好)。

因此,任何信息,鏈接,指向印碼,歡迎...

免責聲明:我不是一個網絡專家。請保持這個答案對我來說是可以理解的;-)
注意:它是Windows Server 2003 SP2上的Indy9/D2007。

更多血淋淋的細節:
TCP零窗口情況發生在與DB服務器通話的中間層。
它發生在最終用戶抱怨客戶端應用程序變慢的相同時刻(這是觸發網絡調查的原因)。
已經確定了導致瓶頸的兩個主要網絡問題。
TCP零窗口發生在有網絡擁塞時,但可能由或可能不是由它造成的。
我們想知道什麼時候發生,並且有辦法在代碼中執行某些操作(至少記錄日誌)。

因此,核心問題是誰將窗口大小設置爲0以及在哪裏?
哪裏掛鉤(在印地?)知道什麼時候發生這種情況?

回答

6

TCP報頭中的窗口大小無法由TCP堆棧軟件設置以反映可用緩衝區空間的大小。如果您的服務器發送窗口設置爲零的數據包,可能是因爲客戶端發送數據的速度比在服務器上運行的應用程序正在讀取的速度更快,並且與TCP連接關聯的緩衝區現在已滿。

如果客戶端發送數據的速度比服務器能夠讀取的速度快,那麼這對於TCP協議來說是非常正常的操作。客戶端應該避免發送數據,直到服務器發送非零窗口大小(沒有意義,因爲它將被丟棄)。

這可能會也可能不會反映客戶端和服務器之間的嚴重問題,但是如果這種情況持續存在,則可能意味着服務器上運行的應用程序已停止讀取接收到的數據(一旦它開始讀取,就釋放了緩衝區空間TCP,並且TCP堆棧將發送新的非零窗口大小)。

+0

核心問題是誰將窗口大小設置爲0以及在哪裏?更新問題... – 2010-06-08 22:11:34

+3

TCP堆棧(在本例中是Windows Server的一部分)將窗口大小設置爲零,但是這是因爲運行在服務器上的應用程序(Indy?)沒有讀取數據。 – 2010-06-08 22:35:31

+0

因此,如果中間層由於網絡阻塞而無法傳送到客戶端應用程序,它可能會停止讀取來自數據庫服務器的數據,然後該數據庫會導致操作系統將tcp窗口大小設置爲0 ...並且每個人都在等待事情變好。對? – 2010-06-09 00:22:05

2

窗口大小爲零的TCP報頭指示接收方的緩衝區已滿。對於比讀者更快的作家來說,這是一個正常的條件。

在閱讀您的描述時,並不清楚這是否意外。是什麼導致你打開協議分析器?

+0

一些在這裏或那裏似乎沒有問題,但是當它發生時,在同一秒內有40個。當最終用戶抱怨客戶端應用程序明顯減速時,觸發了調查。在網絡層面確定了2個可能導致瓶頸的專業問題。但是TCP零窗口可能會或可能不會由這些條件引起,無論如何,我們希望知道它何時發生,並且能夠至少記錄一些信息。 – 2010-06-08 20:44:45

2

既然你可能會感興趣的解決您的問題,太:

如果您有什麼在服務器端運行(即發送0窗口大小的消息一)一些控制: 你考慮使用setsockopt()和SO_RCVBUF來顯着增加套接字接收緩衝區的大小?

在Indy中,setsockopt()是TIdSocketHandle的一個方法。 您應該將其應用於與您的套接字關聯的所有TIdSocketHandle對象。 而在Indy 9中,這些通過TIdTCPServer中的屬性綁定來定位。

我建議首先使用getsockopt()和SO_RCVBUF來查看OS爲您提供的默認緩衝區大小。然後顯着增加這一點,可能會通過連續試驗,每次增加一倍。 您可能還希望在之後重新運行getsockopt()調用以確保您的setsockopt實際上已執行:通常情況下,套接字實現設置爲緩衝區大小的上限。在這種情況下,通常有一種依賴於操作系統的方式來提高上限值。但是那些情況相當極端,你不太可能需要這個。

如果您無法控制溢出端的源代碼,只需檢查運行在那裏的軟件是否暴露了一些參數來更改緩衝區大小。

祝你好運!

+0

感謝這非常有價值的信息 – 2010-06-10 18:01:56