unix网络编程(二) select实现tcp的sever端

select 即是采用轮询内核的方式,获知哪些连接发送或接受消息了。

select 最大监听1024个连接

 过程:

(start)监听套接字:创建绑定监听

(select)初始化fd_set ===> select监听fd_set ===> fd_set中未变化的位置置零(0)

                依据fd_set中剩余的有变化的位置(1) ===> 判断是监听套接字还是已连接的套接字

                ===> 分别处理

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/time.h>
#include<sys/select.h>
#include "pub.h"
int main()
{
	int lfd = -1, cfd = -1;
	char buf[1024];
	// 绑定ip和端口号
	lfd = socketBind("127.0.0.1", 8080);
	
	
	// 记录需要监听的fd的allset,初始化为0
	fd_set allset, rset;
	FD_ZERO(&allset);
	FD_ZERO(&rset);

	// 记录客户端cfd的值的集合, 监听上线FD_SETSIZE = 1024
	int client[FD_SETSIZE], i=0;
	for(i=0; i<FD_SETSIZE; i++)
		client[i] = -1;

	int maxfd = lfd, maxindex = 0;
	FD_SET(lfd, &allset);
	while(1)
	{
		rset = allset;
		int nready = select(maxfd+1, &rset, NULL, NULL, NULL); // 监听的最大fd数量=最大的fd序号+1
		if(nready <= 0)
		{
			perror("select");
			break;
		}


		// 如果是lfd变化
		if(FD_ISSET(lfd, &rset))
		{
			cfd = Accept_with_print(lfd);
			
			
			// 连接数超过1024
			if(cfd == FD_SETSIZE)
			{
				printf("too many connect\n");
				close(cfd);
				continue;
			}


			// 添加cfd到监听集合,更新maxfd; cfd添加到监听客户端client集合,更新maxindex
			FD_SET(cfd, &allset);
			if(cfd > maxfd)
				maxfd = cfd;
			for(i=0; i<FD_SETSIZE; i++)
			{
				if(client[i] < 0)
				{
					client[i] = cfd;
					break;
				}
			}
			if(i > maxindex)
				maxindex = i;

			if(--nready == 0)
				continue;
		}



		// cfd变化
		for(i=0; i<=maxindex; i++)
		{
			// 取需要监听的client
			if((cfd = client[i]) < 0)
				continue;
			if(FD_ISSET(cfd, &rset))
			{
				int num = read(cfd, buf, sizeof(buf));
				if(num < 0)
				{
					perror("read");
					return -1;
				}
				else if(num == 0)
				{
					printf("cfd=%d closed\n", cfd);
					close(cfd);
					FD_CLR(cfd, &allset);
					client[i] = -1;
				}
				else
				{
					write(cfd, buf, num);
				}

			}
			if(--nready == 0)
				break;

		}


	}




}

猜你喜欢

转载自blog.csdn.net/qq_55796594/article/details/127693841
今日推荐