这个问题如果完整贴代码可能会比较长,所以只简单说一下。
Test1是一个简单的成功的例子:
server端代码大概如下:
set up a listenfd
while (1) {
if (select(listenfd) > 0) {
if (FD_ISSET(listenfd)) {
accept new clientfd
read clientfd
write clientfd
close clientfd
}
}
}
client端代码大概如下:
while (1) {
set up a clientfd
write something to server
read something from server
output them to console
}
这里是没什么问题的,两个进程无限跑。client会先sleep1秒,等一下server。
Test2改成下面这种更加复杂一点的模式时就卡住了,先看代码:
server端:
set up a listenfd
while (1) {
if (select(readset, writeset) > 0) {
foreach(fd in readset) {
if (fd == listenfd) {
accept new clientfd
add clientfd to readset
} else {
/*this is a clientfd accepted before*/
read fd
remove fd from readset
add fd to writeset
}
}
foreach(fd in writeset) {
/*this is a clientfd accepted and readed before*/
write fd
remove fd from writeset
close fd
}
}
}
client端:
while (1) {
set up a clientfd
write something to server
read something from server
output them to console
}
//exactly same as before
client端没有改动,server端将accept之后的动作分开重新交给select去监听。
程序运行的时候是卡住的,我调式也一直卡在select处。
我推测是server端的listenfd在accept到一个clientfd,将该clientfd加入readset的这一过程中,
client端中的fd已经read结束了,因此server端select没有监听到该事件,然后client端在等待server的write,而server在等待client的read?
完整代码地址:
https://github.com/zhaochenyou/tips/blob/master/c/socket/server/select.c
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。