He,YuanHui —— 业精于勤荒于嬉,行成于思毁于随

如果你喜欢一个事,又有这样的才干,那就把整个人都投入进去,就要象一把刀直扎下去直到刀柄一样,不要问为什么,也不要管会碰到什么。

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

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

posted on 2010-09-19 13:50  He,YuanHui  阅读(458)  评论(0编辑  收藏  举报

Add to Google