IO多分复用

#include<myhead.h>
#define SER_PORT 8888           //服务器端口号
#define SER_IP "192.168.65.131"  //服务器IPint main(int argc, const char *argv[])
{//1、创建一个套接字int sfd = -1;sfd = socket(AF_INET, SOCK_STREAM, 0);    //参数1:表示创建的是网络通信的套接字//参数2:表示使用的是TCP通信协议//参数3:参数2指定了协议,参数3填0即可if(sfd == -1){perror("socket error");return -1;}printf("%d success sfd = %d\n", __LINE__, sfd);   //3//设置端口号快速重用int reuse = 1;if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) ==-1){perror("setsockopt error");return -1;}printf("端口号快速重用成功\n");//2、绑定IP地址和端口号//2.1填充地址信息结构体struct sockaddr_in sin;sin.sin_family = AF_INET;      //地址族sin.sin_port = htons(SER_PORT);       //端口号sin.sin_addr.s_addr = inet_addr(SER_IP);    //IP地址//2.2 绑定if(bind(sfd, (struct sockaddr *)&sin, sizeof(sin)) ==-1){perror("bind error");return -1;}printf("%d  bind success\n", __LINE__);//3、将套接字设置成被动监听状态if(listen(sfd, 128) == -1){perror("listen error");return -1;}printf("%d  listen success\n", __LINE__);//4、阻塞等待客户端的链接请求int newfd = -1;//定义结构体变量接收对方地址信息结构体struct sockaddr_in cin; //用于接收客户端地址信息结构体socklen_t addrlen = sizeof(cin);  //用于接收客户端结构体的大小char sbuf[128] = "";   //服务器输入数据内容//11、定义一个文件描述符集合fd_set readfds,tempfds;//22、将集合清空FD_ZERO(&readfds);//33、将要被检测的文件描述符放入集合FD_SET(0, &readfds);FD_SET(sfd, &readfds);int maxfd = sfd; //记录容器中的最大文件描述符struct sockaddr_in cin_arr[1024];  //存储客户端地址信息结构体的数组while(1){tempfds = readfds;int 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, &tempfds)){continue;}//判断sfd是否触发事件//程序运行至此代表i文件描述符触发了事件if(i == sfd){if((newfd = accept(sfd, (struct sockaddr*)&cin, &addrlen)) == -1){perror("accept error");return -1;}printf("[%s  %d]:发来连接请求\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port));//将客户端地址信息结构体放入数组容器中cin_arr[newfd] = cin;//将newfd放入容器中检测FD_SET(newfd,&readfds);//可能需要更新maxfdif(newfd > maxfd){maxfd = newfd;}   }//判断0号描述符是否为触发事件else if(0 == i){fgets(sbuf,sizeof(sbuf),stdin);sbuf[strlen(sbuf)-1] = 0;printf("触发了键盘输入事件:%s\n",sbuf);//将消息发送给所有客户端for(int i=4;i<=maxfd;i++){send(i,sbuf,sizeof(sbuf),0);}printf("发送成功\n");}else{//说明有客户端发来消息了,遍历所有客户端,看是哪一个发来的消息//5收发数据char rbuf[128] = "";       //用于接收客户发发来的数据//将容器清空bzero(rbuf, sizeof(rbuf));     //memset(rbuf, 0, sizeof(rbuf));//从套接字中读取数据‘int res = recv(i, rbuf, sizeof(rbuf)-1, 0);   if(res == 0){printf("客户端已经下线\n");//关闭套接字close(i);//将当前文件描述符移除容器FD_CLR(i,&readfds);//可能需要更新maxfdfor(int k=maxfd;k>=sfd;k--){if(FD_ISSET(k,&readfds)){maxfd = k;break;}}continue;}printf("[%s  %d]: %s\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), rbuf);//加个笑脸再回回去strcat(rbuf,"*_*");send(newfd, rbuf, strlen(rbuf), 0);printf("发送成功\n");}}}//6、关闭服务器close(sfd);return 0;
}
#include<myhead.h>
#define SER_PORT 8888
#define SER_IP "192.168.117.74"
#define CLI_PORT 9999
#define CLI_IP "192.168.117.74"int main(int argc, const char *argv[])
{//1、创建用于连接的客户端套接字int cfd = socket(AF_INET, SOCK_STREAM, 0);if(cfd == -1){perror("socket error");return -1;}printf("socket success cfd = %d\n", cfd);        //3//设置端口号快速重用int reuse = 1;if(setsockopt(cfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) ==-1){perror("setsockopt error");return -1;}printf("端口号快速重用成功\n");//2、绑定端口号和ip地址(非必须)//2.1 填充客户端地址信息结构体struct sockaddr_in cin;cin.sin_family = AF_INET;cin.sin_port = htons(CLI_PORT);cin.sin_addr.s_addr = inet_addr(CLI_IP);//2.2 绑定端口号和IPif(bind(cfd, (struct sockaddr*)&cin, sizeof(cin)) == -1){perror("bind error");return -1;}printf("bind success\n");//3、连接服务器//3.1 填充要连接服务器的地址信息结构体struct sockaddr_in sin;sin.sin_family = AF_INET;      //地址族sin.sin_port = htons(SER_PORT);   //服务器端口号sin.sin_addr.s_addr = inet_addr(SER_IP);    //服务器的IP地址//3.2 连接服务器if(connect(cfd, (struct sockaddr*)&sin, sizeof(sin)) == -1){perror("connect error");return -1;}printf("连接成功!\n");//使用poll完成0号文件描述符和cfd文件描述符的多路复用//11、准备文件描述符容器struct pollfd pfds[2];pfds[0].fd = 0; //文件描述符pfds[0].events = POLLIN;    //检测读事件pfds[1].fd = cfd;       //文件描述符pfds[1].events = POLLIN;    //检测读事件//4、收发数据char wbuf[128] = "";while(1){int res = poll(pfds, 2, -1);        //阻塞检测集合中是否有事件产生if(res == -1){perror("poll error");return -1;}else if(res == 0){printf("time out\n");return -1;}//程序执行至此,说明检测的文件描述符集合中有事件产生//判断是否为0号文件描述符产生事件if(pfds[0].revents == POLLIN){fgets(wbuf, sizeof(wbuf), stdin);    //从终端上获取一个字符串wbuf[strlen(wbuf)-1] = '\0';      //将换行换成 '\0'//判断输入的字符串值if(strcmp(wbuf, "quit") ==0){break;}//将数据发送给服务器send(cfd, wbuf, strlen(wbuf), 0);}//判断释放为cfd文件描述符中产生事件if(pfds[1].revents == POLLIN){//将字符数组清空bzero(wbuf, sizeof(wbuf));recv(cfd, wbuf, sizeof(wbuf)-1, 0);printf("收到服务器消息为:%s\n", wbuf);}}//5、关闭套接字close(cfd);return 0;
}

