【问题标题】:Extracting filedescriptors from fd_set从 fd_set 中提取文件描述符
【发布时间】:2021-05-28 07:42:36
【问题描述】:

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

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

有没有什么方法可以在不调用 select() 的情况下从 fd_set 中提取 fd? (最好是便携的)

我已尝试查看 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);

【问题讨论】:

    标签: linux sockets posix


    【解决方案1】:

    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, 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;
    }
    

    【讨论】:

    • 我的问题不是找到 fd 的来源,而是避免同时调用 select() 和 poll()。我试图更新我的答案来解决这个问题。
    • 我怀疑那时是否有一个相对简单的循环解决方案。也许您可以查看libevent.org,这可能会有所帮助。
    猜你喜欢
    • 1970-01-01
    • 2021-07-06
    • 1970-01-01
    • 1970-01-01
    • 2012-10-07
    • 1970-01-01
    • 2020-10-31
    • 2020-09-08
    • 1970-01-01
    相关资源
    最近更新 更多