linux网络编程-Linux下epoll并发数量达到1987个后涨不上去

问题描述

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=%dn", listenfd);
    return -1;
}
curfds = 1;

printf("epollserver startup,port %d, max connection is %d, backlog is %dn", 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:%dn", inet_ntoa(cliaddr.sin_addr), cliaddr.sin_port);
            printf("%d:%s", ++acceptCount, buf);

            if (curfds >= MAXEPOLLSIZE) {
                fprintf(stderr, "too many connection, more than %dn", 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: %sn", connfd, strerror(errno));
                return -1;
            }
            curfds++;
    printf("%dn", 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 connectionn");
    close(connfd);
    return -1;
}
if (nread < 0) {
    perror("read error");
    close(connfd);
    return -1;
}
write(connfd, buf, nread);//响应客户端
return 0;

}

解决方案

确认不是客户端的问题?

时间: 2024-10-31 19:00:23

linux网络编程-Linux下epoll并发数量达到1987个后涨不上去的相关文章

linux网络编程-linux方面遇到的一个难题,希望大哥大姐帮忙解决下,小弟是菜鸟,刚学linux编程

问题描述 linux方面遇到的一个难题,希望大哥大姐帮忙解决下,小弟是菜鸟,刚学linux编程 /proc/进程号/statm包含了进程使用内存的信息,如[root@cs 9519]# more statm 18095 2094 1468 7 0 605 0 [root@cs 9519]# ps 9519PID TTY STAT TIME COMMAND9519 ? S 0:00 /usr/libexec/notification-daemonmore statm 18095 2094 1468

linux网络编程-LINUX下模拟DNS编程,写报文时关于DOMAIN NAME 的格式转换程序

问题描述 LINUX下模拟DNS编程,写报文时关于DOMAIN NAME 的格式转换程序 这段程序要求是转换格式,如www.baidu.com换成3www5baidu3com0 网上有代码 void ChangetoDnsNameFormat(unsigned char* dns,unsigned char* host) { int lock = 0 , i; strcat((char*)host,"."); for(i = 0 ; i < strlen((char*)host)

Linux网络编程 epoll中EPOLLIN EPOLLOUT信号无法触发

问题描述 Linux网络编程 epoll中EPOLLIN EPOLLOUT信号无法触发 比如 if(events[i].events&EPOLLIN) { int bytes_read=read(m_sockfd,read_buf,READ_BUFFER_SIZE); } 这样会触发EPOLLIN 但如果把read()封装到比如service类的sread()函数中 if(events[i].events&EPOLLIN) { service.sread() } 便不会触发EPOLLIN事

Linux 网络编程 epoll中的EPOLLIN EPOLLOUT如何触发

问题描述 Linux 网络编程 epoll中的EPOLLIN EPOLLOUT如何触发 代码很长只截取关键部分 //服务器端 #include #include #include #include #include #include #include #include #include #include"locker.h" #include"threadpool.h" #include"http_conn.h" #include"htt

Linux网络编程入门

(一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍 客户端和服务端          网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户端         在网络程序中,如果一个程序主动和外面的程序通信,那么我们把这个程序称为客户端程序. 比如我们使用ftp程序从另外一         个地方获取文件的时候,是我们的ftp程序主动同外面进行通信(获取文件), 所以这个地方我们的ftp程序就是客户端程序.  服务端        

Linux网络编程一步一步学【转】

转自:http://blog.chinaunix.net/uid-10747583-id-297982.html Linux网络编程一步一步学+基础  原文地址:http://blogold.chinaunix.net/u1/48325/showart_413841.html ·Linux网络编程基础(一)·Linux网络编程基础(二)·Linux网络编程基础(三) • Linux网络编程一步一步学-简单客户端编写   • Linux网络编程一步一步学-绑定IP和端口 • Linux网络编程一步

Proxy源代码分析--谈谈如何学习linux网络编程

原创地址: http://fanqiang.chinaunix.net/a4/b7/20010810/1200001101.html   Linux是一个可靠性非常高的操作系统,但是所有用过Linux的朋友都会感觉到,Linux和Windows这样的"傻瓜"操作系统(这里丝毫没有贬低Windows的意思,相反这应该是Windows的优点)相比,后者无疑在易操作性上更胜一筹.但是为什么又有那么多的爱好者钟情于Linux呢,当然自由是最吸引人的一点,另外Linux强大的功能也是一个非常重要

Linux网络编程socket选项之SO_LINGER,SO_REUSEADDR

                       Linux网络编程socket选项之SO_LINGER,SO_REUSEADDR Linux网络编程中,socket的选项很多.其中几个比较重要的选项有:SO_LINGER(仅仅适用于TCP,SCTP), SO_REUSEADDR.   SO_LINGER 在默认情况下,当调用close关闭socke的使用,close会立即返回,但是,如果send buffer中还有数据,系统会试着先把send buffer中的数据发送出去,然后close才返回.

线程-windows 和 linux 网络编程文件传输

问题描述 windows 和 linux 网络编程文件传输 windows 两个线程,linux 两个进程,现在想传输一个文件,windows 这边其中的一个进程传一部分,剩下的由另外的一个进程来传.有什么好的方法吗?找了好多可是都没有相关的资料.谢谢大家. 解决方案 就是socket通信传递,windows做客户端,linux做服务端 解决方案二: Linux与Windows下文件传输windows到linux的文件传输linux 和 windows 文件传输