华清远见嵌入式学习——网络编程——作业4

作业要求:①使用IO多路复用中的select函数实现TCP并发服务器客户端

                  ②使用IO多路复用中的poll函数实现TCP并发服务器的服务器端

一、

代码

#include <myhead.h>#define SERPORT 8888              //服务器端口号
#define SERIP "192.168.114.113"       //服务器IP地址int main(int argc, const char *argv[])
{//创建用于通信的套接字int cfd = socket(AF_INET,SOCK_STREAM,0);if(cfd == -1){perror("socket error");return -1;}//连接服务器///填充服务器地址信息结构体struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(SERPORT);sin.sin_addr.s_addr = inet_addr(SERIP);///连接服务器if(connect(cfd,(struct sockaddr *)&sin,sizeof(sin)) == -1){perror("connect error");return -1;}//创建用于检测文件描述符的集合fd_set readfds,tempfds;//清空集合FD_ZERO(&readfds);//将要检测的文件描述符放入集合中FD_SET(cfd,&readfds);FD_SET(0,&readfds);int res = 0;    //接收select的返回值int maxfd = cfd;  //集合中值最大的文件描述符//向服务器进行数据的收发char buf[128] = "";int ret = 0;    //接收recv的返回值while(1){tempfds = readfds;res = select(maxfd+1,&tempfds,NULL,NULL,NULL);if(res == -1){perror("select error");return -1;}else if(res == 0){printf("time out\n");return -1;			}//遍历集合中所有的文件描述符for(int i = 0;i <= maxfd;i++){//判断当前文件描述符是否在集合中if(!FD_ISSET(i,&readfds)){continue;}//判断0号文件描述符是否还在集合中if(0 == i){//从标准输入中读取数据fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1] == 0;//将数据发送到服务器if(send(cfd,buf,sizeof(buf),0) == -1){perror("send error");return -1;}}else if(cfd == i)     //判断cfd是否还在集合中{//接收来自服务器的消息ret = recv(cfd,buf,sizeof(buf),0);if(ret == -1){perror("recv error");return -1;}else if(ret == 0){printf("服务器已关闭\n");return -1;}printf("服务器消息:%s\n",buf);}}}//关闭文件描述符close(cfd);return 0; 
}

效果图

二、

代码

