c++ - 非阻塞套接字的 Windows select 和 Unix select 之间的区别

标签 c++ linux windows macos sockets

我尝试从 Windows 平台获取一些 C++ 代码到 Mac OSX/Linux。 Windows 实现使用套接字和 select 语句。在 Windows 下,给 select 的 fd_set 定义如下:

typedef struct fd_set {
        u_int fd_count;               /* how many are SET? */
        SOCKET  fd_array[FD_SETSIZE];   /* an array of SOCKETs */
} fd_set;

这很糟糕,因为 FD_SETSIZE 很小,我不得不构建一个更动态的方法,这在 64 位 Windows 上带来了一些麻烦。在 Windows 上解决所有这些问题后,我在 unix/linux/OSX 上遇到了问题,因为 fd_set 在那里看起来完全不同。

现在是问题。是否有像 Windows 中那样的套接字数量限制?在 Linux 和 Windows 下工作的好的解决方案是什么。如果套接字数量有限制,最好的解决方法是什么?

最佳答案

据我所知,这两个操作系统都允许在包含#include 文件(winsock.h for Windows)之前通过#defining FD_SETSIZE 更改结构的大小。这意味着如果您只是使结构变大(Windows 文档明确说明了这一点),Windows 中就没有真正的套接字数量限制。 FD_SET() 等函数使用 FD_SETSIZE 宏(它们是“内联”函数,甚至只是宏)。

在 Linux 中你会遇到同样的问题。然而,在 Linux 下,fd_set 结构不包含计数,而只包含文件描述符的位字段 (!)(因此,如果小端机器上的第一个字节是 0x81,0x01,则文件描述符 0、7 和 8 位于文件描述符)。

“select()”系统调用的第一个参数必须是位域的长度。在 Windows 下,“select()”的第一个参数应为 0。

如您所见,Windows 和 Linux 之间存在许多差异,因此您可能需要编写一个独立于系统的包装函数(如“closesocket()”/“close()”):

在 Linux 下,您检查最大的文件描述符编号。然后你计算:bitmap_size=(highest_number+64)&~63。您分配 bitmap_size/8 个字节并设置相应的位。

在 Windows 下,您分配一个 fd_set 结构,但有更多的 fd_array 条目。

关于c++ - 非阻塞套接字的 Windows select 和 Unix select 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19095012/

相关文章:

php - 在 Windows 上将 Unicode 字符串传递给 PHP shell_exec

c++通过引用传递问题

linux - 我可以在 Postgresql 生产服务器中更改 Linux 时间吗?

c++ - boost 序列化: save_construct_data not called

C++ IDE 在特定命名空间内搜索

linux - zsh提示功能不起作用

windows - 在 gui 中包装 rsync 进度的最佳方法?

windows - Windows 上运行的 C# 与 linux 上运行的 C 通过 protobuf 进行通信

c++ - 段错误 C++ Cuda

c++ - 如何使用 avx 指令将 float vector 转换为 short int?