micobest 2013-10-21 19:07 采纳率: 0%
浏览 3187

Linux下epoll并发数量达到1987个后涨不上去

Linux下epoll并发数量达到1987个后涨不上去(达到1987个链接后,无法接受新链接,并非最大开文件句柄限制所导致)

我在linux下写来一个简单的epoll server程序,在局域网中另一台windows计算机采用多线程的形式链接server,但是大概epoll链接了1987个套接字后,再也不能增加新链接了(并非最大文件句柄数量所限制),不清楚所什么原因,跪求解答,谢谢各位好心人。

server代码:

#include
#include /* basic system data types /
#include /
basic socket definitions /
#include /
sockaddr_in{} and other Internet defns /
#include /
inet(3) functions /
#include /
epoll function /
#include /
nonblocking */
#include /*setrlimit */

#include
#include
#include
#include

#define MAXEPOLLSIZE 10000
#define MAXLINE 10240
int handle(int connfd);
int setnonblocking(int sockfd)
{
if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)|O_NONBLOCK) == -1) {
return -1;
}
return 0;
}

int main(int argc, char **argv)
{
int servPort = 6888;
int listenq = 1024;

int listenfd, connfd, kdpfd, nfds, n, nread, curfds,acceptCount = 0;
struct sockaddr_in servaddr, cliaddr;
socklen_t socklen = sizeof(struct sockaddr_in);
struct epoll_event ev;
struct epoll_event events[MAXEPOLLSIZE];
struct rlimit rt;
char buf[MAXLINE];

/* 设置每个进程允许打开的最大文件数 */
rt.rlim_max = rt.rlim_cur = MAXEPOLLSIZE;
if (setrlimit(RLIMIT_NOFILE, &rt) == -1) 
{
    perror("setrlimit error");
    return -1;
}


bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET; 
servaddr.sin_addr.s_addr = htonl (INADDR_ANY);
servaddr.sin_port = htons (servPort);

listenfd = socket(AF_INET, SOCK_STREAM, 0); 
if (listenfd == -1) {
    perror("can't create socket file");
    return -1;
}

int opt = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

if (setnonblocking(listenfd) < 0) {
    perror("setnonblock error");
}

if (bind(listenfd, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) == -1) 
{
    perror("bind error");
    return -1;
} 
if (listen(listenfd, listenq) == -1) 
{
    perror("listen error");
    return -1;
}
/* 创建 epoll 句柄,把监听 socket 加入到 epoll 集合里 */
kdpfd = epoll_create(MAXEPOLLSIZE);
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = listenfd;
if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, listenfd, &ev) < 0) 
{
    fprintf(stderr, "epoll set insertion error: fd=%d\n", listenfd);
    return -1;
}
curfds = 1;

printf("epollserver startup,port %d, max connection is %d, backlog is %d\n", servPort, MAXEPOLLSIZE, listenq);

for (;;) {
    /* 等待有事件发生 */
    nfds = epoll_wait(kdpfd, events, curfds, -1);
    if (nfds == -1)
    {
        perror("epoll_wait");
        continue;
    }
    /* 处理所有事件 */
    for (n = 0; n < nfds; ++n)
    {
        if (events[n].data.fd == listenfd) 
        {
            connfd = accept(listenfd, (struct sockaddr *)&cliaddr,&socklen);
            if (connfd < 0) 
            {
                perror("accept error");
                continue;
            }

            sprintf(buf, "accept form %s:%d\n", inet_ntoa(cliaddr.sin_addr), cliaddr.sin_port);
            printf("%d:%s", ++acceptCount, buf);

            if (curfds >= MAXEPOLLSIZE) {
                fprintf(stderr, "too many connection, more than %d\n", MAXEPOLLSIZE);
                close(connfd);
                continue;
            } 
            if (setnonblocking(connfd) < 0) {
                perror("setnonblocking error");
            }
            ev.events = EPOLLIN | EPOLLET;
            ev.data.fd = connfd;
            if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, connfd, &ev) < 0)
            {
                fprintf(stderr, "add socket '%d' to epoll failed: %s\n", connfd, strerror(errno));
                return -1;
            }
            curfds++;
    printf("%d\n", curfds);
            continue;
        } 
        // 处理客户端请求
        if (handle(events[n].data.fd) < 0) {
            epoll_ctl(kdpfd, EPOLL_CTL_DEL, events[n].data.fd,&ev);
            curfds--;


        }
    }
}
close(listenfd);
return 0;

}
int handle(int connfd) {
int nread;
char buf[MAXLINE];
nread = read(connfd, buf, MAXLINE);//读取客户端socket流

if (nread == 0) {
    printf("client close the connection\n");
    close(connfd);
    return -1;
} 
if (nread < 0) {
    perror("read error");
    close(connfd);
    return -1;
}    
write(connfd, buf, nread);//响应客户端  
return 0;

}

  • 写回答

1条回答 默认 最新

  • NK_test 博客专家认证 2016-04-23 15:48
    关注

    确认不是客户端的问题?

    评论

报告相同问题?

悬赏问题

  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3
  • ¥15 牛顿斯科特系数表表示
  • ¥15 arduino 步进电机
  • ¥20 程序进入HardFault_Handler
  • ¥15 关于#python#的问题:自动化测试