对于非阻塞connect的一点认识

本文深入探讨了TCP非阻塞connect操作与select之间的交互,详细解释了其工作原理,包括如何立即返回错误EINPROGRESS,以及如何通过getpeername或read操作来验证connect是否成功。同时,文章提供了三种解决connect与select间非原子操作导致的误判问题的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一般如下:

connect();

select();


由于是非阻塞,很自然connect立即返回,而不同于阻塞条件下的成功或者失败才返回。

对于TCP来说,非阻塞的connect会立即返回一个错误EINPROGRESS,而且完成3路握手。

对于UDP来说,个人觉得,由于内核只是检查是否存在立即可知的错误,并记录对方的IP和端口号,没必要使用非阻塞的connect。

正常情况:

如果connect成功,select会发现套接字变得可写。出错的话套接字变得可写且可读。

极端情况:

connect于select之间并非原子操作,存在时间间隙。如果这个时候connect成功且收到一些数据的话,这个时候套接字由于有数据可读变得可读,又由于connect成功变得可写。

这样会导致本来connect成功,却误当做发生错误。


解决办法:

1.既然connect成功,那就用getpeername获取远端地址。如果出现ENOTCONN错误,则表示connect失败。 个人觉得这条方案不太好。

2.以值0调用read,如果read失败,那么connect失败,链接成功read返回0. 

3.再调用一次connect一次,如果错误为EISCONN,那么套接口已经连接成功。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值