让我用这句话来说明我从来没有使用过I / O完成端口,尽管我已经听过多年了。我的背景主要是select
,poll
,epoll
和WSAEventSelect
以及WaitForMulitpleObjects
。如果我在下文中对I / O完成端口有一个基本的误解,请纠正我。
作为项目工作的一部分,我的任务是开发一个插件(DLL)到模拟,允许客户端连接到插件并通过TCP向模拟发送数据/从模拟接收数据。该插件充当服务器。仿真模拟了不同(不是以太网)接口的通信通道,在这个特定应用中每个通道有一个插槽是有意义的。我不知道会有多少客户端,或者每个客户端将打开多少个通道(套接字)。但是,我确实知道完全有可能超过64个,并且它不会是一个非常大的数字,最多可能不到一千个。
模拟的一个重要方面是插件只有在调用test_cycle
函数时才能工作。在每个测试周期中,我需要:
由于可能有超过64个套接字,我无法(轻松)使用WSAEventSelect
和WSAWaitForMultipleEvents
来检查是否可以读取套接字,或者客户端是否正常终止连接。
所以我想到了另外两种方法可以做到这一点。
让每个套接字都无阻塞。每次调用test_cycle
时,都会遍历所有套接字,尝试每个套接字接收最多数据量。
使用I / O完成端口并从套接字发出异步接收。在test_cycle
中,重复调用GetQueuedCompletionStatus
并将dwMilliseconds
参数设置为0
,直到指示超时(WAIT_TIMEOUT
?)。如果发生接收,则将下一个接收呼叫推迟到测试周期结束,以便客户端使用消息向服务器发送垃圾邮件将不会导致我们无限期地在test_cycle
中循环(希望如此)。
模拟的界面不是线程安全的,并且用于将数据转发到模拟的处理工作很少,所以我认为为工作线程提供工作线程会有任何好处。 I / O完成端口,它只会执行锁定并调用模拟API。但是,不必轮询每个套接字可能会带来更好的性能。
因此,对于这种应用规模,最多不超过1000个套接字,通常小于100个,使用I / O完成端口增加了复杂性是否有任何实际好处?
答案 0 :(得分:0)
我认为你可以这样做:
1)构建一个监听器线程。对于每个连接,将套接字的副本发送到线程池;
2)构建一个线程池来处理请求;
我在不使用I / O完成端口的情况下使用管道进行线程之间的传输,性能非常出色。
设置控制限制,以确保资源不会耗尽。