2013-05-01 26 views
1

我正在寫客戶端服務器程序,其中客戶端是C++/winapi和服務器是C#/ .net。Windows套接字似乎是非雙工

客戶端有一個循環,其中從服務器讀取(並可能阻塞調用線程[表示t1],這對我來說很好)。它還有另一個線程[表示t2],它等待一個超時的Event對象。

如果達到超時(並且事件尚未被選中)t2線程,將在同一個套接字上寫入(字節很大)。

我遇到的問題是,好像寫入不會返回直到t1返回的讀取(在某些合法scner中它永遠不會發生),就好像套接字不是全雙工一樣。

P.S:socket是一個AF_INET/SOCK_STREAM,我使用Readfile和WriteFile進行套接字IO操作。

謝謝。

回答

0

這兩個套接字都不是read()和write()或send()和recv(),都是這樣的。你必須有一些你自己的同步。

0

我已經使用WinSock進行了十多年的編程,我可以向你保證套接字始終是全雙工的。

的唯一方法WriteFile()(或send()WSASend())將阻止任何時間量調用線程如果套接字阻塞模式和數據等待被髮送的其出站隊列運行已經完全充滿(大小的隊列由SO_SNDBUF套接字選項控制)。這表明另一方(您的C#服務器)沒有從其套接字端點讀取入站數據,並及時確認接收到的數據,因此您的套接字端點可以將該數據從其出站隊列中刪除,因此可以接受新數據進行傳輸。

如果您不希望您來WriteFile()呼叫阻止,您可以:

  1. 使SO_SNDTIMEO套接字選項來指定超時緩衝寫。

  2. 使用select()WSAAsyncSelect(),或WSAAsyncEvent()檢測時,插座實際上是可寫的(即,當它可以接受無阻塞數據)寫任何新的套接字之前。

  3. 切換到非阻塞I/O,異步重疊I/O或I/O完成端口。

+0

這是怎麼回事? http://stackoverflow.com/a/16708230/886887套接字是一個特殊的例外嗎?如果您使用ReadFile/WriteFile而不是套接字函數,那麼這個異常是否適用? – 2013-05-29 06:13:45

+0

'socket()'創建一個在內部使用重疊I/O的套接字。爲避免使用重疊的I/O,您必須調用'WSASocket()'而不要使用'WSA_FLAG_OVERLAPPED'標誌。但在大多數情況下,這通常不可取。 – 2013-05-29 14:11:37

+0

這並不意味着如果您使用ReadFile和WriteFile,則需要使用重疊的I/O,即指定一個有效的OVERLAPPED結構?這可能是OP的問題嗎? – 2013-06-03 21:40:44