2012-02-17 47 views
1

我的問題:我的Completionport服務器將接收來自不同客戶端的未知大小的數據,問題是,我不知道如何避免緩衝區溢出/如何避免我的(接收)緩衝區被數據「溢出」。WSARecv,Completionport Model,如何管理緩衝區並避免超支?

現在到Quesitons: 1)如果我通過WSARecv進行接收呼叫,工作線程是否像回調函數一樣工作?我的意思是,它只在完成接收呼叫後才發現接收呼叫,或者在接收時發現接收呼叫? lpNumberOfBytes(來自GetQueuedCompletionStatus)變量是否包含到目前爲止收到的字節數或收到的總字節數? 2)如何避免超限,我想到了動態分配的緩衝區結構,但是又一次,我怎麼知道這個軟件包有多大?

編輯:我討厭問這個,但是有沒有任何「簡單」的方法來管理緩衝區並避免超支?同步聲音對我來說極限,至少現在

回答

1

如果我通過WSARecv進行接收呼叫,工作線程是否像回調函數一樣工作?

請參閱@valdo文章。完成數據排隊到您的線程池,並且一個將準備好處理它。

'我的意思是,它是否只在收到電話完成後才撥打接聽電話?'是的 - 因此這個名字。請注意,「完成」的含義可能會有所不同。取決於協議。對於TCP,這意味着已經從對等端接收到一些流數據字節。

'lpNumberOfBytes(GetQueuedCompletionStatus)變量是否包含到目前爲止收到的字節數或接收到的總字節數?'它包含接收到的字節數並將其加載到僅在該IOCP完成中提供的緩衝區陣列中。'如何避免超支,我想到了動態分配的緩衝區結構,但是接下來我又怎麼知道該軟件包有多大?'如果您提供緩衝區數組,則不能超支 - 加載緩衝區的內核線程數不會超過傳遞的緩衝區長度。在應用程序級別,考慮到TCP的流式性質,決定如何將緩衝區陣列處理爲可用的應用程序級協議單元取決於您。您必須根據您所提供服務的知識決定合適的緩衝區管理方案。

最後的IOCP服務器有點兒通用。我使用了一組緩衝池和一組「緩衝區載體」對象,在啓動時分配(以及一組套接字對象)。每個緩衝池都保存着不同大小的緩衝區。在新建連接時,我使用最小池中的一個緩衝區發出WSARecv。如果此緩衝區已完全填充,則我使用來自下一個最大池的緩衝區作爲下一個WSARecv,依此類推。

然後有一個序列號的問題,以防止多處理器線程無序緩衝:(

1

_1。完成端口是一種隊列(具有關於等待從其中解除I/O完成的線程的優先級的複雜邏輯)。無論何時I/O完成(無論是否成功),它都會排隊到完成端口。然後它被稱爲GetQueuedCompletionStatus的線程中的一個出隊。

因此,您永遠不會將I/O「正在進行」出列。而且,它是由你的工作線程異步處理的。也就是說,它被延遲到你的線程調用GetQueuedCompletionStatus

_2。這實際上是一個複雜的問題。同步並不是一項簡單的任務,特別是當涉及到對稱多線程時(你有幾個線程,每個線程都可以做所有事情)。

使用完整的I/O接收到的參數之一是指向OVERLAPPED結構(您提供給發出I/O的函數,如WSARecv)的指針。分配基於OVERLAPPED的自己的結構(要麼繼承它,要麼作爲第一個成員)是一種常見的做法。收到完成後,您可以將出列的OVERLAPPED轉換爲您的實際數據結構。在那裏,您可能擁有同步所需的一切:同步對象,狀態描述等。

但請注意,即使具有自定義功能,正確同步事件(以獲得良好性能並避免死鎖)也不是一件簡單的任務上下文。這需要精確的設計。