模拟面试总结:

TCP通信中的三次握手和四次挥手?
三次握手:服务器向客户端发送连接请求-->客户端回应服务器的连接请求-->二者建立联系成功
四次挥手:服务器向客户端发送断开连接请求-->客户端回应服务器的断开请求,回应知道要断开链接了 -->客户端向服务器发送断开连接请求-->断开连接成功
并发和并行的区别?
并发:单核CPU中多个任务交叉执行是并发。
并行:多核CPU同时处理多个任务称为并行。
阻塞IO和非阻塞IO的区别?
阻塞IO会等待阻塞事件的产生,如果没有发生会一直阻塞后面函数的执行 。
非阻塞IO如果没有等到事件发生,会立刻返回 ,执行后续的任务。
同步和异步的区别?
同步表示任务有顺序的执行,而异步表示任务没有顺序的执行。
广播的相关内容?
一对多UDP的通信方式实现,广播地址为网络号+255的主机号,发送端类似与UDP的客户端,接收端类似于UDP的服务器端。
组播的相关内容?
D类网络地址,需要对接收端加入多播组属性,发送端类似与UDP的客户端,接收端类似于UDP的服务器端,同样也是使用一对多的UDP通信。
在使用套接字通信时,客户端一定不需要绑定操作吗?
不一定。如果不绑定套接字,系统不会自动绑定IP地址和端口号,服务器无法向客户端发送消息。
目前进程间的通信方式有哪些?
信号,信号灯集,共享内存,消息队列,套接字,有无名管道。
线程的同步互斥机制?
引入同步互斥机制是为了对临界区进行保护。
互斥机制:当多个线程拥有临界资源的临界区时,只要有一个线程在操作这个临界区,那么其他的线程均不可以拥有临界资源的临界区。

同步机制:通过互斥的手段安排好每一个线程的运行顺序,相当于有规律的互斥。

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

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

相关文章

北斗卫星引领农机春耕新时代

北斗卫星引领农机春耕新时代 随着现代科技的快速发展&#xff0c;北斗卫星成为了农业领域不可或缺的利器。在农机自动驾驶系统的引领下&#xff0c;农机正逐渐实现自主操作&#xff0c;为农民节省了大量的时间和精力&#xff0c;并最大限度地提高了农作物的产量和质量。 北斗…

30天拿下Rust之错误处理

概述 在软件开发领域&#xff0c;对错误的妥善处理是保证程序稳定性和健壮性的重要环节。Rust作为一种系统级编程语言&#xff0c;以其对内存安全和所有权的独特设计而著称&#xff0c;其错误处理机制同样体现了Rust的严谨与实用。在Rust中&#xff0c;错误处理通常分为两大类&…

词令微信小程序怎么添加到我的小程序?

微信小程序怎么添加到我的小程序&#xff1f; 1、找到并打开要添加的小程序&#xff1b; 2、打开小程序后&#xff0c;点击右上角的「…」 3、点击后底部弹窗更多选项&#xff0c;请找到并点击「添加到我的小程序」&#xff1b; 4、添加成功后&#xff0c;就可以在首页下拉我的…

迈入编程世界:C 语言初体验

写在前面&#xff1a;OK啊&#xff0c;前面我们介绍了C语言开发环境的搭建&#xff0c;今天我们再来初步的认识一下C语言&#xff0c;了解C语言的基础框架、数据的表现形式以及输入和输出。 文章特点&#xff1a;不会很正经&#xff0c;不会很学术&#xff0c;不会很理论&#…

J4G企业通讯ip电话 sip对讲主机 停车场对讲主机

J4G企业通讯ip电话 sip对讲主机 停车场对讲主机 SV-J4G 是一款企业级彩屏网络电话&#xff0c;具有高清语音&#xff0c;320x240 2.8英寸彩屏&#xff0c;支持千兆以太网&#xff0c;12个SIP账号&#xff0c;支持PoE供电&#xff0c;支持外接EHS无线耳机&#xff0c;三方电话会…

C++有关内存的那些事

个人主页&#xff1a;PingdiGuo_guo 收录转栏&#xff1a;C干货专栏 前言 本篇博客是讲解关于C内存的一些知识点的。 文章目录 前言 1.内存函数 1.1memcpy函数 1.2memmove函数 1.3 memset函数 2.各数据类型占用 2.1bool类型 2.2char类型 2.3short、int、long类型及整数…

京东商品信息采集API商品价格商品详情图主图抓取接口key(提供测试入口)

item_get 获得JD商品详情item_search 按关键字搜索商品item_search_img 按图搜索京东商品&#xff08;拍立淘&#xff09;item_search_shop 获得店铺的所有商品item_history_price 获取商品历史价格信息item_recommend 获取推荐商品列表buyer_order_list 获取购买到的商品订单列…

CMake笔记之GLOB和GLOB_RECURSE的使用方法

CMake笔记之GLOB和GLOB_RECURSE的使用方法 —— 杭州 2024-03-19 夜 文章目录 CMake笔记之GLOB和GLOB_RECURSE的使用方法1.GLOB使用方法2.GLOB对比GLOB_RECURSE 1.GLOB使用方法 在 CMake 中&#xff0c;file(GLOB ...) 命令用于将匹配特定模式的文件列表赋值给变量。这可以用…

MySQL中replace into详解、批量更新、不存在插入存在则更新、replace into的坑

文章目录 一、replace into原理二、replace into的三种形式三、replace into 使用案例3.1、replace into values3.1.1、只有主键且主键冲突3.1.2、有主键有唯一索引且主键冲突3.1.3、有主键有唯一索引且唯一索引冲突(有坑)3.1.4、有主键有唯一索引且与一条主键冲突与另一条唯一…

