13 select的优化一

1. 上个例子中,select通过for循环轮询client套接字,轮询的范围比较大,有优化的地方。

2. 优化代码:

通过数组存储client的套接字,达到少轮询的效果,可以在client数量比较多、读写数据量大的情况下看到效果;

select的最大连接数1024,所以在处理并发量比较小的时候可以用上,如果并发大的时候需要重新考虑。


#include "socket_includes.h"



int mz_ipv4_tcp_create_socket(void)
{
	int listenfd, sockfd, opt = 1;
	struct sockaddr_in server, client;
	socklen_t len;
	int timep;
	int ret;

	listenfd = socket(AF_INET, SOCK_STREAM, 0);
	if(listenfd < 0){
		perror("Create socket fail.");
		return -1;
	} 

	if((ret = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) < 0){
		perror("Error, set socket reuse addr failed");  
		return -1;
	}

	bzero(&server, sizeof(server));
	server.sin_family = AF_INET;
	server.sin_port   = htons(SERV_PORT);
	server.sin_addr.s_addr  = htonl(INADDR_ANY);
	
	len = sizeof(struct sockaddr);
	if(bind(listenfd, (struct sockaddr *)&server, len)<0){
			  perror("bind error.");
		return -1;
	}
	
	  
	listen(listenfd, MAX_LISTEN_QUE);

	return listenfd;
}




int main(int argc, char *argv[])
{
	int listenfd, sockfd;
	struct sockaddr_in server, client;
	socklen_t len;
	int bytes =0 ;
	fd_set global_rdfs,current_rdfs;	
	int maxfd;	
	int i;
	char buf[MAX_BUFFER_SIZE];
	int client_fd[FD_SETSIZE];

	len = sizeof(struct sockaddr_in);

	printf("FD_SETSIZE=%d\n", FD_SETSIZE);

	listenfd = mz_ipv4_tcp_create_socket();
	FD_ZERO(&global_rdfs);
	FD_SET(listenfd, &global_rdfs);
	maxfd = listenfd;
	for(i = 0; i < FD_SETSIZE; i++ )
		client_fd[i] = -1;

	while(1){
		current_rdfs = global_rdfs;
		if(select(maxfd + 1, ¤t_rdfs, NULL, NULL, NULL)<0){
			perror("select error.\n");
			return RT_ERR;
		}

		if(FD_ISSET(listenfd, ¤t_rdfs)){
			
			if((sockfd = accept(listenfd, (struct sockaddr*)&client, (socklen_t*)&len))<0){
				perror("accept error.\n");
				return RT_ERR;
			}
			printf("sockfd:%d\n", sockfd);
			FD_CLR(i, ¤t_rdfs);
			maxfd = maxfd > sockfd ? maxfd :sockfd;
			FD_SET(sockfd, &global_rdfs);
			for(i = 0; i < maxfd; i++){
				if(-1 == client_fd[i]){
					client_fd[i] = sockfd;
					break;
				}
			}
		}

		for(i = 0; i <= maxfd; i++){
			if(-1 == client_fd[i]){
				continue;
			}	
			if(FD_ISSET(client_fd[i], ¤t_rdfs)){
				printf("read socket:%d\n", client_fd[i]);
				bytes = recv(client_fd[i], buf, MAX_BUFFER_SIZE, 0);
				if(bytes < 0){
					perror("recv error.\n");
					return RT_ERR;
				}
				if(bytes == 0){
					FD_CLR(client_fd[i], &global_rdfs);
					close(client_fd[i]);
					client_fd[i] = -1;
					continue;
				}
				printf("buf:%s\n", buf);
				send(client_fd[i], buf, strlen(buf), 0);

			}
		
		}
	}
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值