[IO复用] Windows Select FD_SETSIZE 大小修改

简介

Windows的Select 中,FD_SETSIZE大小默认是64

WinSock2.h

/*
 * Select uses arrays of SOCKETs.  These macros manipulate such
 * arrays.  FD_SETSIZE may be defined by the user before including
 * this file, but the default here should be >= 64.
 *
 * CAVEAT IMPLEMENTOR and USER: THESE MACROS AND TYPES MUST BE
 * INCLUDED IN WINSOCK2.H EXACTLY AS SHOWN HERE.
 */
#ifndef FD_SETSIZE
#define FD_SETSIZE      64
#endif /* FD_SETSIZE */

根据winSock2.h中的注释,是允许在代码中修改FD_SETSIZE的大小的。

在Microsoft 的 select function (winsock2.h)中说:

The variable FD_SETSIZE determines the maximum number of descriptors in a set. (The default value of FD_SETSIZE is 64, which can be modified by defining FD_SETSIZE to another value before including Winsock2.h.)

所以,如果在代码中,在winSock2.h include 之前,定义了FD_SETSIZE,默认的64就不会生效了。

由于Linux默认的FD_SETSIZE是1024, 所以有需要求的话,
可以在windows编程时,把FD_SETSIZE修改为1024。

试验代码

没有自定义FD_SETSIZE宏

输出FD_SETSIZE的大小,和fd_set::fd_array的元素数量。

//#define FD_SETSIZE 1024;
#include <WinSock2.h>
#include <iostream>
#pragma comment(lib, "ws2_32.lib")

int main()
{
    WSADATA WSAData;
    if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0)
        return -1;
    fd_set* pfds = new fd_set();

    std::cout << "FD_SETSIZE " << FD_SETSIZE << std::endl;
    std::cout << "fd_array num " << sizeof(pfds->fd_array) / sizeof(SOCKET) << std::endl;

    WSACleanup();
}

在这里插入图片描述
是默认值64;

自定义FD_SETSIZE

输出FD_SETSIZE的大小,和fd_set::fd_array的元素数量。

#define FD_SETSIZE 1024
#include <WinSock2.h>
#include <iostream>
#pragma comment(lib, "ws2_32.lib")

int main()
{
    WSADATA WSAData;
    if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0)
        return -1;
    fd_set* pfds = new fd_set();

    std::cout << "FD_SETSIZE " << FD_SETSIZE << std::endl;
    std::cout << "fd_array num " << sizeof(pfds->fd_array) / sizeof(SOCKET) << std::endl;

    WSACleanup();
}

在这里插入图片描述
被修改成了1024

自定义FD_SETSIZE最大能多大

fd_array是成员位SOCKET的数组,SOCKET是__int64类型,大小8字节。
所以FD_SETSIZE == 1024, fd_array 大小是8KB。
此时我的电脑可用内存为不到6g,我把FD_SETSIZE改为1024 * 1024 * 768,看看会怎么样。

编译报错:
1>D:\Windows Kits\10\Include\10.0.22000.0\um\WinSock2.h(138,17): error C2148: 数组的总大小不得超过 0x7fffffff 字节
即,数组大小不能超过:2147483647。
FD_SETSIZE改为1024 * 1024 * 768时,fd_array大小应该达到了6442450944,所以超过限制了。

把FD_SETSIZE缩小为:2147483647 / 8 = 268,435,455。
此时编译,new报错。

我把FD_SETSIZE再缩小一点:268,435,400。
编译成功,运行成功,程序运行时,通过资源管理器可以看到大概多占用了2g的内存。

所以FD_SETSIZE不能过大,当超出操作系统允许的极限的时候,会导致编译失败,或者运行崩溃。

结果

windows中虽然默认的FD_SETSIZE是61,但可以修改FD_SETSIZE的大小,而且修改方法比较简单。

如果工程中,在多个地方include了winSock2.h,一定要在第一个include之前,声明自定义的FD_SETSIZE,不然自定义还是不会生效。

  • 33
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值