10.1 国庆节小任务

目录

select实现服务器并发

服务器

客户端

运行现象


select实现服务器并发

服务器

#include<myhead.h>#define PORT 8888             //1024~49151
#define IP "192.168.1.104" //ifconfig查看本机IPint main(int argc, const char *argv[])
{//创建流式套接字int sfd = socket(AF_INET, SOCK_STREAM, 0);if(sfd < 0){ERR_MSG("socket");return -1;}printf("sfd = %d\n", sfd);//设置允许端口被快速复用int reuse = 1;if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0){ERR_MSG("setsockopt");return -1;}printf("允许端口快速重用成功\n");//填充地址信息结构体,真实的地址信息结构体根据地址族指定//AF_INET: man 7 ipstruct sockaddr_in sin;sin.sin_family      = AF_INET;      //必须填AF_INETsin.sin_port        = htons(PORT);  //端口号:1024~49151sin.sin_addr.s_addr = inet_addr(IP); //本机IP ifconfig查看//绑定服务器的IP和端口--->必须绑定if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0){ERR_MSG("bind");return -1;}printf("bind success \n");//将套接字设置为被动监听状态if(listen(sfd, 128) < 0){ERR_MSG("listen");return -1;}printf("listen success\n");//创建一个读集合fd_set readfds, tempfds;//fd_set本质上是一个结构体,成员是一个long类型数组,//集合目的是为了存储让内核监测的文件描述符,若不初始化,//则有可能随机到有效的但不需要监测的文件描述符,//所以需要将集合初始化成无意义的文件描述符FD_ZERO(&readfds);FD_ZERO(&tempfds);//将需要的文件描述符添加到读集合中FD_SET(0, &readfds);FD_SET(sfd, &readfds);int maxfd = sfd;int s_res = -1;int newfd = -1;char buf[128] = "";ssize_t res = 0;struct sockaddr_in cin;     //存储客户端的地址信息socklen_t addrlen = sizeof(cin);struct sockaddr_in saveCin[1024-3];while(1){tempfds = readfds;//调用IO多路复用函数 select()s_res = select(maxfd+1, &tempfds, NULL, NULL, NULL);if(s_res < 0){ERR_MSG("select");return -1;}else if(0 == s_res){printf("time out...\n");break;}//printf("__%d__\n", __LINE__);//能运行到当前位置,则代表集合中有文件描述符准备就绪。//此时集合中会只剩下触发事件的文件描述符//例如://当0号文件描述符触发事件,则集合中只剩下0//当sfd文件描述符触发事件,则集合中只剩下sfd//若0和sfd同时触发事件,则集合中剩下0和sfd //判断是哪个文件描述符准备就绪,走对应处理函数即可//判断集合中剩下哪个文件描述符,就代表哪个文件描述符准备就绪for(int i=0; i<=maxfd; i++){if(FD_ISSET(i, &tempfds) == 0)  //若i所代表的文件描述符不在集合中continue;                   //则继续遍历下一个i//能运行到当前位置,说明i所代表的文件描述符在集合中//判断i所代表的文件描述符触发的事件是什么事件if(0 == i){printf("触发键盘输入事件\n");int sndfd = -1;res = scanf("%d %s", &sndfd,buf);   //返回值:成功获取到的数据个数while(getchar() != 10);if(res != 2){printf("请输入正确的格式: fd string\n");continue;}//能运行到当前位置,则代表输入的格式正确if(sndfd<3 || !FD_ISSET(sndfd, &readfds)){printf("sndfd=%d 文件描述符错误\n", sndfd);continue;}if(send(sndfd, buf, sizeof(buf), 0) < 0){ERR_MSG("send");return -1;}printf("send success\n");}else if(sfd == i){printf("触发客户端连接事件\n");newfd = accept(sfd, (struct sockaddr*)&cin, &addrlen);if(newfd < 0){ERR_MSG("accept");return -1;}printf("[%s : %d] newfd=%d 客户端连接成功\n", \inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), newfd);saveCin[newfd-3] = cin;//将newfd添加到集合中FD_SET(newfd, &readfds);//更新maxfdmaxfd = maxfd>newfd ? maxfd:newfd;}else{printf("触发客户端交互事件\n");bzero(buf, sizeof(buf));//接收数据res = recv(i, buf, sizeof(buf), 0);if(res < 0){ERR_MSG("recv");return -1;}else if(0 == res){printf("[%s : %d] newfd=%d 客户端下线\n", \inet_ntoa(saveCin[i-3].sin_addr), ntohs(saveCin[i-3].sin_port), i);//关闭下线客户端的文件描述符close(i);//将下线客户端的文件描述符从集合中剔除FD_CLR(i, &readfds);//更新maxfd //从大往小判断--->从目前记录的最大fd开始判断是否在集合中//若存在,则该文件描述符就是最大的,//若不存在,则继续往小判断while(FD_ISSET(maxfd, &readfds)==0 && maxfd-->=0);/*int j = maxfd;for(; j>=0; j--){if(FD_ISSET(j, &readfds))break;}maxfd = j;*/continue;}printf("[%s : %d] newfd=%d : %s\n", \inet_ntoa(saveCin[i-3].sin_addr), ntohs(saveCin[i-3].sin_port), i, buf);//发送数据strcat(buf, "*_*");if(send(i, buf, sizeof(buf), 0) < 0){ERR_MSG("send");return -1;}printf("send success\n");}}} //关闭所有文件描述符close(sfd);return 0;
}

