免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: wyezl
打印 上一主题 下一主题

epoll模型的使用及其描述符耗尽问题的探讨 [复制链接]

论坛徽章:
0
161 [报告]
发表于 2007-02-26 16:35 |只看该作者
对于非阻塞socket,recv如果读取到0字节,那么就意味着remote side主动关闭了连接,如果这个时候在server side执行close(fd),那么以后永远都不会触发epoll events,因此这个文件描述字将永远不会关闭了

ret = recv(cfd, buffer, sizeof(buffer),0);

因此在这句之后要判断一次,是否读到了0长度的内容

论坛徽章:
0
162 [报告]
发表于 2007-02-26 16:42 |只看该作者
设定个超时,定期检查不活动的连接,close掉,就ok了。

论坛徽章:
0
163 [报告]
发表于 2007-02-26 16:59 |只看该作者
在楼主给出的第二种架构里面就有对 recv 返回 0 长度的判断
            } else if (n == 0) {

                close(sockfd);

                events.data.fd = -1;

            }

所以第二种架构不会出问题

论坛徽章:
0
164 [报告]
发表于 2007-02-27 09:45 |只看该作者
我把返回值不大于0 的情况,都关闭了。
而且显式执行了 epoll_ctl(epfd, EPOLL_CTL_DEL, cfd, &ev);

尽管如此,问题还是有的。

所以必须设置一个超时监控线程来解决。

论坛徽章:
0
165 [报告]
发表于 2007-04-19 16:07 |只看该作者
你的文件描述符号是怎么耗尽的,有什么结论吗?

论坛徽章:
0
166 [报告]
发表于 2007-04-19 16:21 |只看该作者
原帖由 oknet 于 2007-2-26 16:35 发表
对于非阻塞socket,recv如果读取到0字节,那么就意味着remote side主动关闭了连接,如果这个时候在server side执行close(fd),那么以后永远都不会触发epoll events,因此这个文件描述字将永远不会关闭了

ret = ...

你的说法我怎么看不懂阿,server side 都已经关闭了,怎么又说这个文件描述自将永远不会关闭了,都已经关了还要关什么啊?

论坛徽章:
0
167 [报告]
发表于 2007-04-19 16:33 |只看该作者
我觉得LZ既然是做TCP的SERVER,而且有这样大的访问量,不应该不做TCPKEEPALIVE的操作,而且要把BACKLOG增加到500或者更大。。

感觉LZ的问题,就是因为很多用户在保持与LZ的SERVER连接的时候,直接关机器或者拔网络线,都会操作你这边出现一个死连接。
默认的情况下, LINUX或经过大概7200秒才会回收这个FD,这样肯定会影响你的服务的。

我贴段KEEPALIVE的代码, 希望对LZ有帮助:

# include <netinet/tcp.h>

int keepalive; // 打开TCP KEEPALIVE开关
int keepidle; // 系统等待多长时间开始检测
int keepintvl; // 系统每次探测时间
int keepcnt; // 系统探测几次后执行关闭操作。

setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char*)&keepalive, sizeof(keepalive));
isetsockopt(fd, SOL_TCP, TCP_KEEPIDLE, (char *)&keepidle, sizeof(keepidle));
setsockopt(fd, SOL_TCP, TCP_KEEPINTVL,(char *)&keepintvl, sizeof(keepintvl));
setsockopt(fd, SOL_TCP, TCP_KEEPCNT,(char *)&keepcnt, sizeof(keepcnt));

这个功能是协议栈实现的,应用层不用关心,但当发生检测失败后,他会叫你的epoll函数。

论坛徽章:
0
168 [报告]
发表于 2007-04-19 18:56 |只看该作者

回复 167楼 xhl 的帖子

谢谢你的建议。BACKLOG我一般都用8192。
最大fd一般用20w。
现在服务器很稳定,几个月都不会down掉,已经用做商业应用有半了。

论坛徽章:
1
天蝎座
日期:2013-08-25 10:27:22
169 [报告]
发表于 2008-04-14 18:35 |只看该作者
原帖由 wyezl 于 2006-8-25 16:33 发表


事情是这样的:
以前accept的时候把一个cfd加入了epoll。
后来wait返回。说这个cfd可读,我就去读,读了一次或两次,就返回了EAGAIN。
我难道新把以前的剔除要重 ADD一下?  
那已经读取的一部分数据怎 ...


  1. 我难道新把以前的剔除要重 ADD一下?  
  2. 那已经读取的一部分数据怎么处理呢?
  3. 找个buffer存着? 等待下一次wait返回再接着读?
复制代码

请问这个怎么处理的?

论坛徽章:
0
170 [报告]
发表于 2008-10-06 11:28 |只看该作者
在linsten之后把listen的fd加到epoll监控对象中epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev)
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP