非阻塞listenfd

12 篇文章 0 订阅
10 篇文章 0 订阅

先说一下为什么要使用非阻塞的accept.如果我们使用select或者epoll对listenfd进行监控,正常情况下,三次握手完成之后,服务器端维护了一个队列来保存这些连接,select或者epoll会触发listenfd的可读事件来待程序员调用accept返回这个连接的描述字.但是有一些特殊的情况在本博客中的TCP连接中的close和shutdown一文中提到了一种情况.调用close函数,并且(l_onoff = 1, l_linger =0),这种情况是为了尽快回收套接字资源,不发送FIN报文,发送的时RST报文,套接字直接进入CLOSE状态,不会进入TIMEWAIT状态.这种情况就要求非阻塞accept的存在.

假设一种情况,当客户度端发起连接,完成了三次握手之后.但是此时服务器端因为很忙碌,还没有调用accept函数来确认这个连接.此时客户端使用close函数关闭了连接,注意此时客户端发送的是RST报文而不是FIN报文,所以该链接就在内核中就被断开了,但是此时用户层并不知道这种变化,如果此时服务器端经过epoll触发的listenfd调用阻塞的accept,那么由于连接已经被取消,所以accept就会被阻塞,那么其他注册在epoll中的fd就不能被即使处理,所以我们需要将listenfd设置为非阻塞的,保证完成accept时非阻塞的.

当设置accept是非阻塞的时,如果有连接存在,那么accept正常返回.如果时没有连接存在,或者像上述所说的连接被取消了,那么会返回不同的错误码,我们只需要在accept返回错误后检查这些错误码,如果是这两种情况,把它当做征程情况不用处理即可.


ps:尝试了如果在accept之前,使用正常的close,也就是发送正常的FIN报文的话,accept会返回成功,返回正常的socketfd,在下一次读事件时会读到0.也就是说正常的退出不会出现上述情况,不需要非阻塞的accept来处理.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值