admin管理员组文章数量:1613633
首先,在不同的操作系统下,select模型完全兼容么?
fd_set在2种操作系统下的实现方式差别比较大:
linux下面定义,对宏翻译后大概是这样的:
typedef struct
{
// 支持1024个文件描述符,而用bit作为掩码使用,每个long是64位,所以除以64
long int fds_bits[1024 / (8 * 8))];
} fd_set;
所以使用掩码方式可以直接按比特位进行设置,和删除;
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
man手册中说明,nfds并不是我们设置了多少个socket,而是最大的fd + 1;
这是因为
1)socket本身就是int从小到大的使用,当设置了最大的,最大值可以保证小的都被覆盖;
2)按照掩码方式使用,设置了大值,之前的都是需要监测的;
windows不同:
#define FD_SETSIZE 64
#endif /* FD_SETSIZE */
typedef struct fd_set {
u_int fd_count; /* how many are SET? */
SOCKET fd_array[FD_SETSIZE]; /* an array of SOCKETs */
} fd_set;
这里使用了一个很土的数组,加上一个使用的个数;
设置时候是
1)监测是否设置了;
2)如果找不到,则追加;
删除的时候是:
1)找到当前位置;
2)逐个向前挪动;
效率比linux的方式低了很多啊,
所以在使用select时候nfds的设置其实就是实际添加了多少个socket;
总结:为啥微软不采用掩码方式实现?是微软太笨么?
不是,是因为windows下socket的值并不是从小到大的一个递增的小整数,值可能会非常的大,所以不能使用小数组实现掩码。
另外:
`int retval, numevents = 0;
timeval tv;
tv.tv_sec =0;
tv.tv_usec = 0; // windows 设置为0合适
memcpy(&_rfds, &rfds, sizeof(fd_set));
memcpy(&_wfds, &wfds, sizeof(fd_set));
memcpy(&_efds, &efds, sizeof(fd_set));
//int n = efds.fd_count;
//n =max(_rfds.fd_count, _wfds.fd_count);
//if (n==0)
// return Utils::getmSecNow();
//printf("select n %d \n", n);
retval = select(maxFd + 1, &_rfds, &_wfds, &_efds, &tv);`
版权声明:本文标题:windows与linux系统的select区别 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dianzi/1728655524a1168130.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论