您的位置:首页 > 其它

关于非阻塞connect和select设置

2010-02-02 15:24 295 查看
发现socket api中对connect进行超时判断,期间可能疏忽的一问题~~~

如果设置connect为非阻塞函数后, 进行select时只关注writefds,忽略exceptfds,可能出现一个问题:本来不想由于connect阻塞等太久,结果用select后反而傻等了。

看msdn对select中的exceptfds参数的说明:

int select(
__in int nfds,
__in_out fd_set* readfds,
__in_out fd_set* writefds,
__in_out fd_set* exceptfds,
__in const struct timeval* timeout
);

The parameter exceptfds identifies the sockets that are to be checked for the presence of OOB data or any exceptional error conditions.

Note Out-of-band data will only be reported in this way if the option SO_OOBINLINE is FALSE. If a socket is processing a connect call (nonblocking), failure of the connect attempt is indicated in exceptfds (application must then call getsockopt SO_ERROR to determine the error value to describe why the failure occurred). This document does not define which other errors will be included.
标志红色的大概意思是说:在进行非阻塞connect时,失败的事件是放在exceptfds中的……
那么, 如果在connect后开始select,只关注writefds,设置的超时是10秒, 在connect发出[SYN]后:
假定目标IP的主机不存在或者是目标端口给防火墙过滤了,那么你等再久也不会有任何回复, 这时候如果是阻塞connect可能要15秒才返回, 那么你10秒就返回了, 这种情况就赚了5秒
然而假定connect的目标IP主机是存在的也没防火墙,只是端口是没打开的,在connect发出[SYN]后的1秒系统已经收到目标主机回复的[RST, ACK],也就是说系统此时已经知道这个端口是连接不上的了, 但是应用程序只关注writefds,后面的9秒钟select就会傻傻的等待下去……原本以为用select来减少不必要的等待时间, 如果不设置参数exceptfds,这时候反而浪费时间。
貌似网上讨论connect设置超时的话题已经是很老了, 百度出来的也N多页,我有限的翻了一些看看, 貌似都没人理会 参数exceptfds,……
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: