码迷,mamicode.com
首页 > 其他好文 > 详细

TCP_DEFER_ACCEPT的坑

时间:2014-11-19 23:42:57      阅读:297      评论:0      收藏:0      [点我收藏+]

标签:http   io   ar   on   cti   代码   ef   时间   linux   

我实现了一个server,支持HTTP协议和内部私有协议,为了简化部署,我设计成一个端口同时兼容两种协议的客户端。根据连接后到达的消息头自动识别客户端协议。这种事情的传统做法是,accept后加入epoll,当fd第一次可读时,读出一些并解析,判断协议类型。

创建相应的上下文对象,开始服务。这样就引入了中间状态,为了省事,我用了TCP_DEFER_ACCEPT来简化这个过程。

TCP_DEFER_ACCEPT,是Linux下的socket支持一个tcp选项,man这么说的:

TCP_DEFER_ACCEPT

    Allows a listener to be awakened only when data arrives on the socket. Takes an integer value (seconds), this can bound the maximum number of
  attempts TCP will make to complete the connection. This option should not be used in code intended to be portable.

这样,当accept后,马上就读出并解析协议头,然后再把fd设置为非阻塞的,创建上下文对象,代码简化了不少。

但是今天用大量短连接压测时,发现连接数过了几千后,程序急剧变慢,最后干脆停止响应了。gdb上去看发现居然阻塞在recv的地方,加时间日志发现,recv居然有不少耗时数百毫秒,而如果先设置成非阻塞的,读取时就会大量返回EAGAIN错误。看来行为和文档并不一样。

最后,我把代码改为在epoll通知可读时再读取并解析,故障消失。

TCP_DEFER_ACCEPT的坑

标签:http   io   ar   on   cti   代码   ef   时间   linux   

原文地址:http://www.cnblogs.com/chen3feng/p/4109257.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!