提高Linux的连接限制
DearMichael
|
1#
DearMichael 发表于 2007-08-09 20:59
提高Linux的连接限制
一般linux下TCP连接的限制在TD_SETSIZE,系统默认为1024,由FD_SETSIZE决定。
1.修改方法: 修改/usr/etc/security/limits.conf文件,加入 *soft nofile 20000 *hard nofile 20000 然后reboot系统。 服务器就可以建立连接到20000个了,其连接方法是直接用connect,accept,注意这里用select是不可以的。 2.上面的方法在不用select方法的情况下是不可以的,如果你用select,那么仍然只能打开1024个,这是因为select的数目由FD_SETSIZE决定的。那么我们可以改用poll来替代select,poll数组大小可以根据我们自己的需要来定义,这样就解决了这个问题。 3.linux中的是通过文件方式来管理系统的,因此系统能承载多少TCP连接和系统文件打开数目能力是相关的。 另外在/proc/sys/file-max中定义了,系统最多能够打开的文件数目。 附代码: 服务器端:pollserver.cpp #include <iostream> #include <ctype.h> #include <errno.h> #include <signal.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/file.h> #include <sys/ioctl.h> #include <sys/wait.h> #include <sys/types.h> //#include <asm/poll.h> #include <netdb.h> #include <unistd.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string> #include <sys/poll.h> #include <limits.h> /* for OPEN_MAX */ #define LPORT 3333 #define LISTENQ 1024 #define OPEN_MAX 50000 #define MAX_LINE 100 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 argc, char **argv) { //int i, maxi, listenfd, connfd, sockfd; //int nready; ssize_t n; int listenfd; struct sockaddr_in cliaddr; //客户端的sock描述 struct sockaddr_in servaddr; //服务器的sock描述 struct pollfd *array_conn; array_conn = new pollfd[OPEN_MAX]; if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket create error!"); exit(1); } bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(LPORT); /* 置 socket 重新使用 */ int opt = 1; if (setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,(char *) &opt,sizeof(opt))<0) { close(listenfd); perror("!cserver::init_comm() setsockopt error!"); exit(1); } if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr))== -1) { perror("bind error!"); exit(1); } listen(listenfd, LISTENQ); array_conn[0].fd = listenfd; array_conn[0].events = POLLRDNORM; int i; for ( i = 1; i < OPEN_MAX; i++) array_conn.fd = -1; /* -1 indicates available entry */ int maxi = 0; int connfd; int nready; int clilen; size_t n; int x; x=0; for ( ; ; ) { int nready = poll(array_conn, maxi+1, 0); if (array_conn[0].revents & POLLRDNORM) { clilen = sizeof(cliaddr); connfd = accept(listenfd, (struct sockaddr *) &cliaddr,(socklen_t*) &clilen); printf(" ||%d: Connection from %s:%d\n",x++, inet_ntoa(cliaddr.sin_addr),cliaddr.sin_port); // setnonblocking(connfd); for (i = 1; i < OPEN_MAX; i++) if (array_conn.fd < 0) { array_conn.fd = connfd; // save descriptor break; } if (i == OPEN_MAX) { printf("too many clients"); break; } array_conn.events = POLLRDNORM; if (i > maxi) maxi = i; if (--nready <= 0) continue; /* no more readable descriptors */ } /* check all clients for data */ char line[100]; int sockfd; for (i = 1; i <= maxi; i++) { /* check all clients for data */ if ( (sockfd = array_conn.fd) < 0) continue; if (array_conn.revents & (POLLRDNORM | POLLERR)) { if ( (n = read(sockfd, line, MAX_LINE)) < 0) { if (errno == ECONNRESET) { /*4connection reset by client */ close(sockfd); array_conn.fd = -1; } else { printf("readline error\n"); } } else if (n == 0) { /*4connection closed by client */ close(sockfd); array_conn.fd = -1; } else { char sb[10]; printf("Recv:%s from socket %d",line,sockfd); sprintf(sb,"Pong!"); write(sockfd, sb, 10); } if (--nready <= 0) break; /* no more readable descriptors */ } } } } 客户端pollclient.cpp #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> int main() { int sockfd; int address_len; int connect_flag; struct sockaddr_in address; int connect_result; char client_ch,server_ch; int *sock; sock= new int [50000]; int index=0; int n=0; int ssock; address.sin_family=AF_INET; address.sin_addr.s_addr=inet_addr("192.168.1.249"); address.sin_port=htons(3333); address_len=sizeof(address); while(1) { ssock=socket(AF_INET,SOCK_STREAM,0); if(ssock<0) { printf("local sockfd error \n"); break; } connect_flag=connect(ssock,(struct sockaddr *)&address,address_len); if(connect_flag==-1) { perror("client"); break; } printf("%d Connected! ",n++); char cch[10]; sprintf(cch,"Ping*"); write(ssock,cch,10); char rbuf[100]; read(ssock,rbuf,100); printf( "%d Receive from server ;%s\n",n,rbuf); //char c_ch; //c_ch='*'; //write(ssock,&c_ch,1); //char rbuf[100]; //read(ssock,rbuf,100); //printf( "%d Receive from server ;%s\n",n,rbuf); } delete [] sock; return 0; } |