SOCKET文件描述
所以我完全失去了它,当有人使用select()像我展示了一些代码:SOCKET文件描述
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集中,0描述符(标准输入)显然消失。
谁能解释这件事?我不觉得这是正确的,但我不能真正弄清楚。也许再次设置一些特定的FD设置是一种实际的机制...
我认为bind()
和listen()
可以修改fd集以某种方式。我设置了几个断点,并检查输出。随后,FD集没有改变。
UPDATE:
真正让我困惑的是第二FD_ZERO(&readfds)
。 显然,第一个就像在缓冲区中清理生锈的东西。在每次迭代中,我们必须将fdset清除为未来的默认值。我只是不理解第二个。要么是错误的,要么不会伤害到任何人。
不知道从哪里你的困惑所在,但这里的一个解释。
的fdset是从0开始索引文件描述符位掩码(在技术上,我不认为它有是一个位掩码,但任何其他的实现是......怪)。
因此,一个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一个选择调用将返回。传它作为读取fdset意味着如果你能够读取套接字或者在标准输入中显示出某些内容(例如使用键盘),就会返回。
这可能对代码很有用“聊天”的应用,因为它会等待从你或你的朋友在另一端输入。
你之所以公顷已经重新调零并重新设置这些位中的fdset是因为select
本身修改所述一组,以指示什么FD(或FDS)它检测到的动作。
示例:如果有东西通过套接字进入,而没有通过标准输入进入,则fdset将被修改select
以仅设置该位。这样你就可以用FD_ISSET
来检测你应该看哪个fds。
如果,你似乎在注释中指出,有两个FD_ZERO()/FD_SET()
序列之间(使用readfds
或其它呼叫),则没有select
电话,是的,看来首先是不必要的,因为信息将被第二个覆盖。
没有看到完整的代码或建筑设计文档:-),很难说。
Select()
用于当您试图同时侦听多个套接字时。每当你接受()一个套接字连接时,一个套接字描述符被返回,你用它来发送/接收文件。
当你做一个FD_SET
你添加一个套接字描述符(它可能是读/写)。 FD_ZERO
清除该特定集合中的所有条目。
因此,基本上每次接受连接时都可以将套接字描述符添加到套件中(即如果要使用该套接字来读/写)。
当您调用select()
函数时,您可以指定要使用的集合。 (例如:readfds)和select()
轮询所有已经在该组中的套接字(readfds)。
欲了解更多信息,请阅读beej's guide to network programing。它是一个非常好的教程来学习。
'select'会改变fdset,但'bind'和'listen'不能,它们甚至没有指向它的指针。但是请自己帮忙,并使用像'poll'或'epoll'这样的现代API,并且不要再担心fdset。 – 2012-02-23 03:18:23
听起来很酷,但我不能得到它 – jasonkim 2012-02-23 03:20:57
使用'民意测验'。它现代,便携和快速。 'epoll'仅用于基准自我愉悦,它擅长的基准测试不符合大多数真实世界的使用需求(其中'epoll'实际上比'poll'慢得多)。 – 2012-02-23 03:50:41