2012-12-04 19 views
0

假設我們有一個使用winsock來實現tcp通信的應用程序。我們爲每個套接字創建一個線程並在其上接收數據塊。當數據到達時,我們想通知其他線程(偵聽線程)。winsock應用程序和多線程 - 從另一個線程偵聽套接字事件

我想知道什麼是實現這一目標的最佳方式:

  1. 移動從這個設計拿走並使用非阻塞插座,然後監聽線程必須不斷迭代,並調用非阻止接收,從而使它線程安全(沒有額外的線程插座)

  2. 使用異步過程調用來通知偵聽線程 - 這又一次將警報 - 等待apc排隊等待。

  3. 實現了一些線程安全的消息隊列,其中每個套接字線程將向其發佈消息,並且偵聽器將再次每隔一段時間遍歷它並從中提取數據。

另外,我讀了關於WSAAsyncSelect,但我看到這是用來發送消息到窗口。是不是有類似的其他線程? (以及我猜apcs是...)

謝謝!

+0

[PostThreadMessage函數](http://msdn.microsoft.com/en-us/library/windows/desktop/ms644946%28v=vs.85%29.aspx) – Arno

回答

0

使用I/O完成端口。請參閱文件管理功能下的Win32 API的CreateIoCompletionPort()GetQueuedCompletionStatus()函數。在這種情況下,套接字描述符被用來代替文件句柄。

0

在與應用程序邏輯分離的層中抽象出套接字API的機制(偵聽,接受,讀取&)會更好。擁有一個捕獲連接狀態的對象,該連接在傳入連接期間創建,並且您可以爲此傳入和傳出通信量維護此對象中的緩衝區。這將允許您的網絡接口層獨立於應用程序代碼。這還將通過將應用程序功能與底層通信機制分離來使代碼更加清晰。

阻塞或無阻塞套接字決定取決於應用程序需要實現的可伸縮性級別。如果您的應用程序需要支持數百個傳入連接,那麼採用每個套接字線程的方法並不會很明智。您最好選擇基於Io端口的實現,這將使您的應用在增加代碼複雜度的情況下極大地擴展。但是,如果您在任何時間點只預見幾十個連接,則可以使用Win32事件或消息尋找異步套接字模型。如果併發套接字的數量超過63個(因爲WaitForMultipleObjects最多隻能支持64個套接字),那麼基於Win32事件的方法不能很好地擴展到超出某個限制的範圍。基於Windows消息的機制雖然沒有這個限制。 OHOH,基於Win32事件的方法不需要GUI窗口工作。

檢出WSAEventSelect以及WSAAsyncSelect MSDN中的API文檔。

您可能還想看看boost::asio包。它提供了一個簡潔(雖然有點複雜)的C++抽象概念。