unix select()调用:如何组合fd_sets?

nin*_*ina 5 c unix network-programming

我正在用C语言编写一个Linux应用程序,它使用了2个独立的第三方库.两个库都是异步的,使用select().它们还提供了一个API,用于返回它们等待的文件描述符.我的目的是将这些传递给我自己的select(),然后在设置自己的fd值时将控制权返回给任何一个库.

我想我已经编写了大部分内容,但是在涉及select()参数时我遇到了麻烦:两个库都不提供单独的文件描述符,而是指向它们的读写fd_sets的指针.我需要将这些库中返回的fd_sets组合成一个用于读取的fd_set,一个用于写入的fd_set等.

关于如何将2个fd_sets组合成一个结果fd_set的任何建议?

附录对不起!我本来应该更清楚..这些库只返回fd_sets ...我不知道每组中FD的数量,这样我就可以做一个for循环并单独设置每个FD ..是否有一种简单的方法可以确定这给出了一个fd_set?

Aid*_*lly 5

C代码不依赖于以下的实现fd_set:

void Fdset_Add(fd_set *Out, fd_set const *In, int InNfds)
{
    for(i = 0; i < InNfds; i++)
    {
        if(i < InNfds && FD_ISSET(i, In))
            FD_SET(i, Out);
    }
}

int Fdset_Merge(fd_set *Out, fd_set const *In1, int NFds1, fd_set const *In2, int NFds2)
{
    FD_ZERO(Out);
    Fdset_Add(Out, In1, Nfds1);
    Fdset_Add(Out, In2, Nfds2);
    return Nfds1 > Nfds2 ? Nfds1 : Nfds2;
}

int Fdset_Filter(fd_set const *Result, int ResultNfds, fd_set *ToFilter, int NfdsToFilter)
{
    int i;
    int Retval;

    Retval = 0;
    for(i = 0; i < ResultNfds; i++)
    {
        if(i < NfdsToFilter && FD_ISSET(i, ToFilter))
        {
            if(! FD_ISSET(i, Result))
                FD_CLR(i, ToFilter);
            else
                Retval++;
        }
    }
    return Retval;
}

void Fdset_Split(fd_set const *Result, int ResultNfds, fd_set *In1, int Nfds1, int *Count1, fd_set *In2, int Nfds2, int *Count2)
{
     *Count1 = Fdset_Filter(Result, ResultNfds, In1, Nfds1);
     *Count2 = Fdset_Filter(Result, ResultNfds, In1, Nfds2);
}
Run Code Online (Sandbox Code Playgroud)


bjg*_*bjg 1

fd_set您可以通过循环每个库可能打开的所有可能的文件描述符以及在每个库返回的集合中设置您自己的文件描述符,并相应地设置您的文件描述符。这有点暴力,但不幸的是选择界面非常原始。例如

fd_set *lib1_read_fds, *lib2_read_fds;
int fd;
fdset my_fd_set;
FD_CLR(&my_fd_set);
for (fd = 0; fd < FD_SETSIZE; fd++) {
    if (FD_ISSET(fd, lib1_read_fds) || FD_ISSET(fd, lib2_read_fds)) {
        FD_SET(fd, &my_fd_set);
    }
}
Run Code Online (Sandbox Code Playgroud)