menu

秋梦无痕

一场秋雨无梦痕,春夜清风冻煞人。冬来冷水寒似铁,夏至京北蟑满城。

Avatar

linux下调整最多打开端口数

from: NetPRG@SMTH

linux上自己调整最多能够开多少个socket:

echo "65535" >/proc/sys/fs/file-max
ulimit -n 10000

from: 提高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[i].fd = -1; // -1 indicates

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;
}

评论已关闭