套接字文件描述

时间:2012-02-23 03:04:49

标签: c linux sockets

所以当有人使用select()向我展示一些代码时,我完全失去了它:

FD_ZERO(&readfds);
FD_SET(socket,&readfds);
FD_SET(0,&readfds);
.......// bind() and listen(),regular stuff
// Before select(),this guy cleared readfds to null and sort of start all over again
FD_ZERO(&readfds);// Behold,this is exactly the line confusing myself
FD_SET(socket,&readfds);
// select will be called in the future within a infinite loop 

所以基本上说绑定和监听之后的FD_ZERO由于某种原因清楚了之前的内容并将套接字文件描述符再次插入到fd中。同时,在fd set中,0描述符(标准输入)显然已经消失了。 / p>

有人可以解释这一切吗?我不觉得这是正确的,但我真的无法弄明白。也许重新设置一些特定的fd设置是一种实用的机制......

我认为bind()listen()可以某种方式修改fd。我设置了几个断点并检查输出。因此,fd set根本没有改变。< / p>

更新

真正令我困惑的是第二个FD_ZERO(&readfds)。 显然,第一个就像在缓冲区中清除生锈的东西。在每次迭代中,我们必须将fdset清除为将来的默认值。我只是不明白第二个。无论是错误的还是无论如何都不会受到伤害。

3 个答案:

答案 0 :(得分:4)

不确定你的困惑在哪里,但这是一个解释。

fdset是从零开始索引的文件描述符的位掩码(从技术上讲,我不认为它是一个位掩码,但任何其他实现都是......奇怪的。)

所以fdset可能是这样的:

              Byte 0                              Byte 1
+---+---+---+---+---+---+---+---+ +---+---+----+----+----+----+----+----+
|fd0|fd1|fd2|fd3|fd4|fd5|fd6|fd7| |fd8|fd9|fd10|fd11|fd12|fd13|fd14|fd15|
+---+---+---+---+---+---+---+---+ +---+---+----+----+----+----+----+----+

我们的想法是,如果您对它感兴趣,可以为给定的fd(文件描述符)设置位。如果你对它不感兴趣,你就明白了。

FD_ZERO将清除所有位,这是一个很好的起点。然后,两个FD_SET调用将设置fd0(标准输入)和fd<socket>的位。

然后,如果对标准输入或套接字上的操作有操作,则使用该fdset的select调用将返回(类型的操作将取决于您在传递fdset时使用的参数位置到select。将它作为读取fdset传递意味着如果您可以读取套接字或标准输入上显示的内容(例如您使用键盘),您将返回。

这可能对“聊天”应用程序的代码很有用,因为它会等待你或你朋友在另一端的输入。

你必须重新归零并重新设置fdset中的位的原因是因为select本身修改了集合以指示它检测到动作的fd(或fds)。

示例:如果通过套接字传入某些内容而没有通过标准输入传入任何内容,则select将修改fdset以仅设置该位。这样您就可以使用FD_ISSET来检测您应该查看哪些fds。


如果您似乎在评论中指出,两个select序列之间存在没有 readfds次呼叫(或使用FD_ZERO()/FD_SET()的其他呼叫) ,是的,似乎第一个是不必要的,因为信息将被第二个覆盖。

没有看到完整的代码或建筑设计文档:-),很难说。

答案 1 :(得分:1)

当您尝试同时侦听多个套接字时,会使用

Select()。每次你接受()一个套接字连接时,都会返回一个套接字描述符,你可以使用它来发送/接收文件。

当您执行FD_SET时,您将套接字描述符添加到集合中(可能是读/写)。 FD_ZERO清除该特定集合中的所有条目。

所以基本上每次接受连接时都可以将套接字描述符添加到集合中(即如果你想使用该套接字进行读/写)。

当您调用select()功能时,您可以指定要使用的设置。 (例如:readfds)和select()轮询该集合中已有的所有套接字(readfds)。

有关更多说明,请阅读beej's guide to network programing。这是一个非常好的学习教程。

答案 2 :(得分:0)

select(2)修改了它的参数fd sets,所以你应该在每次迭代时重新初始化它们。