免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3264 | 回复: 12
打印 上一主题 下一主题

求助:select 问题! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-04-10 10:20 |只看该作者 |倒序浏览
在LINUX下建立一个套接字skfd,然后连接上SERVER,在使用select 等待套接字描述符skfd变为可读时,如果另外一个线程探测配置文件里面SERVER地址有变化,需要立即重新建立连接,我采用立即关闭现有套接字skfd,然后重新建立套接字skfd连接新的地址的方式,我想问的是:在我CLIENT端关闭skfd时,此时select正在skfd上等待,关闭后skfd后,select会立即返回吗?根据我测试的结果,好象select不会立即返回,一直会等待超时的,各位大侠能告诉我其中的原因吗?
如果我设置select的超时时间比较长,在超时之前,新的套接字skfd已经连接上了新的SERVER,此时新的SERVER给我发送信息时,我这边暂时没有反应,在select的超时返回后,居然回返回新的skfd可读,于是又可以正常的收发数据,请问这又是为什么?要知道这可是两个不同的套接字啊,虽然他们的描述符名字都是skfd,这让我想不通,这可能需要知道select()是如何实现的。
第三个问题:需要立即重新连接SERVER时,我采用立即关闭现有套接字skfd,然后重新建立套接字skfd连接新的地址的方式,这样的方法合适吗?因为此时设备最好不要中断,还有其他的模块要运行,有没有其他好的方法?

论坛徽章:
0
2 [报告]
发表于 2008-04-10 10:46 |只看该作者
select没有检测到fd中有可读入的数据,因此等待超时返回

你关闭一个fd,只是引用数减一,如果这个fd正在被别的线程使用,那么他的引用数不会是0,因此不会真的关闭。
由此可以推断,你新建立的socket链接fd与原来的那个fd一定不一样。

当程序进入第二此循环后,新的fd被使用,这里select检测了新的fd,因此,你继续使用信fd了。

select在实现的时候,一定是轮询,无论什么样的多线程,活着多进程,底层只有“时分复用”,这个词不陌生吧???

你的地三个问题,你关闭链接,再重新建立链接的方法应该没有问题

论坛徽章:
0
3 [报告]
发表于 2008-04-10 10:47 |只看该作者
你发帖的格式是在是让我看得眼花。

请分段

论坛徽章:
0
4 [报告]
发表于 2008-04-10 11:30 |只看该作者
原帖由 mouse2000 于 2008-4-10 10:20 发表
在LINUX下建立一个套接字skfd,然后连接上SERVER,在使用select 等待套接字描述符skfd变为可读时,如果另外一个线程探测配置文件里面SERVER地址有变化,需要立即重新建立连接,我采用立即关闭现有套接字skfd,然 ...


我的看法,有点猜测的意思:

select是不是立即返回取决你的timeout,要是你设置不为0的话,它是要等的。调用select等待时,你已经把文件描述符设定在了三个fd_set中,这样相应位已经被设置了,但你重新连接后的sockfd值已经发生了变化,但select还是在等原来的描述符,所以不会立即返回。当select返回后,用sockfd再发送数据当然是可以的,因为它已经建立好连接了。

论坛徽章:
0
5 [报告]
发表于 2008-04-10 12:24 |只看该作者
说说我的看法, 你select()在等待的时候, 另外一个线程去关闭了这个套接字, 那么你当前进程执行的是主动关闭, 此时SERVER也只是到了CLOSE_WAIT状态, 此时如果你的SERVER端不调用close, 你的select()就不会检测到读套接口有数据到达.
我认为你应该看看你的SERVER端在接收到了FIN包之后是怎样处理的, 如果立即调用close()完成最后的关闭, 则CLIENT的select()就会返回.

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
6 [报告]
发表于 2008-04-10 12:41 |只看该作者
我也猜猜:

      开始创建的fd = 5. 当你关闭后.当前进程空间的文件描述符的最小可用值就变成5..
      你马上又创建一个socket..此时新建的socket 就是5 ..但select fd_set 里边的fd
      值还是5, 导致后来你说的"居然回返回新的skfd可读,于是又可以正常的收发数据"
如果SERVER也调用了close 那么你这边的可读.或许是新连接的SYS 也或许是SERVER
发过来的FIN

论坛徽章:
0
7 [报告]
发表于 2008-04-10 12:58 |只看该作者

回复 #6 cookis 的帖子

嗯, 我赞成你的解释.

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
8 [报告]
发表于 2008-04-10 13:02 |只看该作者
原帖由 net_robber 于 2008-4-10 10:46 发表
select没有检测到fd中有可读入的数据,因此等待超时返回

你关闭一个fd,只是引用数减一,如果这个fd正在被别的线程使用,那么他的引用数不会是0,因此不会真的关闭。
由此可以推断,你新建立的socket链接fd ...


如果是多线程操作一个fd .不会使用fd的计数增加的..除非是多进程

论坛徽章:
0
9 [报告]
发表于 2008-04-10 13:05 |只看该作者
原帖由 cookis 于 2008-4-10 13:02 发表


如果是多线程操作一个fd .不会使用fd的计数增加的..除非是多进程

我搞混了,谢谢

论坛徽章:
0
10 [报告]
发表于 2008-04-10 13:47 |只看该作者
原帖由 It'sGifted 于 2008-4-10 11:30 发表


我的看法,有点猜测的意思:

select是不是立即返回取决你的timeout,要是你设置不为0的话,它是要等的。调用select等待时,你已经把文件描述符设定在了三个fd_set中,这样相应位已经被设置了,但你重新连接后的sockfd值已经发生了变化,但select还是在等原来的描述符,所以不会立即返回。当select返回后,用sockfd再发送数据当然是可以的,因为它已经建立好连接了。


赞成这个分析.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP