我正在Windows上编写一个TCP服务器/客户端应用程序,以熟悉Winsock API。 我来自UNIX背景,想知道哪些是实现应用程序的最佳方法:
首先是规范
第一种方法 :
第二种方法 :
第三种方法 :
我不知道什么是最有效和可扩展的方法,特别是如果它也可以使用UDP套接字。
注意:我在纯C和旧C中编写应用程序。不涉及.NET和C ++,也禁用C ++exception。
正如Gary所说,I / O完成端口是在Windows平台上以非阻塞/异步方式管理多个网络连接的最有效方法。
使用IOCP,当网络操作完成时,您会收到通知,您可以使用少量的线程处理这些完成。 您可以决定分配多少个线程来处理完成,内核决定何时使用您提供的线程。 它以LIFO顺序使用它们来减少上下文切换,所以如果你只使用最少的线程数量,而且你重复使用相同的线程,而不是循环遍历所有可用的线程使用。
IOCP编程的异步特性可能会有点混乱,但一旦你掌握了它,它就相当简单了。
我有一些免费的IOCP服务器代码,演示了基础知识,并提供了一些很容易构建的示例服务器。 你可以在这里找到代码: http : //www.serverframework.com/products—the-free-framework.html 。 该页面也链接到我写的一些文章来解释代码。
将此与您的问题的细节相关联。 你应该看看你的第三种方法的变化。 使用AcceptEx()接受新的连接,这可以以异步的方式使用,所以你不需要一个单独的线程来接受连接,并且可以使用也处理重叠/异步读写操作的线程。
我写了一个不使用阻塞套接字的异步客户端,所以如果你对这种方法感兴趣,那么看看我的客户端: http : //codesprout.blogspot.com/2011/04/asynchronousous-http- client.html
这是一个HTTP客户端,但是我已经在那里显示了很少的HTTP协议处理,这只是.NET套接字。 服务器将以类似的方式工作:您可以利用诸如AsseptAsync
Async方法。
在Windows下,使用I / O完成调用可以获得最好的性能。
这是因为列表和排队机制是在内核中完成的,远离了大量的用户模式开销(如果你敢自己努力工作,则会拖累你的代码)。
不幸的是,Windows I / O完成调用需要分配许多线程来进行扩展,这很快就会导致性能下降(与可以独立于您决定参与任务的工作线程数量进行扩展的Linux epoll相比)。
最近,我发现http://gwan.com/是一个来自Windows的Web服务器,然后在Linux下移植。 他们的作者在他们的论坛上详细描述了这个问题。