原文。
首先,文章中有个笔误,lsof写成losf了。
其次刚看到这篇文章时,有个疑问,文章中说listen之后如果服务端hang住了的话,假在accept之前,客户端进行了connect(),那这个连接应该还是会被放在TCP的未完成连接队列中的,accept()之后才会转到已完成连接队列中,还以为作者说错了。后来发现,自己记错了,listen()之后,客户端的连接还是可以建立的,在三次握手完成之前,都会被放在未完成队列中,只有完成TCP握手后,才会被放在完成队列中,这些都是在accept()之前完成的,accept()只是会返回已完成连接队列中的第一个。
再者,第一次看到用epoll来进行非阻塞connect,以前都是用select()。
==========MatCNo|转载开始===================
创
建一个socket
设为异步
socket(fcntl)
将
socket加入epoll
connect
到远端(此时connect调用返回非0,但errno为EINPROGRESS,表示正在建立连接中)
epoll_wait之
捕获到EPOLLOUT事件,此时便认为connect
已经成功,client端开始发消息
这个过程通常能够运转,但是线上环境复杂多变,如果发生这种情况:server进程调用listen开始侦听后,被gdb或信号挂住了,此时
异步connect会怎样?很遗憾,client端的epoll_wait依然返回EPOLLOUT,甚至往此socket里发消息都返回成功,只有当发
的消息多得占完了server端的tcp缓冲以后(窗口收缩到很小),send调用才开始失败。这时候用 losf -i
看网络连接也很有趣,client端的机器显示连接建立了,server端的却显示没有这个连接。
仔细想想,OS这样做是正确的,毕竟
connect的语义只是“连接”,当server挂住时,连接还是能成功的,但你能不能往里面发消息那就是另外一回事了。
所以对于应用来说,异步socket想要知道
connect后连接是不是可以正常收发数据了,还是要靠应用层的一问一答才能知道。
====== 2010.5.14 ======
昨天同事管理员在2009年8月13日编辑了该文章文章。
-->
阅读(2828) | 评论(0) | 转发(0) |