每次接受新连接的时候,我监视了这几个事件。
EPOLLIN | EPOLLET | EPOLLERR | EPOLLHUP | EPOLLPRI;
每次有一批事件返回,经过统计
返回的一批fd数量=出错关闭的fd数量+由EPOLLIN转为EPOLLOUT的fd数量+EPOLLOUT正常处理关闭的fd的数量。 也就是说,每批事件都完全处理,没有遗漏。
观察发现EPOLLET | EPOLLERR | EPOLLHUP 这3发事件的发生率为0。
但fd却成增大趋势。以前那写较小的fd在经历一段时间后渐渐丢失,不再可用。
请问fd都丢失到哪里去了?
[ 本帖最后由 wyezl 于 2006-8-25 10:17 编辑 ]
思一克 回复于:2006-08-18 10:46:50
有程序?
wyezl 回复于:2006-08-18 11:10:12
/*-------------------------------------------------------------------------------------------------
gcc -o httpd httpd.c -lpthread
author: wyezl
2006.4.28
---------------------------------------------------------------------------------------------------*/
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#define PORT 8888
#define MAXFDS 5000
#define EVENTSIZE 100
#define BUFFER "HTTP/1.1 200 OK\r\nContent-Length: 5\r\nConnection: close\r\nContent-Type: text/html\r\n\r\nHello"
int epfd;
void *serv_epoll(void *p);
void setnonblocking(int fd)
{
int opts;
opts=fcntl(fd, F_GETFL);
if (opts < 0)
{
fprintf(stderr, "fcntl failed\n");
return;
}
opts = opts | O_NONBLOCK;
if(fcntl(fd, F_SETFL, opts) < 0)
{
fprintf(stderr, "fcntl failed\n");
return;
}
return;
}
int main(int argc, char *argv[])
{
int fd, cfd,opt=1;
struct epoll_event ev;
struct sockaddr_in sin, cin;
socklen_t sin_len = sizeof(struct sockaddr_in);
pthread_t tid;
pthread_attr_t attr;
epfd = epoll_create(MAXFDS);
if ((fd = socket(AF_INET, SOCK_STREAM, 0)) <= 0)
{
fprintf(stderr, "socket failed\n");
return -1;
}
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void*)&opt, sizeof(opt));
memset(&sin, 0, sizeof(struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_port = htons((short)(PORT));
sin.sin_addr.s_addr = INADDR_ANY;
if (bind(fd, (struct sockaddr *)&sin, sizeof(sin)) != 0)
{
fprintf(stderr, "bind failed\n");
return -1;
}
if (listen(fd, 32) != 0)
{
fprintf(stderr, "listen failed\n");
return -1;
}
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
if (pthread_create(&tid, &attr, serv_epoll, NULL) != 0)
{
fprintf(stderr, "pthread_create failed\n");
return -1;
}
while ((cfd = accept(fd, (struct sockaddr *)&cin, &sin_len)) > 0)
{
setnonblocking(cfd);
ev.data.fd = cfd;
ev.events = EPOLLIN | EPOLLET | EPOLLERR | EPOLLHUP | EPOLLPRI;
epoll_ctl(epfd, EPOLL_CTL_ADD, cfd, &ev);
//printf("connect from %s\n",inet_ntoa(cin.sin_addr));
//printf("cfd=%d\n",cfd);
}
if (fd > 0)
close(fd);
return 0;
}
void *serv_epoll(void *p)
{
int i, ret, cfd, nfds;;
struct epoll_event ev,events[EVENTSIZE];
char buffer[512];
while (1)
{
nfds = epoll_wait(epfd, events, EVENTSIZE , -1);
//printf("nfds ........... %d\n",nfds);
for (i=0; i<nfds; i++)
{
if(events.events & EPOLLIN)
{
cfd = events.data.fd;
ret = recv(cfd, buffer, sizeof(buffer),0);
//printf("read ret..........= %d\n",ret);
ev.data.fd = cfd;
ev.events = EPOLLOUT | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_MOD, cfd, &ev);
}
else if(events.events & EPOLLOUT)
{
cfd = events.data.fd;
ret = send(cfd, BUFFER, strlen(BUFFER), 0);
//printf("send ret...........= %d\n", ret);
ev.data.fd = cfd;
epoll_ctl(epfd, EPOLL_CTL_DEL, cfd, &ev);
close(cfd);
}
else
{
cfd = events.data.fd;
ev.data.fd = cfd;
epoll_ctl(epfd, EPOLL_CTL_DEL, cfd, &ev);
close(cfd);
}
}
}
return NULL;
}
wyezl 回复于:2006-08-18 11:23:46
只要能帮我找出描述符从哪耗尽的就行。
:)
思一克 回复于:2006-08-18 11:50:07
是不是main()中的cfd没有关闭
wyezl 回复于:2006-08-18 12:25:12
main中只接受连接,加入监视,不做处理。
估计epoll_ctl 没判断出错,我下午再测试一下。
wyezl 回复于:2006-08-18 13:27:07
if(epoll_ctl(epfd, EPOLL_CTL_ADD, cfd, &ev)<0)
printf("............................................EPOLL_CTL_ADD error!\n");
if(epoll_ctl(epfd, EPOLL_CTL_MOD, cfd, &ev)<0)
printf(".......................................EPOLL_CTL_MOD error!\n");
修改了两句,但未发现这里的错误输出,估计也不是这的问题。
不知道到底从哪耗尽的,奇怪。
wyezl 回复于:2006-08-18 15:50:15
继续顶。。。。。。。。。。。。。。。。
思一克 回复于:2006-08-18 15:58:14
想帮你实验,但程序无法编译
playmud 回复于:2006-08-19 20:48:39
挑挑错吧,说的不对的话,请见谅!
1, while ((cfd = accept(fd, (struct sockaddr *)&cin, &sin_len)) > 0)
可够改成
while(1)
cfd = accept(fd, (struct sockaddr *)&cin, &sin_len;
if(cfd>0)
..
2,你是要让客户端发送一次就不再发送了吗?
if(events.events & EPOLLIN)
{
cfd = events.data.fd;
ret = recv(cfd, buffer, sizeof(buffer),0);
//printf("read ret..........= %d\n",ret);
ev.data.fd = cfd;
ev.events = EPOLLOUT | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_MOD, cfd, &ev);
}
3,将accept事件列入epoll监控的对象
4,对close最好做一个判断
tysn 回复于:2006-08-20 11:25:26
accept()之后的epoll_ctl(epfd, EPOLL_CTL_ADD, cfd, &ev);
要改成:if (epoll_ctl(epfd, EPOLL_CTL_ADD, cfd, &ev)<0) close(cfd);
估计就是这里错吧,这几率比较小,
所以出现“fd在经历一段时间后渐渐丢失”
另外还要考虑playmud挑的4点问题,
比如第一点,lz那样写的while好像跟if差不多,
accept也是在很小几率下出错,出错之后程序就退出?
说的不对的话,请指正!
wyezl 回复于:2006-08-20 12:58:20
引用:原帖由 思一克 于 2006-8-18 15:58 发表
想帮你实验,但程序无法编译
编译没问题,需要linux 2。6以上内核的支持。
wyezl 回复于:2006-08-20 13:10:17
引用:
挑挑错吧,说的不对的话,请见谅!
1, while ((cfd = accept(fd, (struct sockaddr *)&cin, &sin_len)) > 0)
可够改成
while(1)
cfd = accept(fd, (struct sockaddr *)&cin, &sin_len;
if(cfd>0)
..
2,你是要让客户端发送一次就不再发送了吗?
CODE:[Copy to clipboard] if(events.events & EPOLLIN)
{
cfd = events[ i ].data.fd;
ret = recv(cfd, buffer, sizeof(buffer),0);
//printf("read ret..........= %d\n",ret);
ev.data.fd = cfd;
ev.events = EPOLLOUT | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_MOD, cfd, &ev);
}
3,将accept事件列入epoll监控的对象
4,对close最好做一个判断
...
1,如果描述符已经耗尽,这样判断cfd永远不会成立。所以就让它退出算了。
2,我只取http请求的头信息的第一行。 get /xxx http/1.0 做简单分析,其他的都不要了。按照tcp协议的特点,本应该多次读取的,但测试发现,只读一次就能得到我想要的,基本上没出过错。
里面的数据没读完就留那了,会不会对以后的请求造成什么不好的影响?
3,accept是在住线程里跑,加入了epoll有什么好处吗?
4,对close没做判断,这点确实是遗漏了。我得补上。
谢谢你的建议。
[ 本帖最后由 wyezl 于 2006-8-20 13:16 编辑 ]
wyezl 回复于:2006-08-20 13:14:43
引用:原帖由 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在经历一段时间 ...
这一条判断我后来添加了。 但这儿出错几率几乎为0 。
现在仍未发现耗尽的原因。怀疑是不是epoll机制本身有问题呢?
wyezl 回复于:2006-08-21 09:41:20
继续顶。。。。。。。。。
思一克 回复于:2006-08-21 09:49:38
EPOLLIN事件后是不是应该关闭CFD?
我看的,不一定准确,因为无法实验你的程序
wyezl 回复于:2006-08-21 12:14:14
引用:原帖由 思一克 于 2006-8-21 09:49 发表
EPOLLIN事件后是不是应该关闭CFD?
我看的,不一定准确,因为无法实验你的程序
如果关闭了,以后就不会有EPOLLOUT了。 因为我是接受请求,然后返回所请求的信息。
思一克 回复于:2006-08-21 12:18:40
那你把能编译的贴出,我帮你实验。如果你愿意的话
billzhou 回复于:2006-08-21 12:34:25
不懂 什么是epoll,哪位兄弟给解释一下
wyezl 回复于:2006-08-21 16:47:23
引用:原帖由 思一克 于 2006-8-21 12:18 发表
那你把能编译的贴出,我帮你实验。如果你愿意的话
我贴出的代码就是能编译的。
请问你用的是什么操作系统? 版本?
这个程序只能在linux上运行,而且内核版本必须在2.6以上。
[ 本帖最后由 wyezl 于 2006-8-21 16:52 编辑 ]
wyezl 回复于:2006-08-21 16:49:00
思一克是个热心的斑竹,先赞一个。 :)
精简指令 回复于:2006-08-21 20:12:49
“但fd却成增大趋势。以前那写较小的fd在经历一段时间后渐渐丢失,不再可用。”
是否已经将FD用光了? 如果没有用光,试着用到最大值,看看是否会重新分配较小的FD
safedead 回复于:2006-08-21 21:52:01
我没有这么用过epoll
我的程序是仅用epoll弹出发生EPOLIN事件的LISTEN套接字
然后就ACCEPT出客户端连接就交给线程处理了
没有发生过fd耗尽的情况
思一克 回复于:2006-08-22 08:19:12
to LZ,
你的模型好象不太对,至少不太好。epoll_wait和ACCEPT的次序?
你在网络上找,有现成的好的。
wyezl 回复于:2006-08-22 09:54:56
引用:原帖由 safedead 于 2006-8-21 21:52 发表
我没有这么用过epoll
我的程序是仅用epoll弹出发生EPOLIN事件的LISTEN套接字
然后就ACCEPT出客户端连接就交给线程处理了
没有发生过fd耗尽的情况
方便把你的模型大概贴出来看一下吗?
wyezl 回复于:2006-08-22 09:55:54
引用:原帖由 精简指令 于 2006-8-21 20:12 发表
“但fd却成增大趋势。以前那写较小的fd在经历一段时间后渐渐丢失,不再可用。”
是否已经将FD用光了? 如果没有用光,试着用到最大值,看看是否会重新分配较小的FD
确实用光了。不能分配小的了。
星之孩子 回复于:2006-08-22 10:06:27
为何你用epoll还要用多线程
感觉你这个模型怪怪的
wyezl 回复于:2006-08-22 10:32:07
只开了两个线程。 epoll独占一个。
星之孩子 回复于:2006-08-22 10:34:49
多个线程这样用epoll不知道会不会有问题
其实你的应用根本不用多线程
wyezl 回复于:2006-08-22 11:05:13
引用:原帖由 思一克 于 2006-8-22 08:19 发表
to LZ,
你的模型好象不太对,至少不太好。epoll_wait和ACCEPT的次序?
你在网络上找,有现成的好的。
能把你觉得好的模型共享一下吗?
nuclearweapon 回复于:2006-08-22 11:43:27
刚才测试了lz的程序。
50个并发,cfd最大达到37然后回落到5。
如上测试多次没有发现cfd有增大的趋势。
所以感觉和内核版本有关系。
测试环境:
kernel 2.6.15
gcc 4.0.3
distribution:ubuntu
wyezl 回复于:2006-08-22 11:47:58
下面这个模型我也用过。不过效率很底。
#include <iostream>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#define MAXLINE 10
#define OPEN_MAX 100
#define LISTENQ 20
#define SERV_PORT 5555
#define INFTIM 1000
void setnonblocking(int sock)
{
int opts;
opts=fcntl(sock,F_GETFL);
if(opts<0)
{
perror("fcntl(sock,GETFL)");
exit(1);
}
opts = opts|O_NONBLOCK;
if(fcntl(sock,F_SETFL,opts)<0)
{
perror("fcntl(sock,SETFL,opts)");
exit(1);
}
}
int main()
{
int i, maxi, listenfd, connfd, sockfd,epfd,nfds;
ssize_t n;
char line[MAXLINE];
socklen_t clilen;
//声明epoll_event结构体的变量,ev用于注册事件,数组用于回传要处理的事件
struct epoll_event ev,events[20];
//生成用于处理accept的epoll专用的文件描述符
epfd=epoll_create(256);
struct sockaddr_in clientaddr;
struct sockaddr_in serveraddr;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
//把socket设置为非阻塞方式
setnonblocking(listenfd);
//设置与要处理的事件相关的文件描述符
ev.data.fd=listenfd;
//设置要处理的事件类型
ev.events=EPOLLIN|EPOLLET;
//注册epoll事件
epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev);
bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
char *local_addr="200.200.200.204";
inet_aton(local_addr,&(serveraddr.sin_addr));//htons(SERV_PORT);
serveraddr.sin_port=htons(SERV_PORT);
bind(listenfd,(sockaddr *)&serveraddr, sizeof(serveraddr));
listen(listenfd, LISTENQ);
maxi = 0;
for ( ; ; ) {
//等待epoll事件的发生
nfds=epoll_wait(epfd,events,20,500);
//处理所发生的所有事件
for(i=0;i<nfds;++i)
{
if(events.data.fd==listenfd)
{
connfd = accept(listenfd,(sockaddr *)&clientaddr, &clilen);
if(connfd<0){
perror("connfd<0");
exit(1);
}
setnonblocking(connfd);
char *str = inet_ntoa(clientaddr.sin_addr);
std::cout<<"connect from "<_u115 ?tr<<std::endl;
//设置用于读操作的文件描述符
ev.data.fd=connfd;
//设置用于注测的读操作事件
ev.events=EPOLLIN|EPOLLET;
//注册ev
epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev);
}
else if(events.events&EPOLLIN)
{
if ( (sockfd = events.data.fd) < 0) continue;
if ( (n = read(sockfd, line, MAXLINE)) < 0) {
if (errno == ECONNRESET) {
close(sockfd);
events.data.fd = -1;
} else
std::cout<<"readline error"<<std::endl;
} else if (n == 0) {
close(sockfd);
events.data.fd = -1;
}
//设置用于写操作的文件描述符
ev.data.fd=sockfd;
//设置用于注测的写操作事件
ev.events=EPOLLOUT|EPOLLET;
//修改sockfd上要处理的事件为EPOLLOUT
epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);
}
else if(events.events&EPOLLOUT)
{
sockfd = events.data.fd;
write(sockfd, line, n);
//设置用于读操作的文件描述符
ev.data.fd=sockfd;
//设置用于注测的读操作事件
ev.events=EPOLLIN|EPOLLET;
//修改sockfd上要处理的事件为EPOLIN
epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);
}
}
}
}
wyezl 回复于:2006-08-22 11:50:49
引用:原帖由 nuclearweapon 于 2006-8-22 11:43 发表
刚才测试了lz的程序。
50个并发,cfd最大达到37然后回落到5。
如上测试多次没有发现cfd有增大的趋势。
所以感觉和内核版本有关系。
测试环境:
kernel 2.6.15
gcc 4.0.3
distribution:ubuntu
50个并发,cfd最大达到37然后回落到5。 是有这样的现象。所以我说是增大趋势。而没有说直线增长。
这也不是你几分钟就能测试出来的。1024个fd也需要一个多小时才能耗尽(大约处理100万请求)。而且是量比较大的线上测试。
nuclearweapon 回复于:2006-08-22 11:57:36
引用:原帖由 wyezl 于 2006-8-22 11:50 发表
50个并发,cfd最大达到37然后回落到5。 是有这样的现象。所以我说是增大趋势。而没有说直线增长。
这也不是你几分钟就能测试出来的。1024个fd也需要一个多小时才能耗尽(大约处理100万请求)。而且是量比较 ...
你这里说的耗尽是什么意思?
表示Accept不能再接受client了吗?
nuclearweapon 回复于:2006-08-22 12:02:51
就调试来说,当服务程序挂起的时候
你可以看如下目录:
/proc/your_process_id/fd
看一看有那些fd在被你的进程使用!
星之孩子 回复于:2006-08-22 12:38:41
你另外一个模型就是epoll例子的模型吧
凭什么说人家的就效率低了?
wyezl 回复于:2006-08-22 13:10:18
引用:原帖由 星之孩子 于 2006-8-22 12:38 发表
你另外一个模型就是epoll例子的模型吧
凭什么说人家的就效率低了?
我测试过。处理能力底了20%。
思一克 回复于:2006-08-22 13:11:53
to LZ,
你做什么服务? 有多少同时连接?
wyezl 回复于:2006-08-22 13:18:46
引用:原帖由 nuclearweapon 于 2006-8-22 12:02 发表
就调试来说,当服务程序挂起的时候
你可以看如下目录:
/proc/your_process_id/fd
看一看有那些fd在被你的进程使用!
我一共监视了5000个描述符,程序跑了一天,基本上快耗完了。还剩不到1000个了。
ls /proc/24152/fd/
Display all 4051 possibilities? (y or n)
可见这些耗尽的描述符都在使用中。 但不知道什么地方没把它们释放。
wyezl 回复于:2006-08-22 13:22:36
引用:原帖由 思一克 于 2006-8-22 13:11 发表
to LZ,
你做什么服务? 有多少同时连接?
http服务。简单的数据。基本上是读取内存的操作。类似股票行情数据。
当然每秒能处理越多请求越好。
playmud 回复于:2006-08-22 13:48:27
5000 个?我怎么看你的listen才32?
if (listen(fd, 32) != 0)
{
fprintf(stderr, "listen failed\n");
return -1;
}
SYNOPSIS
#include <sys/socket.h>
int listen(int sockfd, int backlog);
DESCRIPTION
To accept connections, a socket is first created with socket(2), a willingness to accept incoming connec-
tions and a queue limit for incoming connections are specified with listen(), and then the connections are
accepted with accept(2). The listen() call applies only to sockets of type SOCK_STREAM or SOCK_SEQPACKET.
The backlog parameter defines the maximum length the queue of pending connections may grow to. If a con-
nection request arrives with the queue full the client may receive an error with an indication of ECONNRE-
FUSED or, if the underlying protocol supports retransmission, the request may be ignored so that retries
succeed.
思一克 回复于:2006-08-22 14:07:38
你的程序我看了。好象是有漏洞,而且是必须在大量连接,慢速的断线才可疑的。
一个fd有事件EPOLLIN后,如果断线,EPOLLOUT永不再来,你的fd不就永远不被关闭了吗?
请讨论。
slay78 回复于:2006-08-22 14:13:42
引用:原帖由 playmud 于 2006-8-22 13:48 发表
5000 个?我怎么看你的listen才32?
if (listen(fd, 32) != 0)
{
fprintf(stderr, "listen failed\n");
return -1;
}
SYNOPSIS
#include <s ...
人家这个32不是表示可以连32个的意思,这个32表示最多有32个同时在连并且都没连上,第33个进不来而已
思一克 回复于:2006-08-22 14:14:15
虽然有HUP等else 控制。但如果EPOLLIN之后由于网络的不好状况,其它时间不在来?如何
wyezl 回复于:2006-08-22 14:32:13
引用:原帖由 playmud 于 2006-8-22 13:48 发表
5000 个?我怎么看你的listen才32?
if (listen(fd, 32) != 0)
{
fprintf(stderr, "listen failed\n");
return -1;
}
SYNOPSIS
#include <s ...
这个32与5000个同时在线并不矛盾。
又不是说1秒内把这5000个连线全接受进来。
5000是我的epoll所监视的最大描述符个数。
nuclearweapon 回复于:2006-08-22 14:33:08
引用:原帖由 思一克 于 2006-8-22 14:14 发表
一个fd有事件EPOLLIN后,如果断线,EPOLLOUT永不再来,你的fd不就永远不被关闭了吗?
由于有SO_KEEPALIVE可以避免这种情况吧(lz的程序也做了处理)。
否则就是client有问题,一直连着不放。
nuclearweapon 回复于:2006-08-22 14:34:54
引用:原帖由 wyezl 于 2006-8-22 13:18 发表
我一共监视了5000个描述符,程序跑了一天,基本上快耗完了。还剩不到1000个了。
ls /proc/24152/fd/
Display all 4051 possibilities? (y or n)
可见这些耗尽的描述符都在使用中。 但不知道什么地方 ...
用ls -l 看下是那些socket
再用 netstat -a看下这些socket的状态
wyezl 回复于:2006-08-22 14:38:09
引用:原帖由 思一克 于 2006-8-22 14:07 发表
你的程序我看了。好象是有漏洞,而且是必须在大量连接,慢速的断线才可疑的。
就是漫漫耗尽的。
第二种模型也一样。出现这样耗尽的情况。 以前都是用测试工具测试的,基本上看不出破绽。
在线上测试,就很明显了。。
思一克 回复于:2006-08-22 14:41:07
to wyezl,
FD泄露,原因就是没有close是无疑问的。
WHY MEIYOU close?
就是事件有的时候(比如网络坏等原因)没有到来。
wyezl 回复于:2006-08-22 14:51:33
引用:原帖由 nuclearweapon 于 2006-8-22 14:34 发表
用ls -l 看下是那些socket
再用 netstat -a看下这些socket的状态
这是只监视1024个fds的时候的部分贴图。
# netstat -a
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 *:32768 *:* LISTEN
tcp 0 0 *:sunrpc *:* LISTEN
tcp 0 0 *:http *:* LISTEN
tcp 0 0 xxx.108.37.77:http 122.48.0.37:56652 SYN_RECV
tcp 0 0 xxx.108.37.77:http 211.147.253.74:55689 SYN_RECV
tcp 0 0 xxx.108.37.77:http 219.135.251.110:2669 SYN_RECV
warning, got duplicate tcp line.
tcp 0 0 xxx.108.37.77:http 122.48.0.89:12881 SYN_RECV
tcp 0 0 xxx.108.37.77:http 58.246.194.192:4254 SYN_RECV
tcp 0 0 xxx.108.37.77:http 122.48.0.89:12923 SYN_RECV
tcp 0 0 xxx.108.37.77:http 218.22.98.170:56851 SYN_RECV
tcp 0 0 xxx.108.37.77:http 122.48.0.89:12888 SYN_RECV
tcp 0 0 xxx.108.37.77:http 60.190.192.46:4072 SYN_RECV
tcp 0 0 xxx.108.37.77:http 61.177.227.182:27180 SYN_RECV
tcp 0 0 xxx.108.37.77:http 60.0.218.7:41237 SYN_RECV
tcp 0 0 xxx.108.37.77:http 221.232.42.194:3713 SYN_RECV
tcp 0 0 xxx.108.37.77:http 218.81.111.25:4495 SYN_RECV
tcp 0 0 xxx.108.37.77:http 122.48.0.35:59812 SYN_RECV
tcp 0 0 xxx.108.37.77:http 58.60.5.33:7660 SYN_RECV
tcp 0 0 xxx.108.37.77:http 222.137.4.7:4296 SYN_RECV
ls -l /proc/27952/fd/
rwx------ 1 root root 64 Aug 22 14:44 837 -> socket:[31398309]
lrwx------ 1 root root 64 Aug 22 14:44 838 -> socket:[31397749]
lrwx------ 1 root root 64 Aug 22 14:44 839 -> socket:[31394222]
lrwx------ 1 root root 64 Aug 22 14:38 84 -> socket:[30926430]
lrwx------ 1 root root 64 Aug 22 14:44 840 -> socket:[31398135]
lrwx------ 1 root root 64 Aug 22 14:44 841 -> socket:[31398930]
lrwx------ 1 root root 64 Aug 22 14:44 842 -> socket:[31397984]
lrwx------ 1 root root 64 Aug 22 14:44 843 -> socket:[31390139]
lrwx------ 1 root root 64 Aug 22 14:44 844 -> socket:[31398331]
lrwx------ 1 root root 64 Aug 22 14:44 845 -> socket:[31397572]
lrwx------ 1 root root 64 Aug 22 14:44 846 -> socket:[31397546]
lrwx------ 1 root root 64 Aug 22 14:44 847 -> socket:[31396094]
lrwx------ 1 root root 64 Aug 22 14:44 848 -> socket:[31393666]
lrwx------ 1 root root 64 Aug 22 14:44 849 -> socket:[31398932]
lrwx------ 1 root root 64 Aug 22 14:38 85 -> socket:[30884712]
lrwx------ 1 root root 64 Aug 22 14:44 852 -> socket:[31397555]
lrwx------ 1 root root 64 Aug 22 14:44 856 -> socket:[31390278]
lrwx------ 1 root root 64 Aug 22 14:44 858 -> socket:[31392652]
lrwx------ 1 root root 64 Aug 22 14:44 859 -> socket:[31392710]
lrwx------ 1 root root 64 Aug 22 14:38 86 -> socket:[30883810]
lrwx------ 1 root root 64 Aug 22 14:38 87 -> socket:[30913192]
lrwx------ 1 root root 64 Aug 22 14:38 88 -> socket:[30943036]
lrwx------ 1 root root 64 Aug 22 14:38 89 -> socket:[31133080]
lrwx------ 1 root root 64 Aug 22 14:38 9 -> socket:[30951877]
lrwx------ 1 root root 64 Aug 22 14:38 90 -> socket:[30999630]
lrwx------ 1 root root 64 Aug 22 14:38 91 -> socket:[31134432]
lrwx------ 1 root root 64 Aug 22 14:38 92 -> socket:[30928870]
lrwx------ 1 root root 64 Aug 22 14:38 93 -> socket:[30975324]
lrwx------ 1 root root 64 Aug 22 14:38 94 -> socket:[30936083]
wyezl 回复于:2006-08-22 14:52:50
引用:原帖由 思一克 于 2006-8-22 14:41 发表
to wyezl,
FD泄露,原因就是没有close是无疑问的。
WHY MEIYOU close?
就是事件有的时候(比如网络坏等原因)没有到来。
这种情况怎么处理才好呢?
思一克 回复于:2006-08-22 14:55:05
你可以设置一个timeout, 超过的cfd(在ACCPTE处)一律关闭
wyezl 回复于:2006-08-22 14:56:56
引用:原帖由 nuclearweapon 于 2006-8-22 14:33 发表
由于有SO_KEEPALIVE可以避免这种情况吧(lz的程序也做了处理)。
否则就是client有问题,一直连着不放。
我没有支持KEEPALIVE。发送完处理,立刻就关闭描述符了。
wyezl 回复于:2006-08-22 15:01:52
引用:原帖由 思一克 于 2006-8-22 14:55 发表
你可以设置一个timeout, 超过的cfd(在ACCPTE处)一律关闭
怎么为每个描述符设置超时?
nuclearweapon 回复于:2006-08-22 15:01:58
引用:原帖由 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 ...
难道有人攻击你:-(
SYN_RECV有多少个!
nuclearweapon 回复于:2006-08-22 15:04:54
你打开tcp_syncookies
试试。
再做测试
思一克 回复于:2006-08-22 15:07:31
可能不是好方法:
while( ......... accept() ....) {
....这里检查全局的time_t fd_create[5000];
}
关闭时设置fd_create[fd] = 0;
wyezl 回复于:2006-08-22 15:11:15
引用:原帖由 nuclearweapon 于 2006-8-22 15:01 发表
难道有人攻击你:-(
SYN_RECV有多少个!
几百个吧。贴出来。省略一部分后面的。
# netstat -a
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 *:32768 *:* LISTEN
tcp 0 0 *:sunrpc *:* LISTEN
tcp 0 0 *:http *:* LISTEN
tcp 0 0 xxx.108.37.77:http 58.217.195.47:4689 SYN_RECV
tcp 0 0 xxx.108.37.77:http 58.47.42.74:2899 SYN_RECV
tcp 0 0 xxx.108.37.77:http 218.68.242.127:1238 SYN_RECV
tcp 0 0 xxx.108.37.77:http 222.67.10.49:30384 SYN_RECV
tcp 0 0 xxx.108.37.77:http pc68.broad.dynamic.xm.:2215 SYN_RECV
tcp 0 0 xxx.108.37.77:http 220.191.231.198:47700 SYN_RECV
tcp 0 0 xxx.108.37.77:http 218.77.186.194:63425 SYN_RECV
tcp 0 0 xxx.108.37.77:http 220.207.230.113:3652 SYN_RECV
tcp 0 0 xxx.108.37.77:http 60.7.59.197:3216 SYN_RECV
tcp 0 0 xxx.108.37.77:http 123.49.160.226:3127 SYN_RECV
warning, got duplicate tcp line.
tcp 0 0 xxx.108.37.77:http 122.48.0.89:13698 SYN_RECV
tcp 0 0 xxx.108.37.77:http 58.67.158.106:krb524 SYN_RECV
tcp 0 0 xxx.108.37.77:http 218.79.187.16:3129 SYN_RECV
tcp 0 0 xxx.108.37.77:http 122.48.0.89:13680 SYN_RECV
tcp 0 0 xxx.108.37.77:http 60.171.192.39:2531 SYN_RECV
tcp 0 0 xxx.108.37.77:http 60.216.170.48:xxx5 SYN_RECV
warning, got duplicate tcp line.
tcp 0 0 xxx.108.37.77:http 218.22.68.194:1101 SYN_RECV
tcp 0 0 xxx.108.37.77:http 219.137.172.101:15053 SYN_RECV
tcp 0 0 xxx.108.37.77:http 61.141.94.21:4748 SYN_RECV
tcp 0 0 xxx.108.37.77:http 58.24.101.69:4188 SYN_RECV
tcp 0 0 xxx.108.37.77:http 222.82.225.134:3118 SYN_RECV
tcp 0 0 xxx.108.37.77:http 59.52.119.145:55806 SYN_RECV
tcp 0 0 xxx.108.37.77:http 124.248.1.69:50344 SYN_RECV
tcp 0 0 xxx.108.37.77:http 220.171.79.196:3014 SYN_RECV
tcp 0 0 xxx.108.37.77:http 123.49.164.148:55258 SYN_RECV
tcp 0 0 xxx.108.37.77:http 212.193.163.60.broad.:63429 SYN_RECV
tcp 0 0 xxx.108.37.77:http 122.48.0.89:13754 SYN_RECV
tcp 0 0 xxx.108.37.77:http 61.188.210.2:3532 SYN_RECV
tcp 0 0 xxx.108.37.77:http 122.48.0.89:13752 SYN_RECV
[root@sina src]# netstat -an | more
warning, got duplicate tcp line.
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:32768 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
tcp 0 0 xxx.108.37.77:80 xxx.103.215.242:62165 SYN_RECV
tcp 0 0 xxx.108.37.77:80 220.191.231.198:47700 SYN_RECV
tcp 0 0 xxx.108.37.77:80 218.246.73.21:60164 SYN_RECV
tcp 0 0 xxx.108.37.77:80 222.64.136.219:2881 SYN_RECV
tcp 0 0 xxx.108.37.77:80 123.49.160.226:3127 SYN_RECV
tcp 0 0 xxx.108.37.77:80 60.63.11.185:22834 SYN_RECV
tcp 0 0 xxx.108.37.77:80 58.51.39.146:1870 SYN_RECV
tcp 0 0 xxx.108.37.77:80 122.48.0.89:13698 SYN_RECV
tcp 0 0 xxx.108.37.77:80 211.147.240.74:3076 SYN_RECV
tcp 0 0 xxx.108.37.77:80 59.54.226.64:1135 SYN_RECV
tcp 0 0 xxx.108.37.77:80 218.28.166.198:61757 SYN_RECV
tcp 0 0 xxx.108.37.77:80 222.82.225.134:3118 SYN_RECV
tcp 0 0 xxx.108.37.77:80 58.35.242.69:23660 SYN_RECV
tcp 0 0 xxx.108.37.77:80 211.92.156.131:1210 SYN_RECV
tcp 0 0 xxx.108.37.77:80 221.5.82.81:2100 SYN_RECV
tcp 0 0 xxx.108.37.77:80 220.171.79.196:3014 SYN_RECV
tcp 0 0 xxx.108.37.77:80 60.163.193.212:63429 SYN_RECV
tcp 0 0 xxx.108.37.77:80 122.48.0.89:13754 SYN_RECV
tcp 0 0 xxx.108.37.77:80 61.188.210.2:3532 SYN_RECV
tcp 0 0 xxx.108.37.77:80 218.82.23.151:64811 SYN_RECV
tcp 0 0 xxx.108.37.77:80 122.48.0.89:13752 SYN_RECV
tcp 0 0 xxx.108.37.77:80 218.18.33.108:4641 SYN_RECV
tcp 0 0 xxx.108.37.77:80 211.95.165.175:61439 SYN_RECV
tcp 0 0 xxx.108.37.77:80 218.28.188.86:52324 SYN_RECV
tcp 0 0 xxx.108.37.77:80 211.92.156.131:1215 SYN_RECV
tcp 0 0 xxx.108.37.77:80 211.92.156.131:1206 SYN_RECV
tcp 0 0 xxx.108.37.77:80 218.71.200.192:1503 SYN_RECV
tcp 0 0 xxx.108.37.77:80 221.200.137.120:1619 SYN_RECV
tcp 0 0 xxx.108.37.77:80 218.59.106.182:53008 SYN_RECV
tcp 0 0 xxx.108.37.77:80 211.69.18.125:3158 SYN_RECV
tcp 0 0 xxx.108.37.77:80 218.81.193.198:1434 SYN_RECV
tcp 0 0 xxx.108.37.77:80 61.144.254.129:50050 SYN_RECV
tcp 0 0 xxx.108.37.77:80 211.92.156.131:1216 SYN_RECV
tcp 0 0 xxx.108.37.77:80 218.28.58.69:9898 SYN_RECV
tcp 0 0 xxx.108.37.77:80 220.234.241.178:1679 SYN_RECV
tcp 0 0 xxx.108.37.77:80 219.242.196.109:2261 SYN_RECV
tcp 0 0 xxx.108.37.77:80 124.21.243.228:1648 SYN_RECV
tcp 0 0 xxx.108.37.77:80 221.200.137.120:1620 SYN_RECV
tcp 0 0 xxx.108.37.77:80 222.35.126.211:1336 SYN_RECV
tcp 0 0 xxx.108.37.77:80 221.234.146.160:2188 SYN_RECV
tcp 0 0 xxx.108.37.77:80 222.169.187.100:3529 SYN_RECV
tcp 0 0 xxx.108.37.77:80 122.48.0.89:13748 SYN_RECV
--More--warning, got duplicate tcp line.
warning, got duplicate tcp line.
warning, got duplicate tcp line.
tcp 0 0 xxx.108.37.77:80 218.246.73.21:60165 SYN_RECV
tcp 0 0 xxx.108.37.77:80 221.196.131.130:4444 SYN_RECV
tcp 0 0 xxx.108.37.77:80 220.174.8.13:12043 SYN_RECV
tcp 0 0 xxx.108.37.77:80 211.95.165.175:61440 SYN_RECV
tcp 0 0 xxx.108.37.77:80 220.205.30.17:1519 SYN_RECV
tcp 0 0 xxx.108.37.77:80 61.188.210.2:3531 SYN_RECV
tcp 0 0 xxx.108.37.77:80 60.163.193.212:63427 SYN_RECV
tcp 0 0 xxx.108.37.77:80 218.94.127.135:30598 SYN_RECV
tcp 0 0 xxx.108.37.77:80 219.155.143.97:1120 SYN_RECV
tcp 0 0 xxx.108.37.77:80 221.7.131.131:4331 SYN_RECV
tcp 0 0 xxx.108.37.77:80 211.147.240.74:3077 SYN_RECV
tcp 0 0 xxx.108.37.77:80 210.76.66.35:1524 SYN_RECV
tcp 0 0 xxx.108.37.77:80 61.138.254.47:29233 SYN_RECV
tcp 0 0 xxx.108.37.77:80 59.35.87.21:11079 SYN_RECV
tcp 0 0 xxx.108.37.77:80 219.242.196.109:2260 SYN_RECV
tcp 0 0 xxx.108.37.77:80 220.205.30.17:1518 SYN_RECV
tcp 0 0 xxx.108.37.77:80 58.62.84.52:4315 SYN_RECV
tcp 0 0 xxx.108.37.77:80 221.216.74.228:4444 SYN_RECV
tcp 0 0 xxx.108.37.77:80 222.169.187.100:3528 SYN_RECV
tcp 0 0 xxx.108.37.77:80 211.92.156.131:1207 SYN_RECV
tcp 0 0 xxx.108.37.77:80 222.209.217.21:38807 SYN_RECV
tcp 0 0 xxx.108.37.77:80 219.238.191.17:17679 SYN_RECV
tcp 0 0 xxx.108.37.77:80 61.172.137.186:4075 SYN_RECV
tcp 0 0 xxx.108.37.77:80 211.92.156.131:1212 SYN_RECV
tcp 0 0 xxx.108.37.77:80 221.214.13.109:17600 SYN_RECV
tcp 0 0 xxx.108.37.77:80 218.23.149.98:46060 SYN_RECV
tcp 0 0 xxx.108.37.77:80 221.222.116.178:1658 SYN_RECV
tcp 0 0 xxx.108.37.77:80 xxx.103.215.242:62164 SYN_RECV
tcp 0 0 xxx.108.37.77:80 222.173.191.91:1143 SYN_RECV
tcp 0 0 xxx.108.37.77:80 61.242.112.118:59158 SYN_RECV
tcp 0 0 xxx.108.37.77:80 222.209.217.21:38551 SYN_RECV
tcp 0 0 xxx.108.37.77:80 219.129.164.182:62607 SYN_RECV
tcp 0 0 xxx.108.37.77:80 58.60.67.4:48095 SYN_RECV
tcp 0 0 xxx.108.37.77:80 211.92.156.131:1213 SYN_RECV
tcp 0 0 xxx.108.37.77:80 122.48.0.89:13694 SYN_RECV
tcp 0 0 xxx.108.37.77:80 218.87.71.62:2363 SYN_RECV
tcp 0 0 xxx.108.37.77:80 61.173.14.106:4444 SYN_RECV
tcp 0 0 xxx.108.37.77:80 220.234.241.178:1678 SYN_RECV
tcp 0 0 xxx.108.37.77:80 210.21.209.145:5554 SYN_RECV
tcp 0 0 xxx.108.37.77:80 122.48.0.89:13750 SYN_RECV
tcp 0 0 xxx.108.37.77:80 59.35.87.21:11080 SYN_RECV
tcp 0 0 xxx.108.37.77:80 61.172.137.186:4076 SYN_RECV
tcp 0 0 xxx.108.37.77:80 222.67.94.46:1434 SYN_RECV
tcp 0 0 xxx.108.37.77:80 122.48.0.89:13697 SYN_RECV
tcp 0 0 xxx.108.37.77:80 61.242.112.118:59160 SYN_RECV
tcp 0 0 xxx.108.37.77:80 58.35.242.69:23659 SYN_RECV
--More--warning, got duplicate tcp line.
warning, got duplicate tcp line.
tcp 0 0 xxx.108.37.77:80 61.181.71.50:3946 SYN_RECV
tcp 0 0 xxx.108.37.77:80 211.92.156.131:1209 SYN_RECV
tcp 0 0 xxx.108.37.77:80 60.63.11.185:22833 SYN_RECV
tcp 0 0 xxx.108.37.77:80 122.48.0.89:13744 SYN_RECV
tcp 0 0 xxx.108.37.77:80 222.137.152.197:4755 SYN_RECV
tcp 0 0 xxx.108.37.77:80 220.169.5.239:3676 SYN_RECV
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN
tcp 0 0 xxx.108.37.77:80 221.6.163.131:35293 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 221.198.127.25:1956 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 60.2.106.52:58968 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 221.222.144.24:1618 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 211.158.132.14:1808 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 218.89.188.200:60118 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 221.0.180.142:58305 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 61.51.223.223:1992 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 61.170.213.11:14704 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 219.136.26.220:3765 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 211.158.81.195:4087 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 218.71.200.192:1460 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 221.5.152.50:37803 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 210.21.232.236:33515 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 221.198.127.25:1957 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 221.15.17.77:1878 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 221.1.244.62:1230 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 61.155.209.139:2875 TIME_WAIT
tcp 1 1 xxx.108.37.77:80 60.186.14.190:13808 CLOSING
tcp 0 0 xxx.108.37.77:80 60.208.111.253:57016 TIME_WAIT
tcp 1 1 xxx.108.37.77:80 219.145.113.15:52970 CLOSING
tcp 0 0 xxx.108.37.77:80 61.170.213.11:14705 TIME_WAIT
tcp 1 1 xxx.108.37.77:80 xxx.106.180.254:2266 CLOSING
tcp 1 1 xxx.108.37.77:80 222.68.248.150:7632 CLOSING
tcp 0 0 xxx.108.37.77:80 60.17.17.149:62063 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 60.0.16.66:3159 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 58.101.33.97:3616 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 125.32.0.114:1367 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 125.33.217.83:3502 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 71.135.63.37:61595 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 218.26.227.9:31478 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 220.161.163.113:1141 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 221.1.244.62:1229 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 60.2.106.52:58970 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 221.15.17.77:1877 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 222.64.14.150:64545 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 222.67.166.24:2299 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 61.51.223.223:1994 TIME_WAIT
--More--warning, got duplicate tcp line.
warning, got duplicate tcp line.
tcp 0 0 xxx.108.37.77:80 61.155.18.18:56733 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 60.15.21.5:12313 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 58.33.225.117:2739 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 61.167.60.224:58498 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 58.60.5.33:7454 TIME_WAIT
tcp 0 243 xxx.108.37.77:80 218.71.200.192:1718 FIN_WAIT1
tcp 0 0 xxx.108.37.77:80 123.49.164.148:55288 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 125.33.217.83:3501 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 221.214.13.109:47024 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 221.218.117.87:17919 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 218.108.44.10:21325 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 124.200.18.190:3484 TIME_WAIT
tcp 0 300 xxx.108.37.77:80 221.218.117.87:26879 FIN_WAIT1
tcp 0 567 xxx.108.37.77:80 221.218.117.87:27135 FIN_WAIT1
tcp 0 0 xxx.108.37.77:80 218.26.227.9:31479 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 220.161.163.113:1140 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 221.222.144.24:1617 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 60.2.106.52:58971 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 221.5.181.31:3752 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 61.49.166.124:62700 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 221.0.180.142:58306 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 61.51.223.223:1995 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 60.208.111.253:57018 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 xxx.111.152.6:56054 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 58.33.225.117:2738 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 61.181.245.85:25618 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 123.49.164.148:55289 TIME_WAIT
tcp 1 1 xxx.108.37.77:80 125.92.214.174:6619 CLOSING
tcp 0 0 xxx.108.37.77:80 124.200.18.190:3483 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 60.166.100.106:48296 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 222.223.6.176:40086 ESTABLISHED
tcp 0 0 xxx.108.37.77:80 124.42.126.70:55826 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 221.226.242.212:64827 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 221.198.127.25:1952 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 222.64.14.150:64295 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 xxx.106.113.61:6182 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 221.229.12.88:4273 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 61.49.166.124:62699 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 221.8.9.91:5210 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 210.21.196.86:11655 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 218.87.255.183:3552 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 61.181.250.190:32782 TIME_WAIT
tcp 0 0 xxx.108.37.77:80 125.33.217.83:3499 TIME_WAIT
wyezl 回复于:2006-08-22 15:12:21
引用:原帖由 nuclearweapon 于 2006-8-22 15:04 发表
你打开tcp_syncookies
试试。
再做测试
怎么打开?
思一克 回复于:2006-08-22 15:14:30
wyezl,
攻击不会影响FD。FD是已经建立的连接没close.
思一克 回复于:2006-08-22 15:15:40
这个帖子可以做为精华了。因为问题微妙又棘手,有普遍性,尤其对与EPOLL
nuclearweapon 回复于:2006-08-22 15:17:25
如果一直有大量的SYN_RECV就有可能是攻击。
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
可以打开。
下边还有几个都是对付 ddos的。太具体要自己查查。
wyezl 回复于:2006-08-22 15:23:30
引用:原帖由 思一克 于 2006-8-22 15:14 发表
wyezl,
攻击不会影响FD。FD是已经建立的连接没close.
我暂时的方法是描述符用完了,就退出。
由监视程序定时检查和重启。
这不知道是不是epoll自身的缺陷。
nuclearweapon 回复于:2006-08-22 15:25:25
引用:原帖由 思一克 于 2006-8-22 15:14 发表
wyezl,
攻击不会影响FD。FD是已经建立的连接没close.
我记得和斑竹有一些出入。
因为:
只要有socket就会有一个inode,也就会有一个fd。而不是连接以后才会有fd的。
对于linux2。6来说
每当在内核创建完struct socket后,就会调用sock_map_fd()在调用进程创建一个fd。
如果有SYN_RECV状态,也就有了struct socket,也就有了inode,进而有了fd。
希望指正!
[ 本帖最后由 nuclearweapon 于 2006-8-22 15:27 编辑 ]
思一克 回复于:2006-08-22 15:26:40
应该不是epoll本身的问题。epoll采样事件,如果事件没有来它也无能为力。timeout是必须的
wyezl 回复于:2006-08-22 15:27:28
引用:原帖由 思一克 于 2006-8-22 15:15 发表
这个帖子可以做为精华了。因为问题微妙又棘手,有普遍性,尤其对与EPOLL
如果能讨论出一个成熟的,通用的epoll模型。 加精华也不亏。呵呵。
我继续线上测试。
uname -a
Linux xxx.com.cn 2.6.9-34.EL #1 Wed Mar 8 00:07:35 CST 2006 i686 i686 i386 GNU/Linux
[finance@sina src]$ cat /etc/issue
CentOS release 4.1 (Final)
Kernel \r on an \m
思一克 回复于:2006-08-22 15:30:35
TO nuclearweapon,
你说的对。但他的问题是accept之后的fd被耗尽了,那就是有连接的socket.
如果那些DDOS攻击,往往是半连接(部分IP包),accept不了。
引用:原帖由 nuclearweapon 于 2006-8-22 15:25 发表
我记得和斑竹有一些出入。
因为:
只要有socket就会有一个inode,也就会有一个fd。而不是连接以后才会有fd的。
对于linux2。6来说
每当在内核创建完struct socket后,就会调用sock_map_fd()在调用进程创建 ...
nuclearweapon 回复于:2006-08-22 15:35:28
引用:原帖由 思一克 于 2006-8-22 15:30 发表
TO nuclearweapon,
你说的对。但他的问题是accept之后的fd被耗尽了,那就是有连接的socket.
如果那些DDOS攻击,往往是半连接(部分IP包),accept不了。
就是这半连接的socket把fd用完了。
因为只有有了socket才可能有sycrcv状态。
思一克 回复于:2006-08-22 15:42:47
To nuclearweapon,
也有可能是攻击引起的。让他继续实验。
半连接accept能成功返回fd吗?我不是十分肯定。
nuclearweapon 回复于:2006-08-22 15:45:33
对于半连接来说accpet是不能返回了,但是在内核中fd已经建立起来了,也就消耗了一个进程的可用fd数量。
wyezl 回复于:2006-08-22 15:50:57
引用:原帖由 思一克 于 2006-8-22 15:42 发表
To nuclearweapon,
也有可能是攻击引起的。让他继续实验。
半连接accept能成功返回fd吗?我不是十分肯定。
现在访问量下降了。
SYN_RECV 也下降到了只有20~30个。
恶意攻击的可能性比较小。
是不是由于我的次序造成的?
思一克 回复于:2006-08-22 15:52:56
TO nuclearweapon,
你肯定没有建立的连接,没有accept的也消耗KERNEL中的fd吗? 我不SURE
wyezl 回复于:2006-08-22 15:54:38
引用:原帖由 nuclearweapon 于 2006-8-22 15:45 发表
对于半连接来说accpet是不能返回了,但是在内核中fd已经建立起来了,也就消耗了一个进程的可用fd数量。
我可以统计一段时间内, accpet的总数,和close的总数。看他们的差是不是等于。
/etc/pid/fd 下面的fd数。
思一克 回复于:2006-08-22 16:00:55
TO nuclearweapon,
我刚才看了KERNEL代码,看到fd消耗只有3个函数socket() , accept(), socketpair(), 而且都是成功后才消耗fd. 网络程序其它任何地方没有看到用fd的?
半连接能消耗fd吗,我不是很清楚。如果你清楚就写出来。
谢谢
引用:原帖由 nuclearweapon 于 2006-8-22 15:45 发表
对于半连接来说accpet是不能返回了,但是在内核中fd已经建立起来了,也就消耗了一个进程的可用fd数量。
wyezl 回复于:2006-08-22 16:05:40
现在访问量比较少的时候。fd随时间变化情况。当然是重新启动之后测试的。这样看起来基本没问题。
压力上来后就漫漫变了。
[root@xxx ~]# ls /proc/28305/fd/
0 10 12 14 16 18 2 21 23 25 28 4 6 8
1 11 13 15 17 19 20 22 24 27 3 5 7 9
< |