如果您真的喜欢可扩展的套接字编程,那么在 Windows 上没有什么比 IO 完成端口更好的了。
话虽如此,您的程序可能需要对完成端口模型进行大量重写。
但是,即使使用 select()/FD_ISSET,也可以提高性能。
这是如何完成的:在 winsock2.h 中,fd_set 被定义为一个 SOCKET 数组和一个元素计数器
typedef struct fd_set {
u_int fd_count; /* how many are SET? */
SOCKET fd_array[FD_SETSIZE]; /* an array of SOCKETs */
} fd_set;
同样在 winsock2.h 中,您会发现 FD_SET 在该数组的末尾添加了一个 SOCKET,并且 FD_ISSET 正在数组中进行线性搜索。
现在,如果您更改宏以使用 SOCKET 的排序数组,即
- FD_SET 按排序顺序添加套接字
- FD_ISSET 进行二分查找而不是线性查找
然后依赖于数组的大小 FD_ISSET 可以大大提高(虽然 FD_SET 的性能会有所下降,但我们假设 FD_SET 是一个很少的操作)。
在 Unix 上,select() 的性能更好,因为它们 FD_SET 作为位图,FD_SET/FD_ISSET 只会测试或设置一个位。在 Windows 上,此技术不适用,因为套接字不是一个小的正文件描述符数,它是一个句柄,句柄的标量值可能很大。