2010-06-12 50 views
2

因爲我不是英語母語的人,所以我可能會錯過一些東西,所以也許這裏有人比我更瞭解我。IOCP文檔解釋問題 - 緩衝區所有權模糊

在MSDN從WSASend的doumentation摘自:

lpBuffers [IN]

一個指向WSABUF 結構的陣列。每個WSABUF結構 包含指向緩衝區的指針和緩衝區的長度(以字節爲單位)。對於 Winsock應用程序,一旦WSASend 函數被調用,系統擁有 這些緩衝區和應用程序可能 不訪問它們。該數組必須 在 發送操作期間保持有效。

好的,你能看到粗體文字嗎?這是不明確的地方!

我能想到的兩個譯本的這一行(可能是別的東西,你的名字):
翻譯1 - 「緩衝區」是指重疊結構我打電話時,通過這個功能。只有在得到關於它的完成通知時,我纔可以再次使用該對象。
翻譯2 - 「buffers」指的是實際的緩衝區,那些數據與我正在發送。如果WSABUF對象指向一個緩衝區,那麼在操作完成之前我無法觸摸此緩衝區。

任何人都可以告訴什麼是正確的解釋,該行?

而.....如果答案是第二個 - 你將如何解決它?
因爲對我來說,這意味着對於我發送的每個數據/緩衝區,我都必須在發送端保留一份它的副本 - 因此在高流量應用程序上有許多「未決」緩衝區(大小不同),它們真的會傷害「可擴展性」。

聲明1:
除了上面的段落(「And ....」),我還以爲IOCP將要發送的數據複製到它自己的緩衝區並從那裏發送,除非您設置SO_SNDBUF歸零。

聲明2:
我用堆棧分配的緩衝區(你知道,在函數體像char cBuff[1024]; - 如果翻譯的主要問題是第二個選項(即緩衝區必須保持原樣,直到發送是完成),然後......真的把事情搞得一團糟......你能想出解決它的辦法嗎?(我知道,我用上面的話來問)

回答

3

答案是重疊結構並且數據緩衝區本身不能被重新使用或釋放​​,直到操作完成。

這是因爲操作是異步完成的即使數據最終被複制到TCP/IP堆棧中的操作系統擁有的緩衝區中,這些緩衝區可能在將來的某個時間纔會出現,並且您會收到發生寫入完成時的通知。請注意,如果您在發送時沒有明確的流量控制並依靠TCP協議棧爲您進行流量控制(參見此處:some OVERLAPS using WSASend not returning in a timely manner using GetQueuedCompletionStatus?),寫入完成時可能會延遲一段令人驚訝的時間量...

您不能使用堆棧分配的緩衝區,除非您將事件放置在重疊結構中並阻塞它,直到異步操作完成;這樣做並沒有太多的意義,因爲你在普通的阻塞呼叫中增加了複雜性,並且通過發出異步呼叫然後等待它,你不會獲得很大的收益。

在我的IOCP服務器框架(您可以從here免費獲得)我使用動態分配的緩衝區,其中包括OVERLAPPED結構和引用計數。這意味着清理(在我的情況下它們被返回到池中以供重用)發生在完成並且參考被釋放時。這也意味着您可以選擇在操作之後繼續使用緩衝區,並且清理仍然很簡單。

也見這裏:I/O Completion Port, How to free Per Socket Context and Per I/O Context?

+0

非常感謝你的回覆萊恩,得到它從你意味着很多給我!我得到的總體思路,但我不能回到具體問題,在http://stackoverflow.com/questions/3034047/limiting-tcp-sends-with-a-to-be-sent-queue-和其他設計問題。 – Poni 2010-06-13 21:45:14

+0

標記爲答案,因爲您的答案是一天結束時的答案。再次感謝你! – Poni 2010-06-13 21:45:45