【问题标题】:New to socket programming, questions regarding "select()"套接字编程新手,关于“select()”的问题
【发布时间】:2015-12-29 06:06:24
【问题描述】:

目前在我的学位中,我们开始使用套接字。

我有几个关于从套接字轮询输入的问题,

使用 select() 函数。

int select( int nfds,
    fd_set *readfds,
    fd_set *writefds,
    fd_set *exceptfds,
    const struct timespec *timeout);
  1. 我们提供选择“nfds”参数,这通常会 是我们想要监控的最大套接字数。我怎样才能只看一个特定的套接字而不是 0 到 nfds_val 套接字的范围?

  2. 我们使用哪些文件描述符对象?他们的目的是什么, 为什么我们不能只将“select”指向相关的套接字结构?

  3. 我在论坛上阅读了关于 BlockingNon-Blocking 模式的选择,但无法理解它们的含义或用途,也不如何实现,如果有人可以解释,将很高兴。

  4. 最后但并非最不重要的(仅暂时 :D) - 当将 socketaddr_in 绑定到套接字号时,为什么需要强制转换为 socketaddr * 而不是将其保留为 sockaddr_in * ? 我的意思是除了 bind 方法需要这种指针类型;)

希望这里有一些专家的回答:)

谢谢你们,祝大家度过愉快的一周!

【问题讨论】:

    标签: sockets select file-descriptor


    【解决方案1】:

    我们提供 select "nfds" 参数,这通常是我们想要监控的最大套接字数。我怎样才能只看一个特定的套接字而不是 0 到 nfds_val 套接字的范围?

    编辑。(抱歉,这里之前的文字有误)只需提供您的套接字descriptor + 1。我很确定这并不意味着操作系统会检查 [0, 1... descriptor] 范围内的所有描述符。

    我们使用的文件描述符对象是什么?它们的目的是什么,为什么我们不能将“select”指向相关的套接字结构?

    文件描述符通常是操作系统给用户的整数值。 OS 使用描述符来控制物理和逻辑资源 - 一个文件描述符意味着 OS 为您提供了一些 file-like 来控制。由于 Berkeley 套接字定义了读取和写入操作,它们是类似文件的,并且套接字对象本质上是普通文件描述符。

    回答why can't we just point "select" to the relevant socket structure? - 我们确实可以。传递给select 的具体内容取决于操作系统和语言。在 C 中,您将套接字描述符(很可能是纯 int 值)放入 fd_set。然后将fd_set 传递给select

    编辑。 Linux 的一个小例子:

    fd_set set;
    FD_ZERO(&set);
    FD_SET(socket_fd, &set);
    // check if socket_fd is ready for reading
    result = select(socket_fd + 1, &set, NULL, NULL, NULL);  
    if (result == -1) report_error(errno);
    

    Docs.
    Windows has similar code.

    我在论坛上阅读了有关 select 的阻塞和非阻塞模式,但无法理解每个的含义或用途,也不知道如何实现,如果有人可以解释,将很高兴。

    阻塞操作让你的线程等待直到它完成。它是您使用的 99% 的功能。如果有套接字准备好进行一些 IO,阻塞select 将立即返回something。如果没有这样的套接字,线程将等待它们。 非阻塞select,在后一种情况下,不会等待,会返回-1(错误)。

    例如,尝试实现能够与多个客户端一起工作的单线程服务器,包括同时发生文件传输等长时间操作。在这种情况下,您绝对不想使用阻塞套接字操作。

    最后但并非最不重要的(仅暂时 :D ) - 当将 socketaddr_in 绑定到套接字编号时,为什么需要强制转换为 socketaddr * 而不是将其保留为 sockaddr_in * ?我的意思是除了 bind 方法需要这种指针类型的事实;)

    可能由于历史原因,但我不确定。 And there seems to be a fine answer on SO already.

    【讨论】:

    • 感谢您的有用评论。关于只监控一个特定的套接字 - 如何做到这一点?您提到 在 C 中您将套接字描述符(很可能是纯 int 值)放入 fd_set - 您如何“放置”它?这种“铸造”的惯例是什么?相反 - 当使用 select 监视多个套接字时,fd_set 的内容表示什么?谢谢你的精彩评论。欣赏它。
    • @Adiel fd_set 只是一个由描述符数组和数组长度组成的容器(参见Windows implementation as an example)。所以这里没有类型转换 - 你只需将你的套接字(套接字)放入一个特殊的容器中。我已经用一个例子更新了答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-15
    • 2010-10-27
    • 1970-01-01
    • 2019-08-30
    • 1970-01-01
    • 2022-10-06
    相关资源
    最近更新 更多