瑞_Redis_短信登录_基于Session实现登录流程

文章目录 项目介绍1 短信登录1.1 项目准备1.2 基于Session实现登录流程1.2.1 功能流程介绍1.2.1.1 发送短信验证码1.2.1.2 短信验证码登录、注册1.2.1.3 校验登录状态 1.2.2 实现发送短信验证码功能1.2.2.1 页面流程1.2.2.2 代码实现1.2.2.3 测试 1.2.3 实现短信验证码登录、注…

2024年蓝牙耳机哪个好?真人实测告诉你如何选购,避免后悔!

在繁忙的通勤途中&#xff0c;无线蓝牙耳机已成为我们摆脱线缆束缚、享受音乐的理想选择。面对众多品牌和型号&#xff0c;选择合适的耳机似乎并不简单。因此&#xff0c;我精心挑选了几款表现不错的蓝牙耳机&#xff0c;希望我的分享能为你提供有价值的参考。 一、如何挑选蓝牙…

搭建EMQX MQTT服务器(超详细)

MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;服务器是一种实现 MQTT 协议的服务器软件。MQTT 是一种轻量级的、发布/订阅模式的消息传输协议&#xff0c;通常用于物联网&#xff08;IoT&#xff09;应用中的设备通信。MQTT 服务器负责接收来自客户端的消息…

Java_13 反转字符串中的单词 III(方法一将String改为StringBuilder)

一、反转字符串中的单词 III 给定一个字符串 s &#xff0c;你需要反转字符串中每个单词的字符顺序&#xff0c;同时仍保留空格和单词的初始顺序。 示例 1&#xff1a; 输入&#xff1a;s "Lets take LeetCode contest" 输出&#xff1a;"steL ekat edoCteeL …

数据之谜:解读Facebook的用户行为

在当今数字化时代&#xff0c;社交媒体平台已经成为人们生活中不可或缺的一部分&#xff0c;而Facebook作为全球最大的社交网络之一&#xff0c;其背后隐藏着许多数据之谜。本文将深入探讨Facebook的用户行为&#xff0c;并试图解读其中的奥秘。 用户行为数据的收集 Facebook作…

在Arm 虚拟硬件(AVH)部署深度学习OCR算法

AI算法的嵌入式部署 AI算法在独立的设备上运行其实就是行业内的嵌入式AI的概念, 大致过程如下: 开发AI模型, 2.对数据集进行处理, 3.训练AI模型并验证效果, 4.转成ONNX格式(ONNX:万金油中间格式,给模型优化和部署带来了更多可能性)或者借助libtorch或者TensorFlow来部署C++版…

CSS学习(3)-浮动和定位

一、浮动 1. 元素浮动后的特点 脱离文档流。不管浮动前是什么元素&#xff0c;浮动后&#xff1a;默认宽与高都是被内容撑开&#xff08;尽可能小&#xff09;&#xff0c;而且可以设置宽 高。不会独占一行&#xff0c;可以与其他元素共用一行。不会 margin 合并&#xff0c;…

json字符串的数据提取

json的数据提取 学习目标 掌握 json相关的方法(load loads dump dumps)了解 jsonpath的使用(提取 json中的数据) 2 复习什么是json JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式&#xff0c;它使得人们很容易的进行阅读和编写。同时也方便了机器进行解析和…

【LeetCode: 173. 二叉搜索树迭代器 + dfs + 二叉搜索树】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

docker入门(五)—— 小练习,docker安装nginx、elasticsearch

练习 docker 安装 nginx # 搜素镜像 [rootiZbp15293q8kgzhur7n6kvZ home]# docker search nginx NAME DESCRIPTION STARS OFFICIAL nginx …

SpringBoot中使用验证码easy-captcha

easy-captcha使用的大概逻辑: 当一个请求发送到后端服务器请求验证,服务器使用easy-captcha生成一个验证码图片,并通过session将验证信息保存在服务器,当用户登录校验时候,会从ession中取出对比是否一致 但是前后端分离之后 由于跨域问题 以上就无法实现了 下面这种情况没…