C/S架构学习之使用select实现TCP小型并发服务器

news/2025/1/3 14:58:05/
  • select实现TCP小型并发服务器的流程:
  • 一、创建套接字(socket函数):
  • 通信域选择IPV4网络协议、套接字类型选择流式
	int sockfd = socket(AF_INET,SOCK_STREAM,0); //通信域选择IPV4、套接字类型选择流式
  • 二、填充服务器的网络信息结构体:
  • 1.定义网络信息结构体变量;
  • 2.求出网络信息结构体变量的内存空间大小,以作备用;
  • 3.网络信息结构体清0
  • 4.使用IPV4网络协议AF_INET
  • 5.在终端输入的服务器端主机的IP地址inet_addr(argv[1])
  • 6.在终端输入的服务器端网络字节序的端口号htons(atoi(argv[2]))
	struct sockaddr_in serveraddr; //定义网络信息结构体变量socklen_t serveraddrlen = sizeof(serveraddr);//求出结构体变量的内存空间大小memset(&serveraddr,0,serveraddrlen); //结构体清零serveraddr.sin_family = AF_INET;  //使用IPV4网络协议serveraddr.sin_addr.s_addr = inet_addr(argv[1]);  //IP地址serveraddr.sin_port = htons(atoi(argv[2]));//网络字节序的端口号
  • 三、套接字和服务器的网络信息结构体进行绑定(bind函数):
	int ret = bind(sockfd,(struct sockaddr *)&serveraddr,serveraddrlen);
  • 四、套接字设置成被动监听(listen函数):
	int ret1 = listen(sockfd, 5);
  • 五、创建要监听的文件描述符集合:
  • 使用select函数后,会将没有就绪的文件描述符在集合中去除,所以需要创建两个文件描述符集合,一个是母本read_fds,类似于常量,保持不变,而另一个作为副本read_fds_t,类似于变量,可以改变;
	fd_set read_fds;FD_ZERO(&read_fds);fd_set read_fds_t;FD_ZERO(&read_fds_t);
  • 六、把创建的套接字添加到要监视的集合中:
	FD_SET(sockfd,&read_fds);int fd_max = 0;fd_max = fd_max > sockfd ? fd_max : sockfd;
  • 七、设置系统时间结构体变量,用来指定超时的时间:
	struct timeval tm_out;
  • 八、等待文件描述符中的事件是否就绪,成功则返回就绪的文件描述符的个数(select函数):
  • select函数:
	#include <sys/select.h>int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);/*参数:nfds:		要监视的最大文件描述符+1readfds:	要监视的读文件描述符集合 不关心可以传NULLwritefds:	要监视的写文件描述符集合 不关心可以传NULLexceptfds:	要监视的异常文件描述符集合 不关心可以传NULLtimeout:	超时时间 如果设置成NULL 会一直阻塞 直到有文件描述符就绪返回值:成功 就绪的文件描述符的个数超时 0失败 -1 重置错误码*///struct timeval  可以指定超时时间//如果结构体的两个成员都为0 表示非阻塞struct timeval {long    tv_sec;         //秒 long    tv_usec;       //微秒};void FD_CLR(int fd, fd_set *set);	//将文件描述符在集合中删除int  FD_ISSET(int fd, fd_set *set);	//判断文件描述符是否还在集合中// 返回0 表示不在了 非0 表示在void FD_SET(int fd, fd_set *set);	//向集合中添加一个文件描述符void FD_ZERO(fd_set *set);			//清空集合
		if(-1 == (ret = select(fd_max + 1,&read_fds_t,NULL,NULL,&tm_out))){perror("select error");exit(-1);}else if(0 == ret){puts("timeout!!!!!");putchar('\n');continue;}
  • 九、遍历文件描述符集合,判断哪些文件描述符已经准备就绪:
		for(int i = 3; i < fd_max + 1 && 0 != ret; i++){...}
  • 十、判断文件描述符是否还在集合中,并且接收来自客户端的数据(recv函数)和给客户端发送应答消息(send函数):
            if(FD_ISSET(i,&read_fds_t)){//说明有新的客户端连接服务器if(i == sockfd){   if(-1 == (accept_fd = accept(sockfd,NULL,NULL))){perror("accept error");exit(-1);}printf("客户端[%d]连接到服务器\n",accept_fd);//将新连接的客户端的套接字添加到要监视的集合中FD_SET(accept_fd,&read_fds);fd_max = fd_max > accept_fd ? fd_max : accept_fd;}else //之前连接的客户端在向服务器发送信息{memset(buf,0,sizeof(buf));if(-1 == (nbytes = recv(i,buf,sizeof(buf),0))){perror("recv error");exit(-1);}else if(0 == nbytes){printf("客户端[%d]已断开连接\n",i);//将已断开连接客户端的套接字在文件描述符集合中剔除FD_CLR(i,&read_fds);//关闭套接字close(i);continue;}if(!strncmp(buf,"quit",4)){printf("客户端[%d]已退出\n",i);//将已断开连接客户端的套接字在文件描述符集合中剔除FD_CLR(i,&read_fds);//关闭套接字close(i);continue;}printf("客户端[%d]发来信息[%s]\n",i,buf);//组装应答消息strcat(buf,"----------k");//给客户端发送应答消息if(-1 == send(i,buf,sizeof(buf),0)){perror("send error");exit(-1);}}ret--; //减少遍历次数}
  • 十一、关闭套接字(close函数):
	close(sockfd);

http://www.ppmy.cn/news/1166809.html

相关文章

大数据测试用例分析

基于大数据分析&#xff0c;对业务系统产生的日志进行智能分析&#xff0c;能够识别日志中的接口、参数、业务流&#xff0c;并依据分析的结果生成测试用例。 问题与背景 业务复杂 业务系统的复杂性&#xff0c;对测试人员的业务能力提出严格要求&#xff0c;加重测试成本。 …

文件目录(文件控制块FCB,目录结构,索引结点)

1.文件控制块&#xff08;实现文件目录的关键数据结构) 目录文件中的一条记录就是文件控制块&#xff08;FCB&#xff09; FCB的有序集合称为“文件目录”&#xff0c;一个FCB就是一个文件目录项。 1.FCB的组成 FCB中包含了文件的基本信息&#xff08;文件名、物理地址、逻…

交换机控制在同一个网段内的终端,用hybrid接口实现不同的IP通和不通。

实验效果&#xff1a;pc1和pc2不能通&#xff0c;但pc1和pc2分别可以和pc3通。 通过这个实验可以彻底掌握数据包在交换机上的进去的类型状态。 sw1配置&#xff1a; [sw1]dis current-configuration sysname sw1 vlan batch 10 20 100 interface GigabitEthernet0/0/1 port h…

字节面试题——计算机网络,附答案

1.TCP 三次握手和四次挥手 相关面试题&#xff1a; 计算机网络常见面试题总结(上) | JavaGuide(Java面试 学习指南) 为什么要三次握手?第 2 次握手传回了 ACK&#xff0c;为什么还要传回 SYN&#xff1f;为什么要四次挥手&#xff1f;为什么不能把服务器发送的 ACK 和 FIN…

RHCE---搭建博客网站

一.实验要求&#xff1a; Server-NFS-DNS主机配置NFS服务器&#xff0c;将博客网站资源文件共享给Server-web主机&#xff0c;Server-NFS-DNS主机配置DNS Server-web主机配置web服务&#xff0c;通过域名www.openlab.com可以访问到自建的博客网站 二.准备工作 创建两台虚拟机…

c++_learning-对象模型探索

c对象模型探索 深入理解面向对象&#xff1a;c类对象模型&#xff1a;类中的成员&#xff1a;对象的内存大小&#xff1a;类对象内存的组成&#xff1a;不在对象内存中存放的成员&#xff1a; 类与类对象的内存分配&#xff1a;数据部分和代码部分&#xff1a;类对象占用的内存…

安装.net framework报错“...扩展属性不一致”

Windows操作系统中安装.net framework4.8&#xff0c;双击安装文件直接报错“…扩展属性不一致”&#xff0c;最初以为是操作系统补丁没有装全或者是没有管理员权限造成的&#xff0c;但是打了几个补丁&#xff0c;同时以管理员身份运行安装文件后&#xff0c;依然报同样的错误…

【力扣周赛】第 367 场周赛(⭐二维数组当成一维数组,前后缀分解)

文章目录 竞赛链接Q1&#xff1a;100096. 找出满足差值条件的下标 I竞赛时代码——暴力双循环 Q2&#xff1a;100084. 最短且字典序最小的美丽子字符串竞赛时代码——双指针 Q3&#xff1a;100101. 找出满足差值条件的下标 II竞赛时代码——记录可用最大最小值下标 Q4&#xff…