2010-06-10 50 views
1

這是一個比特定的代碼問題更多的設計問題,我敢肯定我錯過了明顯的,我只需要另一組眼睛。Winsock WSAAsyncSelect發送沒有無限的緩衝區

我寫基於WSAAsyncSelect多客戶端服務器,每個連接都被製作成我寫了一個連接類,它包含相關的設置和緩衝區等對象

我的問題是關於FD_WRITE,我瞭解它運行:建立連接後立即發送一個FD_WRITE。此後,您應該發送,直到收到WSAEWOULDBLOCK,在此處您將要發送的內容保存在緩衝區中,然後等待被告知可以再次發送。

這是我遇到問題的地方,我在每個連接對象內製作這個保持緩衝區有多大?直到收到一個新的FD_WRITE的時間量是未知的,我可能會嘗試在這段時間內發送很多東西,並一直添加到我的傳出緩衝區中。如果我使緩衝區動態化,如果出於某種原因,內存使用可能會失控,我無法發送()並減少緩衝區。

所以我的問題是你通常如何處理這種情況?注意我不是在談論winsock使用的網絡緩衝區本身,而是我自己創建的一個用於「發送」隊列的緩衝區。

希望我解釋得很好,謝謝大家!

回答

0

當然,正確的設計取決於您的應用程序的性質。

某些程序可以預測在必須完成某些操作之前可以生成的數據量,因此它們可以使用固定大小的緩衝區。例如,我設計的一個協議有一個命令響應結構和一個2字節長度的前綴,所以我可以使用64K緩衝區,並知道我永遠不會溢出它們。如果緩衝區已滿,程序必須先等待應答,然後才允許從該緩衝區發送數據,因此不會再向該緩衝區添加任何數據。

固定大小緩衝區的另一個好處是數據來自另一個I/O源。考慮一個Web服務器:在最基本的情況下,它會從磁盤中汲取文件並將它們吐出電線。因此,您知道您一次從磁盤讀取多少內容,因此您知道緩衝區的大小必須是多少。

我有麻煩想出使用動態緩衝區的好理由。

你不需要它們的主要原因是TCP's sliding window。如果其中一個連接節點停止接收數據,則當TCP窗口填滿時,遠程節點的堆棧將停止發送數據。未讀數據將保留在接收堆棧的緩衝區中,直到發送給它的程序請求它爲止。這爲接收器提供了一種方法來將輸入數據調節到可以處理的水平。據我所知,這使得固定大小的緩衝區在所有條件下都很實用。

+0

嗨,謝謝你的回答。我的應用程序設置類似,數據包被定義爲size-instruction-data,每個數據最多可達64k,因此對於接收,我可以輕鬆定義最大緩衝區大小。 這給我留下了另一個我不確定如何回答的問題。它涉及「緩衝區已滿」的情況,我該如何處理。如果用戶點擊一個可以發送數據包到服務器的按鈕,但由於緩衝區已滿而無法完成,因此我的用戶界面無法按預期工作。我是否等待用戶重複該命令? 謝謝! – Xexr 2010-06-15 12:25:08

+0

只要你知道如何創建它,把它放在一個鏈表中,並讓你的FD_WRITE處理程序使用這些塊來發送,我就會構建每個傳出的數據包。 – 2010-06-15 19:00:26

+0

請參閱,但鏈接列表只是管理的動態內存 - 而不是從我原來的方法不同。但感謝您的幫助,我會更新我的代碼以使用鏈接列表,而不是我現在擁有的自定義解決方案。 – Xexr 2010-06-15 19:32:56

相關問題