客户端

#include <myhead.h>#define PORT 8888             //1024~49151
#define IP "192.168.1.104"int main(int argc, const char *argv[])
{//创建流失套接字int cfd=socket(AF_INET,SOCK_STREAM,0);if(cfd<0){ERR_MSG("socket");return -1;}//填充服务器的ip地址信息结构体struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(PORT);sin.sin_addr.s_addr=inet_addr(IP);//连接服务器if(connect(cfd,(struct sockaddr*)&sin,sizeof(sin))<0){ERR_MSG("connect");return -1;}printf("连接服务器成功\n");char buf[128];//与服务器交互while(1){bzero(buf,sizeof(buf));fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1]='\0';if(send(cfd,buf,sizeof(buf),0)<0){ERR_MSG("send");return -1;}if(0==strlen(buf)){break;}printf("向服务器发送消息成功\n");bzero(buf,sizeof(buf));if(recv(cfd,buf,sizeof(buf),0)<0){ERR_MSG("recv");return -1;}printf("服务器:%s\n",buf);}//关闭客户端close(cfd);return 0;
}

运行现象

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/91899.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

本次CTF·泰山杯网络安全的基础知识部分(二)

简记23年九月参加的泰山杯网络安全的部分基础知识的题目&#xff0c;随时补充 15&#xff08;多选&#xff09;网络安全管理工作必须坚持“谁主管、谁负责&#xff0c;谁运营、谁负责&#xff0c;谁使用、谁负责”的原则&#xff0c;和“属地管理”的原则 谁主管、谁负责&…

WiFi网络分析工具Airtool for Mac

Airtool是一款Mac平台上的WiFi网络分析工具&#xff0c;它可以帮助用户监测、分析和管理无线网络。 以下是Airtool的一些主要功能和特点&#xff1a; 实时监测&#xff1a;Airtool可以实时监测当前Mac设备所连接的WiFi网络&#xff0c;包括网络速度、信号强度、连接状态等。信…

Greenplum 对比 Hadoop

Greenplum属于MPP架构&#xff0c;和Hadoop一样都是为了解决大规模数据的并行计算而出现的技术&#xff0c;两者的相似点在于&#xff1a; 分布式存储&#xff0c;数据分布在多个节点服务器上分布式并行计算框架支持横向扩展来提高整体的计算能力和存储容量都支持X86开放集群架…

8、表格标签

8、表格标签 一、为什么使用表格 简单通用结构稳定 二、基本结构 &#xff08;一&#xff09;单元格 &#xff08;二&#xff09;行 行的英语是rows所以&#xff0c;行就用tr表示 &#xff08;三&#xff09;列 使用td表示 &#xff08;四&#xff09;跨行 &#xff…

蓝桥等考Python组别九级002

第一部分:选择题 1、Python L9 (15分) 运行下面程序,可以输出几行“*”?( ) for i in range(5): for j in range(6): print(*, end = ) print() 3456正确答案:C 2、Python L

Spark SQL

Spark SQL 一、Spark SQL概述二、准备Spark SQL的编程环境三、Spark SQL程序编程的入口四、DataFrame的创建五、DataFrame的编程风格六、DataSet的创建和使用七、Spark SQL的函数操作 一、Spark SQL概述 Spark SQL属于Spark计算框架的一部分&#xff0c;是专门负责结构化数据的…

运算符 - Go语言从入门到实战

运算符 - Go语言从入门到实战 算术运算符 假设A变量等于10&#xff0c;B变量等于20。 运算符描述实例相加A B 输出结果 30-相减A - B 输出结果 -10*相乘A * B 输出结果 200/相除B / A 输出结果 2%求余B % A 输出结果 0⾃增A 输出结果 11–⾃减A-- 输出结果 9 特性&#xf…

NIO基础

nio : non-blocking io 非阻塞IO 1. 三大组件 1.1 channel和buffer channel 有点像stream &#xff0c;他就是读写数据的双向通道&#xff0c;可以从channel将数据读入buffer&#xff0c;也可以将buffer的数据写入channel&#xff0c;之前的stream 要么输入&#xff0c;要么…

