2014-09-25 99 views
0

同一插座上後許多wsasend(的問題是從MSDN論壇複製)從多個線程

MSDN這樣說:

如果您正在使用I/O完成端口,要知道,對WSASend的調用順序也是填充緩衝區爲 的順序。 WSASend不應該從不同線程同時調用同一套接口 ,因爲它可能導致 不可預知的緩衝區順序。

好的...但是如果我不在乎這個順序,也不關心順序,我會在另一邊接收它...我可以使用它嗎?從多個線程調用WSASend是否安全?那麼這些軟件包是如何傳遞的(也許訂購的方式不同,但完整)?

E.g. - >我會在一次呼叫中發送[12a],[34b],[11c]和[223d] ...([]標記我傳給WSASend的單元) 34b,11c,12a,223d?或者它會崩潰?或者我可以收到類似2a,34b,7a,5c,...

這樣的問題,也許問題應該是 - 它是原子嗎? (我正在談論WSASend與IOCP一起使用,因此重疊)

+0

IIRC是的,你可以做到這一點。這樣的調用是線程安全的,但不是TCP安全的。) – 2014-09-25 20:06:33

+0

想一想 - 通過WSARecv()調用相同的套接字並由兩個不同的線程池線程來處理兩個緩衝區是非同尋常的,但並非不可能。在處理完緩衝區數據之後,這些線程可能會發出WSASend調用來將回復同時發送到一個套接字。所以是的,他們必須是線程安全的。 – 2014-09-25 20:12:41

+0

由於兩個線程池獲得完整的數據報需要回復的機會比TCP要高,因此我的場景更適合使用UDP協議。 – 2014-09-25 20:15:30

回答

1

似乎實際調用WSASend()不是線程安全的,並且如果您打算從同一連接上的多個線程調用WSASend(),那麼您應該同步,以便只有一個線程實際上在任何給定的點處調用API(即,在WSASend()調用周圍保持每個連接鎖定)。有關詳細信息,請參閱此問題和附加的測試代碼:TCP/IP IOCP received data sometimes corrupt - Visual C++ on Windowsthis blog entry以獲得更詳細的說明。

另請注意,如果您使用來自多個線程的多個WSASend()調用發送不同的應用程序級別的消息,則會出現問題,因爲在數據寫入TCP流之前可能會混合使用多個調用。

所以,

如果你有5個線程發送 '完整的2級字節的信息',這樣你發送

AA,BB,CC,DD,EE等來自5級不同的線程,那麼你不會得到包含

ABCCDDBAEE

,但你能得到的消息令的任何組合的流。

如果您的線程正在使用多個發送調用發送消息,例如三個發送,則線程1中的A1 A2 A3將形成單個應用程序級別的消息。然後所有投注都關閉,因爲您可能在TCP流中結束了

A1B1A2A3B2B3等。

如果您以後需要做某些事情,您可能需要圍繞所有WSASend調用進行某種鎖定,以便可以將多個發送組合爲單個應用程序級別的原子發送,或者您應該爲單個應用程序使用多個WSABUF WSASend調用將多個寫入集中在一個調用中。