Linux c/c++ 基于socket select 复用,一个固定大小int 数组记录服务端连接的socket 信息

本文展示了如何在Linux环境下,利用C/C++编程通过socket的select复用技术,管理固定数量的客户端连接。代码创建了一个固定大小的数组来存储socket文件描述符,并使用select函数监听所有连接,当有输入事件发生时,处理相应的客户端请求。当新的客户端连接到来时,会寻找数组中未使用的空间进行存储,同时更新最大文件描述符。
摘要由CSDN通过智能技术生成

Linux c/c++ 基于socket select 复用技术,使用一个int 数组记录服务端连接的socket 信息,在本文中采用一个固定大小数组来管理socket信息,避免连接增多数组长度无限制增长。

#define MAXSIZE 1024
int maxindex=0;   //最大socket_fd 数组
int allfds[MAXSIZE]; //保存socket_fd 数组
int maxfd = -1;
fd_set rfds;
int main()
{
	for(int y = 0;y<MAXSIZE;y++)
		allfds[y] = -1;
	int ss  = socket(AF_INET,SOCK_STREAM,0);
	server_sockaddr.sin_family  = AF_INET;
	server_sockaddr.sin_port = htons(6666);
	server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	int flag =1;
	int result = setsockopt(ss, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));
	if(bind(ss,(struct sockaddr*)&server_sockaddr,sizeof(server_sockaddr)) == -1)
	{
		printf("bind error\n");
		exit(1);
	}
	if(listen(ss,20) == -1)
	{
	...
	}
	maxfd = ss;
    	allfds[maxindex] = ss;
    	while(1)
    	{
    		FD_ZERO(&rfds);
    		 for(int i = 0;i<MAXSIZE;i++)
        	{   
            
            		if(allfds[i]!= -1)
                	FD_SET(allfds[i],&rfds);     
        	}

	
		int retval;
        	retval = select(maxfd+1, &rfds, NULL, NULL,NULL);
        	if(retval == -1){
             		printf("seleect error\n");
         		break;
        	 }
        	 else if(retval == 0)
         	 {
           	 // printf("server no input\n");
             		continue;
        	  }
        	  else{
			for(int i =0;i<MAXSIZE;i++)
			{
				if(retval == 0)
                        	 break;

			}
			 if(!FD_ISSET(allfds[i],&rfds))
                        {
                         	continue;
                        }
			 if(allfds[i] == ss)
			 {
			 	retval--;
                          	struct sockaddr_in client_addr;
                          	socklen_t length  = sizeof(client_addr);
    
                           	int conn = accept(ss,(struct sockaddr*)&client_addr,&length);
                           	if(conn < 0)
                           	{
                               		printf("accept error\n");
                           	}
                           	else{
                           
                                 	printf("Client[%d], welcome!\n",conn);              
                                 }
				for(int n=0;n<MAXSIZE;n++) //找为-1的空位,如果大于最大sockfd ,更新最大值和下标
                           	{
                               		if(allfds[n] == -1)
                               		{
                                   		allfds[n] = conn;
                                   		if(maxfd < conn)
                                   		{
                                      		maxfd = conn;
                                       		maxindex = n;
                                    		}
                                   break;                            
                               }
                           
                           }
			
			 }
			 else{
				char msg[MAXSIZE] = {0x0};
				int nrecvSize;
				if((nrecvSize = read(allfds[i],msg,MAXSIZE))< 0)
				{
					continue;
				}
 				else if(nrecvSize == 0 )
 				{
					 printf("client has disconnected!\n");
					 close(allfds[i]);  
					 FD_CLR(allfds[i], &rfds);
					 allfds[i] = -1; //释放对应下标元素
					 if(i == maxindex)
					 {
						 int maxnum = -1;
						 for (int maxsearch = 0 ;maxsearch < MAXSIZE;maxsearch++)//重新遍历找最大值
						 {
							if(allfds[maxsearch] > maxnum)
                                    			 {
                                         			maxnum =  allfds[maxsearch];
                                         			maxindex = maxsearch;
                                     
                                     			}
						 }
						 maxfd = maxnum;
          				 }
				}

				else{
			 		printf("msg is %s\n",msg);
				}

			
		  }
	
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值