最适合即时消息客户端的异步套接字模型?

时间:2009-02-07 20:24:27

标签: c++ sockets

我正在使用C ++(Win32)中的即时通讯客户端,我正在尝试使用不同的异步套接字模型。到目前为止,我一直在使用WSAAsyncSelect通过我的主窗口接收通知。但是,我遇到了一些意想不到的结果,Winsock还为一个插槽生成了另外5-6个线程(除了为调用WSAAsyncSelect时创建的初始线程)。

我计划通过DLL修改客户端以支持其他协议:我担心我目前的解决方案不适合我的WSAAsyncSelect经验,除了我对网络与UI的混合负面代码(在消息循环中)。

我正在寻找关于多协议IM客户端适合的异步套接字模型的建议,该客户端需要能够处理大约10-20个+连接(取决于数量)协议和协议设计等),虽然没有使用过多的线程 - 我对性能非常感兴趣并且保持资源使用率下降。

我一直在寻找IO完成端口,但从我收集的内容来看,它似乎有些过分。我非常感谢关于合适的套接字解​​决方案的一些意见!

提前致谢! : - )

5 个答案:

答案 0 :(得分:5)

有四种基本方法可以处理多个并发套接字。

  1. 多路复用,即使用select()轮询套接字。
  2. AsyncSelect,基本上就是你在使用WSAAsyncSelect。
  3. 工作线程,为每个连接创建一个线程。
  4. IO完成端口或IOCP。 dp在上面提到了它们,但基本上它们是处理异步I / O的操作系统特定方式,它具有非常好的性能,但它更令人困惑。
  5. 您选择的往往取决于您打算去的地方。如果您计划将应用程序移植到其他平台,您可能需要选择#1或#3,因为select与其他操作系统上使用的其他模型没有太大差别,而且大多数其他操作系统也有线程的概念(尽管它们可能以不同的方式运作IOCP通常是特定于Windows的(尽管Linux现在也有一些异步I / O功能)。

    如果您的应用仅限Windows,那么您基本上想要为您正在做的事情选择最佳模型。这可能是#3或#4。 #4是最有效的,因为它回调到您的应用程序(类似,但具有更好的性能和更少的WSAsyncSelect问题)。

    使用线程(IOCP或WorkerThreads)时必须处理的重要事情是将数据封送回可以更新UI的线程,因为您无法在工作线程上调用UI函数。最终,在大多数情况下,这将涉及一些来回的消息传递。

    如果你是在托管代码中开发这个,我会告诉你看看Jeffrey Richter的AysncEnumerator,但是你选择了C ++,它有它的优点和缺点。很多人为C ++编写了各种网络库,也许你应该花一些时间研究其中的一些。

答案 1 :(得分:3)

考虑使用您可以在boost(www.boost.org)中找到的ASIO库。

答案 2 :(得分:3)

只需使用同步模型。现代操作系统可以很好地处理多个线程。在极少数情况下确实需要异步IO,主要是在服务器上。

答案 3 :(得分:2)

在某些方面,IO完成端口(IOCP)是过度的,但说实话,我发现异步套接字的模型比替代方案更容易使用(选择,非阻塞套接字,重叠IO等)。

IOCP API可能更清晰,但一旦你通过它,我认为它实际上更容易使用。回到何时,最大的障碍是平台支持(它需要一个基于NT的操作系统 - 即Windows 9x不支持IOCP)。随着这个限制早已消失,我会考虑它。

答案 4 :(得分:2)

如果您决定使用IOCP(如果您正在为Windows编写,那么恕我直言,这是最好的选择)那么我可以获得一些免费代码,这可以带走您需要完成的大量工作。

最新版本的代码和原始文章的链接可从here获得。

我对框架与Boost :: ASIO的比较的看法可以在这里找到:http://www.lenholgate.com/blog/2008/09/how-does-the-socket-server-framework-compare-to-boostasio.html