#include <myhead.h>#define IP "192.168.114.118"
#define PORT 8888int main(int argc, const char *argv[])
{//创建用于连接的套接字int sfd = socket(AF_INET,SOCK_STREAM,0);if(sfd == -1){perror("socket error");return -1;}//设置端口号快速重用int reuse = 1;if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1){perror("setsockopt error");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(bind(sfd,(struct sockaddr *)&sin,sizeof(sin)) == -1){perror("bind error");return -1;}printf("bind success\n");//将连接用套接字设置为被动监听状态if(listen(sfd,128) == -1){perror("listen error");return -1;}printf("listen success\n");//定义一个集合管理sfd和打开的通信用文件描述符struct pollfd fds[1024];int maxfd = 0;//手动放入sfdfds[0].fd = sfd;fds[0].events = POLLIN;     //表明为读事件//将fds中其余元素初始化为-1for(int i = 4;i <= 1024;i++){fds[i].fd = -1;}//填充客户端地址信息结构体struct sockaddr_in cin;cin.sin_family = AF_INET;socklen_t socklen = sizeof(cin);char cbuf[128] = "";  //给客户端用的容器int nfd;int res = 0;  //接收poll返回的结果while(1){res = poll(fds,maxfd+1,-1);if(res == -1){perror("select");return -1;}else if(res == 0){continue;;}else if(res > 0)                //说明检测到了有文件描述符对应的缓冲区的数据发生了改变{if(fds[0].revents ==  POLLIN)    //表明有新的客户连接进来了{int nfd = accept(sfd,(struct sockaddr*)&cin,&socklen);  //阻塞在此处,直到有客户端连接上来if(nfd == -1)   //增加这些错误的判断非常重要,可以帮助找到出现问题的地方{perror("accept");return -1;}//将新的文件描述符加入到集合中for(int i = 1;i < 1024;i++){if( fds[i].fd == -1){fds[i].fd = nfd;fds[i].events = POLLIN;break;}}//更新最大的文件描述符if(nfd > maxfd){maxfd = nfd;}}for(int i = 1;i <= maxfd;i++)     //轮询客户端对应的文件描述符{if(fds[i].revents == POLLIN)  //说明此文件描述符对应的客户端发送来了数据{int ret = read(fds[i].fd,cbuf,sizeof(cbuf));if(ret == -1){perror("read");exit(-1);}else if(ret == 0){printf("client closed\n");close(fds[i].fd);   //关闭对应的文件描述符fds[i].fd = -1;   //在fds中清空对应的文件描述符}else if(ret > 0){printf("read buf = %s\n",cbuf);write(fds[i].fd,cbuf,strlen(cbuf)+1);}}}}}//关闭所有套接字close(sfd);return 0;}

效果图

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

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

相关文章

Samsung下origen中uboot的配置与编译

uboot的特点&#xff1a; n代码结构清晰 n 支持丰富的处理器与开发板&#xff0c;易于移植 n 支持丰富的用户命令 n 支持丰富的网络协议 n 支持丰富的文件系统 n 支持丰富的设备驱动 n 更新活跃、用户较多、资料丰富 n 开放源代码 n 较高的稳定性 n 不具有通用性&#xff08;不…

JavaScript编程基础 – 布尔值(Booleans)

JavaScript编程基础 – 布尔值(Booleans) Javascript Programming Essentials – Booleans 一个JavaScript布尔值包含两个值中的一个&#xff0c;即 true 或者 false。 本文简要介绍JavaScript布尔值的具体应用&#xff0c;以及可能作为对象的布尔值等。 1. 布尔值(Booleans)…

Go语言超全详解(入门级)

文章目录 1. Go语言的出现2. go版本的hello world3. 数据类型3.0 定义变量3.0.1 如果变量没有初始化3.0.2 如果变量没有指定类型3.0.3 :符号3.0.4 多变量声明3.0.5 匿名变量3.0.6 变量作用域 3.1 基本类型3.2 指针3.2.1 指针声明和初始化3.2.2 空指针 3.3 数组3.3.1 声明数组3.…

java+mysql的校园兼职微信小程序(附源码 调试 文档)

校园兼职微信小程序 摘要一、引言二、国内外研究现状三、系统设计四、系统实现与界面展示五、源码获取 摘要 本文详述了一个基于Java和MySQL数据库技术的校园兼职微信小程序的毕业设计。系统主要分为三种用户角色&#xff1a;管理员、学生用户和商家用户。管理员拥有学生管理、…

jjwt使用说明-笔记

jjwt官网链接&#xff1a;https://github.com/jwtk/jjwt POM 依赖 <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId><version>0.12.3</version> </dependency> <dependency><grou…

华纳云:linux中vsz和rss有哪些区别

在Linux中&#xff0c;VSZ(Virtual Set Size)和RSS(Resident Set Size)是两个用于描述进程内存使用的指标&#xff0c;它们表示不同方面的内存情况。 1. VSZ&#xff08;Virtual Set Size&#xff09;: VSZ 表示进程的虚拟内存大小。 包括进程使用的所有内存&#xff0c;包括实…

Python中的函数

一、函数参数与返回值基础知识 1、不要使用可变类型&#xff08;list等&#xff09;作为参数默认值&#xff0c;用None来代替。 参数默认值只会在函数定义阶段被创建一次&#xff0c;之后无论创建多少次&#xff0c;函数内拿到的默认值都是同一个对象&#xff0c;为规避这个问…

Vue 2.0源码分析-数据驱动

Vue.js 一个核心思想是数据驱动。所谓数据驱动&#xff0c;是指视图是由数据驱动生成的&#xff0c;我们对视图的修改&#xff0c;不会直接操作 DOM&#xff0c;而是通过修改数据。它相比我们传统的前端开发&#xff0c;如使用 jQuery 等前端库直接修改 DOM&#xff0c;大大简化…

【python学习】基础篇-常用模块-collections模块:数据结构,如列表、元组、字典和集合等

Python中的collections模块提供了一些有用的数据结构&#xff0c;如列表、元组、字典和集合等。 以下是collections模块中一些常用数据结构的用法&#xff1a; Counter类 Counter类是一个字典子类&#xff0c;用于计数可哈希对象。 它可以接受一个可迭代对象作为参数&#xff…

Atlassian Confluence 路径遍历和命令执行漏洞 (CVE-2019-3396)

漏洞描述 Confluence 是由澳大利亚软件公司 Atlassian 开发的基于 Web 的企业 wiki。 Atlassian Confluence 6.14.2 版本之前存在一个未经授权的目录遍历漏洞&#xff0c;攻击者可以使用 Velocity 模板注入读取任意文件或执行任意命令。 漏洞环境及漏洞利用 启动docker环境…

快来考试拿证书!KubeSphere 个人技能专业考试认证上线啦!

以容器技术和容器编排为基础的云原生应用&#xff0c;被越来越多的企业用户接受和使用&#xff0c;并且在生产环境中使用容器技术的比例逐年增加。Kubernetes 无疑已经成为容器编排的事实基础&#xff0c;而依托于 Kubernetes 开发的开源容器平台 KubeSphere 也收获了一众拥趸。…

vue3使用provider+ inject直接将参数由祖宗传送给孙子

如题。在vue项目中&#xff0c;如果祖宗想将参数传递给孙子甚至更小一辈的组件&#xff0c;是一件麻烦事。可以通过爷爷-儿子-孙子-曾孙这样的链条&#xff0c;一辈辈地传承下去&#xff0c;但未免太繁琐、太蠢了些&#xff1b;也可以通过store间接传送&#xff0c;但如何触发孙…

9-什么是迭代器,生成器,装饰器、django的信号用过吗?如何用,干过什么、什么是深拷贝,什么是浅拷贝,如何使用、slice操作符和list构造函数

1 什么是迭代器&#xff0c;生成器&#xff0c;装饰器 2 django的信号用过吗&#xff1f;如何用&#xff0c;干过什么 3 什么是深拷贝&#xff0c;什么是浅拷贝&#xff0c;如何使用 3.1 浅拷贝 3.2 深拷贝 3.3 扩展(slice操作符和list构造函数) 1 什么是迭代器&#xff0c;生成…

14 redis全量复制与部分复制

1、设置主服务器的地址和端口 首先是在从服务器设置需要同步的主服务器信息&#xff0c;包括机器IP, 端口。 主从复制的开启&#xff0c;完全是在从节点发起的。不需要我们在主节点做任何事情。 从节点开启主从复制&#xff0c;有3种方式 配置文件&#xff1a;在从服务器的配…

【神印王座】龙皓晨美妆胜过月夜,魔神皇识破无视,撮合月夜阿宝

Hello,小伙伴们&#xff0c;我是拾荒君。 《神印王座》国漫第82集已更新&#xff0c;拾荒君和大多数人一样&#xff0c;更新就去看了。魔神皇枫秀&#xff0c;威严凛然&#xff0c;突然空降月魔宫&#xff0c;整个宫殿都在这股无与伦比的强大气息中颤栗。为了顺利躲避魔神皇的…

稻谷飘香金融助力——建行江门市分行助力乡村振兴

7月的台山&#xff0c;稻谷飘香。在大耕户李胜业的农田里&#xff0c;金灿灿的稻谷翻起层层稻浪&#xff0c;收割机在稻浪里来回穿梭&#xff0c;割稻、脱粒、装车等工序一气呵成。空气中弥漫着丰收的喜悦。 夏粮迎丰收的背后&#xff0c;是中国建设银行江门市分行&#xff08…

远端WWW服务支持TRACE请求

安全扫描的时候&#xff0c;扫出来的问题&#xff0c;这里不分享如何处理&#xff0c;就只分享下&#xff0c;如何找到有问题的端口。 通过命令 curl -v -X TRACE -I ip:port&#xff0c;这里的ip和端口就是扫描出有问题的服务器地址ip以及开放的服务端口。 观察返回值&#x…

Python基础:生成器(Generators)和生成器表达式(Generator Expressions)详解

生成器&#xff08;Generators&#xff09;和 生成器表达式&#xff08;Generator Expressions&#xff09;是 Python 中用于处理迭代器和序列数据的强大工具。它们允许你按需生成值&#xff0c;而不是一次性生成所有值&#xff0c;从而节省内存和提高性能。 1. 生成器&#x…

深度强化学习笔记与无线通信应用案例

这里写自定义目录标题 参考资料比较和分类基础知识16.3 有模型学习16.3.1 策略评估递归形式&#xff1a;Bellman 等式 16.3.2 策略改进16.3.3 策略迭代16.3.3 值迭代 16.4 免模型学习on-policy off-policy16.4.1 蒙特卡罗强化学习16.4.2 时序差分学习Sarsa算法&#xff1a;同策…

睡前随笔记录

一个人从出生到长大&#xff0c;就像一部手机从新用到旧。手机里面积累了太多的缓存&#xff0c;积累了太多的照片&#xff0c;各种app的数据&#xff0c;安装了各式各样的程序。 所以大概这就是年纪越大&#xff0c;记性越差的原因吗&#xff1f;就像一个屋子&#xff0c;堆满…