2014-03-28 90 views
1

我在Windows中使用多線程IOCP服務器。爲了避免處理很多未決的讀取,我在每個連接的套接字上始終只有一個wsarecv操作。總之我的設計是這樣的:當沒有wsarecv時,輸入數據會發生什麼

  1. 客戶端連接後,wsarecv是在連接插座貼
  2. 在執行wsarecv,數據處理連線和wsasend張貼在同一插座上
  3. wsasend從第2步完成(GQCS獲得通知),wsarecv重新貼。

這意味着在步驟2和步驟3之間只有一小段時間,當沒有掛起的wsarecv正在等待客戶端數據時,它可以在任何時候出現。

是這種情況,我應該擔心或者我可以假設,如果數據會在這個特定的時間內到達,它將被存儲在某種內部緩衝區中,並從步驟3中的wsarecv那裏獲取張貼?

thx尋求幫助。

+2

TCP或UDP?在任何一種情況下,它都會被緩衝,在UDP的情況下,如果緩衝時間過長(隨着更多數據的進入),它可能會被丟棄。 – Chad

+0

@乍得,它是TCP。 – maciekm

+0

@maciekm考慮在標題,文本和標籤中添加它的tcp信息 –

回答

2

只要您還沒有禁用網絡堆棧的緩衝(使用SO_RCVBUF並將緩衝區大小設置爲0),那麼網絡堆棧中將有一些緩衝區空間,如果您沒有WSARecv()懸而未決。

如果您使用的是TCP,那麼當您填充此緩衝區空間時,您甚至不必擔心,因爲這會導致零窗口,並且發送者希望停止發送(請參閱here,以瞭解爲什麼它可能不會實際停止發送),但即使沒有,你的堆棧也會丟棄後續的數據報,TCP將最終重新發送它們。

與UDP有點不同。如果你填充recv緩衝區,那麼你將開始刪除數據報。默認情況下,堆棧將丟棄最新的數據報,您可以通過設置SIO_ENABLE_CIRCULAR_QUEUEING來更改此設置,這會導致最舊的數據報被丟棄。

您可以選擇始終至少有一個WSARecv()等待在連接上通過a)張貼多個開始和b)發佈一個新的作爲您完成時的第一件事。這適用於UDP,但對於TCP而言,這種方法的問題在於,您必須考慮到多個recvs可能「同時」完成,然後您必須確保您的I/O線程一起工作以保持TCP數據流同步(有關問題,請參閱here)。

禁用堆棧的recv緩衝區可能會更高效,並且始終有足夠的WSARecv()在連接上掛起,因爲這會從入站數據路徑中刪除內存副本。

相關問題