概述
这两天,突然想写一个与平台无关的socket(仅仅是windows和linux平台)。查资料,敲代码,测试,修改。。。如此不断反复,搞了2-3天了。在此期间,发现fd_set在windows和linux平台下面的实现是不同的。特此记录下。
在win下面,实现是(VS2005):
typedef struct fd_set {
u_int fd_count; /* how many are SET? */
SOCKET fd_array[FD_SETSIZE]; /* an array of SOCKETs */
} fd_set;
很明了,一个计数的fd_count,另一个就是SOCKET数组。其中,FD_SETSIZE是64.(具体可以去查看vs的代码)
win下面FD_SET就是检查SOCKET在数组中是否存在,如果不存在,那么就插入到数组最后。而FD_CLR(fd, set)是把fd后面的东西往前拷贝,然后计数减1.FD_ZERO仅仅是把计数置为0(这个要注意!!)!FD_ISSET就看不到实现了。
下面是fd_set在linux下的实现:
typedef struct
{
/* XPG4.2 requires this member name. Otherwise avoid the name
from the global namespace. */
#ifdef __USE_XOPEN
__fd_mask fds_bits[__FD_SETSIZE / __NFDBITS];
# define __FDS_BITS(set) ((set)->fds_bits)
#else
__fd_mask __fds_bits[__FD_SETSIZE / __NFDBITS];
# define __FDS_BITS(set) ((set)->__fds_bits)
#endif
} fd_set;
根据UNIX网络编程对fd_set的介绍,fd_set是个整数数组,用每个bit位来表示fd的。比如,一个32位整数,则数组第一个整数表示0-31的fd,以此类推,第二个整数表示32-63.。。。(下面有截图,详见UNIX网络编程第6章,I/O复用,6.3节)
查看linux的FD_SET、FD_CLR是用汇编实现的。根据说明可以知道,就是给bit置位。
(在我的系统中,__FD_SETSIZE是1024,__NFDBITS是sizeof(long int)即32,就是说,fd_set是4个long int 数组,最多放128个文件描述符(是不是太少了啊???))
由于fd_set实现不同,导致selet也不太一样,其他第一个参数在windows下就没有意义了(MSDN: The nfds parameter is included only for compatibility with Berkeley sockets),而在linux下面,是fd_set种的最大的一个描述符+1.具体可以参考其他资料。
最后
以上就是无限大神为你收集整理的fd_set的一些认识的全部内容,希望文章能够帮你解决fd_set的一些认识所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复