原帖由 思一克 于 2006-8-18 15:58 发表
想帮你实验,但程序无法编译
原帖由 tysn 于 2006-8-20 11:25 发表
accept()之后的epoll_ctl(epfd, EPOLL_CTL_ADD, cfd, &ev);
要改成:if (epoll_ctl(epfd, EPOLL_CTL_ADD, cfd, &ev)<0) close(cfd);
估计就是这里错吧,这几率比较小,
所以出现“fd在经历一段时间 ...
原帖由 思一克 于 2006-8-21 09:49 发表
EPOLLIN事件后是不是应该关闭CFD?
我看的,不一定准确,因为无法实验你的程序
原帖由 思一克 于 2006-8-21 12:18 发表
那你把能编译的贴出,我帮你实验。如果你愿意的话
原帖由 safedead 于 2006-8-21 21:52 发表
我没有这么用过epoll
我的程序是仅用epoll弹出发生EPOLIN事件的LISTEN套接字
然后就ACCEPT出客户端连接就交给线程处理了
没有发生过fd耗尽的情况
原帖由 精简指令 于 2006-8-21 20:12 发表
“但fd却成增大趋势。以前那写较小的fd在经历一段时间后渐渐丢失,不再可用。”
是否已经将FD用光了? 如果没有用光,试着用到最大值,看看是否会重新分配较小的FD
原帖由 思一克 于 2006-8-22 08:19 发表
to LZ,
你的模型好象不太对,至少不太好。epoll_wait和ACCEPT的次序?
你在网络上找,有现成的好的。
原帖由 nuclearweapon 于 2006-8-22 11:43 发表
刚才测试了lz的程序。
50个并发,cfd最大达到37然后回落到5。
如上测试多次没有发现cfd有增大的趋势。
所以感觉和内核版本有关系。
测试环境:
kernel 2.6.15
gcc 4.0.3
distribution:ubuntu
原帖由 wyezl 于 2006-8-22 11:50 发表
50个并发,cfd最大达到37然后回落到5。 是有这样的现象。所以我说是增大趋势。而没有说直线增长。
这也不是你几分钟就能测试出来的。1024个fd也需要一个多小时才能耗尽(大约处理100万请求)。而且是量比较 ...
原帖由 星之孩子 于 2006-8-22 12:38 发表
你另外一个模型就是epoll例子的模型吧
凭什么说人家的就效率低了?
原帖由 nuclearweapon 于 2006-8-22 12:02 发表
就调试来说,当服务程序挂起的时候
你可以看如下目录:
/proc/your_process_id/fd
看一看有那些fd在被你的进程使用!
原帖由 思一克 于 2006-8-22 13:11 发表
to LZ,
你做什么服务? 有多少同时连接?
原帖由 playmud 于 2006-8-22 13:48 发表
5000 个?我怎么看你的listen才32?
if (listen(fd, 32) != 0)
{
fprintf(stderr, "listen failed\n");
return -1;
}
[code]SYNOPSIS
#include <s ...
原帖由 playmud 于 2006-8-22 13:48 发表
5000 个?我怎么看你的listen才32?
if (listen(fd, 32) != 0)
{
fprintf(stderr, "listen failed\n");
return -1;
}
[code]SYNOPSIS
#include <s ...
原帖由 思一克 于 2006-8-22 14:14 发表
一个fd有事件EPOLLIN后,如果断线,EPOLLOUT永不再来,你的fd不就永远不被关闭了吗?
原帖由 wyezl 于 2006-8-22 13:18 发表
我一共监视了5000个描述符,程序跑了一天,基本上快耗完了。还剩不到1000个了。
ls /proc/24152/fd/
Display all 4051 possibilities? (y or n)
可见这些耗尽的描述符都在使用中。 但不知道什么地方 ...
原帖由 思一克 于 2006-8-22 14:07 发表
你的程序我看了。好象是有漏洞,而且是必须在大量连接,慢速的断线才可疑的。
原帖由 nuclearweapon 于 2006-8-22 14:34 发表
用ls -l 看下是那些socket
再用 netstat -a看下这些socket的状态
原帖由 思一克 于 2006-8-22 14:41 发表
to wyezl,
FD泄露,原因就是没有close是无疑问的。
WHY MEIYOU close?
就是事件有的时候(比如网络坏等原因)没有到来。
原帖由 nuclearweapon 于 2006-8-22 14:33 发表
由于有SO_KEEPALIVE可以避免这种情况吧(lz的程序也做了处理)。
否则就是client有问题,一直连着不放。
原帖由 思一克 于 2006-8-22 14:55 发表
你可以设置一个timeout, 超过的cfd(在ACCPTE处)一律关闭
原帖由 wyezl 于 2006-8-22 14:51 发表
这是只监视1024个fds的时候的部分贴图。
# netstat -a
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State ...
原帖由 nuclearweapon 于 2006-8-22 15:01 发表
难道有人攻击你
SYN_RECV有多少个!
原帖由 nuclearweapon 于 2006-8-22 15:04 发表
你打开tcp_syncookies
试试。
再做测试
原帖由 思一克 于 2006-8-22 15:14 发表
wyezl,
攻击不会影响FD。FD是已经建立的连接没close.
原帖由 思一克 于 2006-8-22 15:14 发表
wyezl,
攻击不会影响FD。FD是已经建立的连接没close.
原帖由 思一克 于 2006-8-22 15:15 发表
这个帖子可以做为精华了。因为问题微妙又棘手,有普遍性,尤其对与EPOLL
原帖由 nuclearweapon 于 2006-8-22 15:25 发表
我记得和斑竹有一些出入。
因为:
只要有socket就会有一个inode,也就会有一个fd。而不是连接以后才会有fd的。
对于linux2。6来说
每当在内核创建完struct socket后,就会调用sock_map_fd()在调用进程创建 ...
原帖由 思一克 于 2006-8-22 15:30 发表
TO nuclearweapon,
你说的对。但他的问题是accept之后的fd被耗尽了,那就是有连接的socket.
如果那些DDOS攻击,往往是半连接(部分IP包),accept不了。
原帖由 思一克 于 2006-8-22 15:42 发表
To nuclearweapon,
也有可能是攻击引起的。让他继续实验。
半连接accept能成功返回fd吗?我不是十分肯定。
原帖由 nuclearweapon 于 2006-8-22 15:45 发表
对于半连接来说accpet是不能返回了,但是在内核中fd已经建立起来了,也就消耗了一个进程的可用fd数量。
原帖由 nuclearweapon 于 2006-8-22 15:45 发表
对于半连接来说accpet是不能返回了,但是在内核中fd已经建立起来了,也就消耗了一个进程的可用fd数量。
原帖由 思一克 于 2006-8-22 16:26 发表
to LZ,
我试图在我一个SERVER上跑80(有IP),遗憾的是无法编译,因为EPOLL支持问题
原帖由 思一克 于 2006-8-22 16:00 发表
TO nuclearweapon,
我刚才看了KERNEL代码,看到fd消耗只有3个函数socket() , accept(), socketpair(), 而且都是成功后才消耗fd. 网络程序其它任何地方没有看到用fd的?
半连接能消耗fd吗,我不是很清楚。如 ...
原帖由 思一克 于 2006-8-22 14:07 发表
你的程序我看了。好象是有漏洞,而且是必须在大量连接,慢速的断线才可疑的。
一个fd有事件EPOLLIN后,如果断线,EPOLLOUT永不再来,你的fd不就永远不被关闭了吗?
请讨论。
原帖由 tysn 于 2006-8-22 16:55 发表
可不可以不用分成
if(events[ i].events & EPOLLIN)
和
else if(events[ i].events & EPOLLOUT)
两种情况?
只要有事件来就进行读写,
当然要对读写cfd的函数进行出错判断,一旦出错就close(cfd) ...
原帖由 wyezl 于 2006-8-22 14:32 发表
这个32与5000个同时在线并不矛盾。
又不是说1秒内把这5000个连线全接受进来。
5000是我的epoll所监视的最大描述符个数。
原帖由 playmud 于 2006-8-22 17:35 发表
怎么不矛盾了?
你是if ((fd = socket(AF_INET, SOCK_STREAM, 0)) <= 0)
你把listen设成5000看看。
原帖由 wyezl 于 2006-8-22 17:43 发表
5000以内的描述符我都能 接受到。
设那个没什么影响。 估计listen也不能支持那么大的。
原帖由 playmud 于 2006-8-22 17:49 发表
tcp正常的断开需要3次或者4次握手确认,如果没有这个确认他就会保持一定的时间。
/proc/sys/net/ipv4/tcp_keepalive_time
原帖由 playmud 于 2006-8-22 17:52 发表
实在找不到原因,你可以把那个默认超时时间设成10几秒或者几十秒。
系统帮你释放掉占用的资源。
原帖由 wyezl 于 2006-8-22 17:06 发表
通过观察知道
lrwx------ 1 root root 64 Aug 22 16:25 480 -> socket:[34370805]
480这个描述符是死掉。不能回收了。我怎么看它的状态?
# ls -l /proc/28477/fd/
total 20
lrwx------ 1 root ...
原帖由 nuclearweapon 于 2006-8-22 22:36 发表
34370805是inode号
cat /proc/net/tcp|grep 34370805
第2、3项为socket的adress:port
还可以:
netstat -a | grep _pid_
如果照你说只有一个的话就很好分析出是拿一个是那个死掉的。看看他的状 ...
原帖由 wyezl 于 2006-8-23 09:48 发表
死掉的fd。
lrwx------ 1 root root 64 Aug 23 09:37 7 -> socket:[35074112]
#cat /proc/net/tcp|grep 35074112
17392: 4D256CCA:0050 4ACF18DA:0843 01 00000000:00000000 00:00000000 00000000 ...
欢迎光临 Chinaunix (http://bbs.chinaunix.net/) | Powered by Discuz! X3.2 |