winsock应用程序和multhreading - 从另一个线程中侦听套接字事件

时间:2012-12-04 08:07:46

标签: multithreading winapi winsock2 winsockets

假设我们有一个使用winsock来实现tcp通信的应用程序。 对于每个套接字,我们在其上创建一个线程和块接收。 当数据到达时,我们想通知其他线程(监听线程)。

我想知道实现这个的最佳方法是什么:

  1. 离开这个设计并使用非阻塞套接字,然后监听线程将不断迭代并调用非阻塞接收,从而使其线程安全(没有额外的线程用于套接字)< / p>

  2. 使用异步过程调用来通知侦听线程 - 这也需要警告 - 等待apc为它们排队。

  3. 实现一些线程安全消息队列,其中每个套接字线程都会向其发送消息,并且侦听器将再次每隔一段时间检查它并从中提取数据。

  4. 另外,我读到了WSAAsyncSelect,但我看到这用于向窗口发送消息。其他线程是不是有类似的东西? (我猜apc是......)

    谢谢!

2 个答案:

答案 0 :(得分:0)

使用I / O完成端口。请参阅Win32 API的CreateIoCompletionPort()GetQueuedCompletionStatus()函数(在“文件管理”功能下)。在这个例子中,套接字描述符用于代替文件句柄。

答案 1 :(得分:0)

最好在与应用程序逻辑分开的层中抽象套接字API(侦听,接受,读取和写入)的机制。有一个捕获连接状态的对象,该连接是在传入连接期间创建的,您可以在此对象中维护传入和传出流量的缓冲区。这将允许您的网络接口层独立于应用程序代码。这也将通过将应用程序功能与底层通信机制分离来使代码更清晰。

阻塞或非阻塞套接字决策取决于应用程序需要实现的可伸缩性级别。如果您的应用程序需要支持数百个传入连接,那么采用每插槽线程方法并不是非常明智。您最好选择基于Io端口的实现,这将使您的应用程序在增加代码复杂性的情况下极大地扩展。但是,如果您只预见任何时间点的几十个连接,您可以使用Win32事件或消息来寻找异步套接字模型。基于Win32事件的方法不能很好地扩展到超出某个限制,因为如果并发套接字的数量超过63,则必须管理多个线程(因为WaitForMultipleObjects最多只能支持64个套接字)。基于Windows消息的机制虽然没有这个限制。 OHOH,基于Win32事件的方法不需要GUI窗口即可工作。

在MSDN中查看WSAEventSelect以及WSAAsyncSelect API文档。

您可能还想查看boost::asio包。它通过套接字API提供了一个整洁的(虽然有点复杂)C ++抽象。