您的位置:首页 > 运维架构 > Linux

fd_set的一些认识

2012-03-02 10:38 141 查看
 
    这两天,突然想写一个与平台无关的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.具体可以参考其他资料。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息