【问题标题】:How to access FDs in fd_set through indexing in Linux?如何在 Linux 中通过索引访问 fd_set 中的 FD?
【发布时间】:2018-12-10 03:10:22
【问题描述】:

例如,我可以在 Windows 中使用fd_set.fd_array[i] 访问它们..

request_list getIncomingRequests()
{
    fd_set master_set_copy = master_set;
    request_list requests;
    int socket_count = select(0, &master_set_copy, nullptr, nullptr, nullptr);
    for (int i = 0; i < socket_count; ++i)
    {
    #ifdef _WIN32
        auto req_fd = master_set_copy.fd_array[i];
    #else
        auto req_fd = master_set_copy...[i]; // ??
    #endif
        sockaddr_in req_addr;
        getsockname(req_fd, (sockaddr*)&req_addr, &addr_len);
        requests.push_back(request(req_fd, this->fd, req_addr));
    }
    return requests;
}

但是fd_array 在 Linux 中不存在,所以我需要一个等价物。

【问题讨论】:

  • C 和 C++ 是两种不同的语言。请删除其中一个标签。
  • 你能编辑你想要达到的目标吗?这对我来说太笼统了,
  • @DYZ 我知道,但套接字 API 适用于 C 和 C++,而不仅仅是它们。
  • @ThiruShetty 我只想通过索引访问 fd_set 中的任何套接字..
  • @XStylish 你不能直接使用windows代码直接..需要DYZ建议的少量修改

标签: c++ c linux sockets networking


【解决方案1】:

fd_set 的 POSIX 实现不要求结构具有字段fd_arrayfd_set 应该是一个不透明的数据结构。

您可以通过遍历所有受支持的描述符(0FD_SETSIZE-1)并调用 FD_ISSET() 来检查设置了哪些文件描述符。

注意来自手册页:

select() 只能监控小于FD_SETSIZE 的文件描述符数; poll(2) 没有这个限制。请参阅错误。

【讨论】:

  • 我还需要将select()中的第一个参数设置为FD_SETSIZE。在没有它的情况下它在 Windows 中工作真的很奇怪,但是.. 谢谢。
  • 如果是这样,那我想我会使用poll
  • 使用pollselect糟糕
  • @XStylish 套接字在 Linux 上使用描述符,所以 select() 需要被告知要监视的最高描述符。但是Windows上的sockets是内核对象,select()的第一个参数被忽略了。这是记录在案的行为。另外,由于fd_set 是不透明的,在某些平台上您需要使用FD_COPY() 将一个fd_set 复制到另一个。
【解决方案2】:

添加一个新变量,可能是max_fd,它跟踪集合中编号最高的文件描述符。然后你可以这样做:

request_list getIncomingRequests()
{
    fd_set master_set_copy = master_set;
    request_list requests;
    int socket_count = select(max_fd + 1, &master_set_copy, nullptr, nullptr, nullptr);
    for (int req_fd = 0; req_fd <= max_fd; ++req_fd)
    {
        if (!FD_ISSET(req_fd, &master_set_copy))
            continue;
        sockaddr_in req_addr;
        getsockname(req_fd, (sockaddr*)&req_addr, &addr_len);
        requests.push_back(request(req_fd, this->fd, req_addr));
    }
    return requests;
}

但您最好使用poll 而不是select

【讨论】:

    猜你喜欢
    • 2020-06-30
    • 1970-01-01
    • 2011-12-24
    • 2015-10-13
    • 1970-01-01
    • 2019-02-13
    • 1970-01-01
    • 2012-04-20
    • 2012-05-13
    相关资源
    最近更新 更多