微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从 fd_set 中提取文件描述符

如何解决从 fd_set 中提取文件描述符

我必须在两个不同的协议之间实现一个转换工具。 它应该是一个相对简单的循环,由文件描述符事件触发。 然而,协议 API:

  1. st API:旨在与 select() 一起使用,它公开了一个 GetFD() 方法,该方法将使用 FD_SET 将其 fd 放入给定的 fd_set
  2. nd API:仅适用于 poll()(它是 ZMQ)

有没有办法从 fd_set 中提取 fds,而不调用 select()? (最好是便携的)

我曾尝试查看 fd_set 结构的来源,但它并不是真正可读的,并且可能暗示您不应通过除 4 宏 FD_CLR/SET/ISSET/ZERO 之外的任何内容来接触它。

//Pseudo-code of what i hope to achieve
// Get fd's from API1
fd_set readfds;
FD_ZERO( & readfds );
int max = api1.GetFd(readfds);
    
struct zmq_pollitem_t poll_items[MAX_COUNT];
int fd_count = 0;
convert_fdset_to_pollitem( readfds,poll_items,fd_count ); //what i need

poll_items[fd_count].fd = api2.GetFD();
poll_items[fd_count].socket = api2.GetSocket();
fd_count++;    

const uint32_t timeout_msec = 500;
int ret = zmq_poll( poll_items,fd_count,timeout_msec);

解决方法

一个 select() 函数的例子。您可以将返回值与每个不同的协议套接字进行比较 - 例如if (select_socket(s1,s2) == protocol_1_sd)。我正在使用该函数来处理 http 和 https 套接字。

// selecting corresponding socket from FD_SET
int select_socket(int sock_1,int sock_2) {

     fd_set read;
     struct timeval timeout;

     int ret = -1; 

     FD_ZERO(&read);
     FD_SET(sock_1,&read);
     FD_SET(sock_2,&read);
      
     timeout.tv_sec= 10;
     timeout.tv_usec = 0;

     if (select(FD_SETSIZE,&read,NULL,&timeout ) < 0)
         perror("select");

     for (int i = 0; i < FD_SETSIZE; i++) {

         if (FD_ISSET(i,&read)) {

         if (i == sock_1)
            ret = sock_1; 
        
         else if (i == sock_2)
            ret = sock_2;
        
         else {
            FD_CLR(i,&read);
            ret = -1;
         }  
       }
    }

return ret;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。