套接字编程新手,有关 "select()" 的问题
New to socket programming, questions regarding "select()"
目前在我的学位课程中,我们开始使用套接字。
我有几个关于从套接字轮询输入的问题,
使用 select() 函数。
int select( int nfds,
fd_set *readfds,
fd_set *writefds,
fd_set *exceptfds,
const struct timespec *timeout);
我们给 select "nfds" 参数,这通常会
是我们想要监控的最大套接字数。我怎样才能只看一个特定的套接字而不是 0 到 nfds_val 套接字的范围?
我们使用的文件描述符对象是什么?他们的目的是什么,
为什么我们不能直接将 "select" 指向相关的套接字结构?
我在论坛上阅读了有关 阻塞 和 非阻塞 模式的 select ,但不明白每个的含义或用途,也不知道如何实现,如果有人能解释一下,我会很高兴。
最后但并非最不重要的(仅暂时:D)-将socketaddr_in绑定到套接字编号时,为什么需要转换为socketaddr * 而不是将其保留为 sockaddr_in * ?
我的意思是除了 bind 方法需要这种指针类型之外;)
在此感谢一些专家的回答:)
谢谢你们,祝大家度过愉快的一周!
We give select "nfds" param, which would normally would be the maximum sockets number we would like to monitor. How can i watch only one specific socket instead of the range of 0 to nfds_val sockets ?
Edit.(抱歉,这里之前的文字有误)只需提供您的插座descriptor + 1
。我很确定这并不意味着 OS 将检查 [0, 1... descriptor]
范围内的所有描述符。
What are the file descriptors objects that we use? what is their purpose, and why can't we just point "select" to the relevant socket structure?
文件描述符通常是由 OS 提供给用户的整数值。 OS 使用描述符来控制物理和逻辑资源 - 一个文件描述符意味着 OS 已经给了你一些 file-like 来控制。由于 Berkeley 套接字定义了读写操作,因此它们是 file-like 并且套接字对象本质上是普通文件描述符。
回答why can't we just point "select" to the relevant socket structure?
- 我们确实可以。传递给 select
的具体内容取决于 OS 和语言。在 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.
I've read over the forum regarding Blocking and Non-Blocking mode of select, but couldn't understand the meaning or uses of each, nor how to implement such, would be glad if someone could explain.
阻塞 操作使您的线程等待完成。这是您使用的 99% 的功能。如果有套接字准备好进行某些 IO,阻塞 select
将立即 return something
。如果没有这样的套接字,线程将等待它们。 Non-blocking select
,在后一种情况下,不会等待,会return -1
(错误)。
例如,尝试实现能够与多个客户端一起工作的单线程服务器,包括同时发生的文件传输等长时间操作。在这种情况下,您绝对不想使用阻塞套接字操作。
Last but not least (only for the time being :D ) - When binding a socketaddr_in to socket number, why does one needs to cast to socketaddr * and not leave it as sockaddr_in * ? I mean except for the fact that bind method expects this kind of pointer type ;)
可能是由于历史原因,但我不确定。 And there seems to be a fine answer on SO already.
目前在我的学位课程中,我们开始使用套接字。
我有几个关于从套接字轮询输入的问题,
使用 select() 函数。
int select( int nfds,
fd_set *readfds,
fd_set *writefds,
fd_set *exceptfds,
const struct timespec *timeout);
我们给 select "nfds" 参数,这通常会 是我们想要监控的最大套接字数。我怎样才能只看一个特定的套接字而不是 0 到 nfds_val 套接字的范围?
我们使用的文件描述符对象是什么?他们的目的是什么, 为什么我们不能直接将 "select" 指向相关的套接字结构?
我在论坛上阅读了有关 阻塞 和 非阻塞 模式的 select ,但不明白每个的含义或用途,也不知道如何实现,如果有人能解释一下,我会很高兴。
最后但并非最不重要的(仅暂时:D)-将socketaddr_in绑定到套接字编号时,为什么需要转换为socketaddr * 而不是将其保留为 sockaddr_in * ? 我的意思是除了 bind 方法需要这种指针类型之外;)
在此感谢一些专家的回答:)
谢谢你们,祝大家度过愉快的一周!
We give select "nfds" param, which would normally would be the maximum sockets number we would like to monitor. How can i watch only one specific socket instead of the range of 0 to nfds_val sockets ?
Edit.(抱歉,这里之前的文字有误)只需提供您的插座descriptor + 1
。我很确定这并不意味着 OS 将检查 [0, 1... descriptor]
范围内的所有描述符。
What are the file descriptors objects that we use? what is their purpose, and why can't we just point "select" to the relevant socket structure?
文件描述符通常是由 OS 提供给用户的整数值。 OS 使用描述符来控制物理和逻辑资源 - 一个文件描述符意味着 OS 已经给了你一些 file-like 来控制。由于 Berkeley 套接字定义了读写操作,因此它们是 file-like 并且套接字对象本质上是普通文件描述符。
回答why can't we just point "select" to the relevant socket structure?
- 我们确实可以。传递给 select
的具体内容取决于 OS 和语言。在 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.
I've read over the forum regarding Blocking and Non-Blocking mode of select, but couldn't understand the meaning or uses of each, nor how to implement such, would be glad if someone could explain.
阻塞 操作使您的线程等待完成。这是您使用的 99% 的功能。如果有套接字准备好进行某些 IO,阻塞 select
将立即 return something
。如果没有这样的套接字,线程将等待它们。 Non-blocking select
,在后一种情况下,不会等待,会return -1
(错误)。
例如,尝试实现能够与多个客户端一起工作的单线程服务器,包括同时发生的文件传输等长时间操作。在这种情况下,您绝对不想使用阻塞套接字操作。
Last but not least (only for the time being :D ) - When binding a socketaddr_in to socket number, why does one needs to cast to socketaddr * and not leave it as sockaddr_in * ? I mean except for the fact that bind method expects this kind of pointer type ;)
可能是由于历史原因,但我不确定。 And there seems to be a fine answer on SO already.