建筑能源管理(3)——建筑能源监管

为了全面落实科学发展观&#xff0c;提高建筑能源管理水平&#xff0c;进一步降低能源和水资源消耗、合理利用资源&#xff0c;以政府办公建筑和大型公共建筑的运行节能管理为突破口&#xff0c;建立了既有政府办公建筑和大型公共建筑运行节能监管体系&#xff0c;旨在提高政府…

【bug 记录】yolov5_C_demo 部署在 rv1126

问题1&#xff1a;opencv find 不到 在 CMakeLists 中将正确的 OpenCV库 路径添加到 CMAKE_PREFIX_PATH 变量中 set(CMAKE_PREFIX_PATH “/mnt/usr/local” ${CMAKE_PREFIX_PATH}) 问题2&#xff1a; rknn_api.h 找不到 将该文件从别处复制到项目 include 文件夹 问题3&…

28271-2012 米制超细牙螺纹 公差

声明 本文是学习GB-T 28271-2012 米制超细牙螺纹 公差. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本标准规定了米制超细牙螺纹的公差和标记。 本标准适用于精密仪器和电子设备等领域的螺纹连接。 2 规范性引用文件 下列文件对于本文件…

windows server 2019 、win11安装docker desktop

Docker Desktop Docker Desktop是可以部署在windows运行docker的应用服务&#xff0c;其基于windos的Hyper-V服务和WSL2内核在windos上创建一个子系统(linux)&#xff0c;从而实现其在windows上运行docker。 前提条件 WSL 查看wsl是否安装 我们可以直接在 cmd 或 powershe…

vue3中的watch

在Vue3中&#xff0c;watch中的参数可以分为两部分&#xff0c;即要监听的响应式数据以及回调函数。 语法格式如下&#xff1a; watch(要监听的响应式数据, 回调函数)除了以上的两个还有其他的参数 immediate&#xff1a;是否在初始化时立即执行一次回调函数&#xff0c;默认…

MySql出错点

一、DDL 1.修改表&#xff0c;添加新的字段时&#xff0c;不要加引号 2.在修改表中字段的类型时&#xff0c;会发生数据截断。 像DATETIME 转化为 TIME 二、DML 1.插入和删除的注意点 2.可以通过 select 来协助插入 3.

Linux 基本语句_4_指针和函数

指针函数 顾名思义&#xff0c;即返回值为指针的函数 int * f (int n){int *p NULL;//空指针return p;//返回一个地址 }函数指针 指向函数的指针&#xff0c;每个函数都有自己的入口地址&#xff0c;函数指针专门指向这些地址#include <stdio.h>int max(int a, int b)…

【Linux】完美解决ubuntu18.04下vi不能使用方向键和退格键

今天在刚安装完ubuntu18.04&#xff0c;发现在使用vi命令配置文件时使用方向键并不能移动光标&#xff0c;而是出现一堆奇怪的英文字母&#xff0c;使用退格键也不能正常地删除内容&#xff0c;用惯了CentOS的我已经感觉到ubuntu没有centos用着丝滑&#xff0c;但是没办法&…

【C++】类和对象(中)

一、类的6个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。但是空类中并不是真的什么都没有&#xff0c;任何类在什么都不写的时候&#xff0c;编译器会自动生成以下 6 个默认成员函数。 默认成员函数&#xff1a;用户没有显式实现&#xff0c;编译器会生成…

5G消息发展的前景与挑战

随着5G技术的快速发展和普及&#xff0c;5G消息正逐渐成为全球通信领域的新焦点。 随着5G技术的快速发展和普及&#xff0c;5G消息正逐渐成为全球通信领域的新焦点。 5G消息发展呈现规模化、产业化趋势 自2020年4月国内三大运营商联合发布5G消息白皮书以来&#xff0c;已经过…

【C语言】通讯录系统实现 (保姆级教程,附源码)

目录 1、通讯录系统介绍 2、代码分装 3、代码实现步骤 3.1、制作菜单menu函数以及游戏运行逻辑流程 3.2、封装人的信息PeoInfo以及通讯录Contact结构体类型 3.3、初始化通讯录InitContact函数 3.4、增加联系人AddContact函数 3.5、显示所有联系人ShowContact函数 3.6、…

【Idea】idea、datagrip设置输入法

https://github.com/RikudouPatrickstar/JetBrainsRuntime-for-Linux-x64/releases/tag/jbr-release-17.0.6b829.5https://github.com/RikudouPatrickstar/JetBrainsRuntime-for-Linux-x64/releases/tag/jbr-release-17.0.6b829.5 下载后解压并重命名为 jbr, 然后替换对应 ide…