42. TCP套接字之accept非阻塞


本节来理论性的了解一下关于服务端 accept 非阻塞.


阻塞 accept

服务器在繁忙过程时, 在建立三次握手之后, 调用accept之前, 如果出现客户端突然断开连接的情况, POSIX 指出这种情况 errno 设置为 CONNABORTED.

如: 三次握手之后, 客户端发送 RST后断开连接, 之后服务端调用accept准备执行连接但并不知道对端已经关闭, 这个时候accept就会阻塞, 直到有下一个已完成的连接准备好被accept为止. 这个问题在 TCP可能出现的异常[1] 中提到过, 只是实验没有成功.

上述描述的整个过程如下 :

  1. 服务器的监听的 socket 可读, 但服务器要在一段时间之后 (实验中采用sleep模仿) 才能调用accept.
  2. 服务器调用accept之前, 收到从客户发送过来的 RST;
  3. 这个已经完成的连接被从已完成连接队列中被删除;
  4. 服务器调用 accept, 但是由于没有其它已完成的连接存在, 因而服务器被阻塞了.

服务器会被一直阻塞在accept调用上, 直到另外一个客户建立一个连接为止; 但如果一直没有其它客户建立连接, 那么服务器将仍然一直被阻塞在accept调用上, 不处理任何其他已就绪的 socket. 这样的就严重降低了服务器的利用率.


非阻塞 accept

上述的问题也很容易解决, 解决这个问题的办法:

如果使用 select 来获知何时有已完成连接时, 总是把监听 socket 设置为非阻塞模式,并且在 accept 调用中忽略以下错误 : EWOULDBLOCK (Berkeley : 客户放弃连接时出现的错误)、 ECONNABORTED (POSIX : 客户放弃连接时出现的错误)、 EPROTO (SVR4 : 客户放弃连接时出现的错误) 和 EINTR (信号中断).


小结

  • 阻塞 accept 可能发生的错误
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值