Windows上多线程应用程序中非阻塞服务器/侦听套接字的最佳方法?

时间:2011-05-01 14:34:16

标签: c windows multithreading sockets winsock

我正在Windows上编写TCP服务器/客户端应用程序,以熟悉Winsock API。我来自UNIX背景,想知道哪些是实现应用程序的最佳方法:

首先是规范

  • 必须在多处理器和单处理器系统上很好地扩展。
  • 没有硬连接限制。
  • 应用程序既可以侦听连接,也可以充当服务器,并充当客户端。
  • 多线程。

第一种方法

  • 用于侦听的非阻塞类选择套接字,位于“服务器”主题中。
  • 为每个连接客户端我们生成一个单独的线程。

第二种方法

  • 在“服务器”主题中阻止侦听套接字。
  • 为每个连接客户端我们生成一个单独的线程。

第三种方法

  • 用于侦听的非阻塞类选择套接字,位于“服务器”主题中。
  • 每个传入连接都没有单独的线程,协议需要在我认为的会话中保留状态信息。

我想知道什么是最有效和可扩展的方法,特别是如果它也适用于UDP套接字。

注意:我正在使用普通和旧C编写应用程序。不涉及.NET或C ++,也禁用了C ++异常。

3 个答案:

答案 0 :(得分:2)

正如Gary所说,I / O完成端口是在Windows平台上以非阻塞/异步方式管理多个网络连接的最有效方式。

使用IOCP,您可以在网络操作完成后收到通知,并且可以使用少量线程处理这些完成。您可以决定分配多少线程来处理完成,内核决定何时使用您提供的线程。它以LIFO顺序使用它们,以减少上下文切换,因此如果您只使用任何点所需的最小线程数并且您重复使用相同的线程而不是循环遍历您可用的所有线程使用

IOCP编程的异步特性从一开始就有点混乱,但是一旦掌握了它,它就会非常直接。

我有一些免费的IOCP服务器代码,它演示了基础知识并提供了一些非常容易构建的示例服务器。您可以在此处找到代码:http://www.serverframework.com/products---the-free-framework.html。该页面还链接到我编写的一些文章来解释代码。

将此与您问题的详细信息联系起来。你应该看看你的第三种方法的变化。使用AcceptEx()接受新连接,这可以以异步方式使用,因此您不需要单独的线程来接受连接,并且可以使用也处理重叠/异步读取和写入操作的线程。

答案 1 :(得分:0)

我编写了一个不使用阻塞套接字的异步客户端,因此如果您对该方法感兴趣,请查看我的客户端:http://codesprout.blogspot.com/2011/04/asynchronous-http-client.html

这是一个HTTP客户端,但我在那里显示的HTTP协议处理很少,它只是.NET套接字。服务器的工作方式类似:您可以利用AsseptAsync等*异步方法。

答案 2 :(得分:-2)

在Windows下,通过使用I / O完成调用可以获得最佳性能。

这是因为列表和排队机制是在内核中完成的,远远不是繁重的用户模式开销(如果你敢于自己做艰苦的工作,就会拖延你的代码)。

不幸的是,Windows I / O完成调用需要分配许多线程来扩展,这很快就会破坏性能(与Linux epoll相比,它可以独立于决定的工作线程数量而扩展参与任务)。

最近,我发现了http://gwan.com/一个来自Windows的Web服务器,然后在Linux下移植。他们的作者在他们的论坛上详细描述了这个问题。