套接字编程的新手,有关" select()"

时间:2015-12-29 06:06:25

标签: sockets select file-descriptor

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

关于轮询输入的轮询,我有几个问题,

使用select()函数。

int select( int nfds,
    fd_set *readfds,
    fd_set *writefds,
    fd_set *exceptfds,
    const struct timespec *timeout);
  1. 我们给select" nfds" param,通常会 是我们想要监控的最大套接字号。我怎样才能只观看一个特定的插座而不是 0到nfds_val 插座的范围?

  2. 我们使用的文件描述符对象是什么?他们的目的是什么, 为什么我们不能指出"选择"到相关的套接字结构?

  3. 我已经在论坛上阅读了有关阻止非阻止模式的选择,但无法理解其含义或用途如果有人能够解释,那么每个人,以及如何实施这些,都会很高兴。

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

  5. 非常感谢一些专家在这里的回答:)

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

1 个答案:

答案 0 :(得分:2)

  

我们给出选择“nfds”param,这通常是我们想要监视的最大套接字号。我怎样才能只观察一个特定的套接字而不是0到nfds_val套接字的范围?

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

  

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

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

回答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.

  

我已经阅读了论坛关于阻止和非阻止模式的选择,但无法理解每个模式的含义或用途,也不知道如何实现这些模式,如果有人能解释的话会很高兴。

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

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

  

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

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