提高linux的连接限制

王朝system·作者佚名  2006-01-09
宽屏版  字体: |||超大  

一般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[i].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[i].fd < 0)

{

array_conn[i].fd = connfd; // save descriptor

break;

}

if (i == OPEN_MAX)

{

printf("too many clients");

break;

}

array_conn[i].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[i].fd) < 0) continue;

if (array_conn[i].revents & (POLLRDNORM | POLLERR))

{

if ( (n = read(sockfd, line, MAX_LINE)) < 0)

{

if (errno == ECONNRESET)

{

/*4connection reset by client */

close(sockfd);

array_conn[i].fd = -1;

} else

{

printf("readline error\n");

}

}

else if (n == 0)

{

/*4connection closed by client */

close(sockfd);

array_conn[i].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;

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
© 2005- 王朝网络 版权所有