Chinaunix首页 | 论坛 | 博客
  • 博客访问: 439696
  • 博文数量: 132
  • 博客积分: 2511
  • 博客等级: 大尉
  • 技术积分: 1385
  • 用 户 组: 普通用户
  • 注册时间: 2006-04-11 15:10
文章分类

全部博文(132)

文章存档

2012年(18)

2011年(35)

2010年(60)

2009年(19)

分类: LINUX

2010-05-20 21:02:02

原文。

首先,文章中有个笔误,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) |
给主人留下些什么吧!~~