网络编程(8.15)io模型,IO多路复用(select,poll)

1.使用select函数实现IO多路复用

使用select函数实现IO多路复用的服务器:

#include<stdio.h>
#include<head.h>
#include<netinet/in.h>
#include<sys/select.h>
#include<arpa/inet.h>
#define PROT 1112
#define IP "192.168.125.232"
int 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");//绑定服务器的IP和端口--->必须绑定struct sockaddr_in sin;sin.sin_family      = AF_INET;//必须填AF_INETsin.sin_port        = htons(PROT);//端口号:1024~49151sin.sin_addr.s_addr = inet_addr(IP);//本机IPif(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))<0){   ERR_MSG("bind");return -1; }   printf("绑定成功\n");//将套接字设置为被动监听状态if(listen(sfd,128)<0){   ERR_MSG("listen");return -1; }   printf("被动监听状态设置成功\n");//创建一个读集合fd_set readfds,tempfds;//fd_set本质是一个结构体,成员是一个long类型的数组//集合目的是为了存储让内核监测的文件描述符,不初始化有可能随机到有效的但不需要监测的文件描述符//需要将集合初始化为无意义的文件描述符FD_ZERO(&readfds);FD_ZERO(&tempfds);//将需要的文件描述符添加到读集合中FD_SET(0,&readfds);FD_SET(sfd,&readfds);int s_res=-1;int nfd=-1;int maxfd=sfd;char buf[128]="";ssize_t res=0;struct sockaddr_in cin;//存储客户端地址信息socklen_t addrlen = sizeof(cin);struct sockaddr_in saveCin[1024];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("timeout...\n");break;}printf("__%d__\n",__LINE__);//能运行到当前位置,代表集合中有文件描述符准备就绪//此时集合中路会只剩下触发事件的文件描述符//例如://当0号文件描述符触发事件,则集合中只剩下0//当sfd文件描述符触发事件,则集合中只剩下sfd//当0和sfd同时触发,集合中剩下0和sfd//判断哪个文件描述符准备就绪,走对应处理函数//判断集合中剩下哪个文件描述符,代表哪个文件描述符准备就绪//判断nfd是否在集合中,若不在集合中则走recv函数for(int i=0;i<=maxfd;i++){if(FD_ISSET(i,&tempfds)==0)//判断i是否在集合中,不在进入下一个循环continue;if(0 == i){printf("触发键盘输入事件\n");fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1]=0;printf(": %s\n",buf);}else if(sfd == i){printf("触发客户端连接事件\n");nfd=accept(sfd,(struct sockaddr*)&cin,&addrlen);if(nfd<0){ERR_MSG("accept");return -1; }printf("[%s:%d]nfd=%d,客户端连接成功\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),nfd);saveCin[nfd]=cin;//将nfd添加到集合中FD_SET(nfd,&readfds);//更新maxfdmaxfd = maxfd>nfd ? maxfd : nfd;    }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]nfd=%d 客户端下线\n",inet_ntoa(saveCin[i].sin_addr),ntohs(saveCin[i].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(maxfd,&readfds))break;maxfd=j;}*/continue;}printf("nfd=%d : %s\n",i,buf);//发送数据strcat(buf,"*_*");if(send(nfd,buf,sizeof(buf),0)<0){ERR_MSG("send");return -1; }printf("发送成功\n");}}}   //关闭所有文件描述符close(sfd);return 0;
}                

使用select函数实现IO多路复用的客户端:

#include<stdio.h>
#include<head.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/select.h>
#define PROT 1112//服务器绑定的端口
#define IP "192.168.125.232"//服务器绑定的IP端口
int main(int argc, const char *argv[])
{//创建流式套接字int cfd=socket(AF_INET,SOCK_STREAM,0);if(cfd<0){   ERR_MSG("socket");return -1; }   printf("cfd=%d\n",cfd);//绑定客户端的IP和端口--->非必须绑定//连接服务器//先填充服务器的地址信息结构体,真实地址信息结构体根据地址族制定struct sockaddr_in sin;sin.sin_family   = AF_INET;sin.sin_port     = htons(PROT);//服务器绑定的端口号sin.sin_addr.s_addr     = inet_addr(IP);//服务器绑定的本机IP//连接服务器if(connect(cfd,(struct sockaddr*)&sin,sizeof(sin))<0){   ERR_MSG("connect");return -1; }   printf("连接服务器成功\n");char buf[128]="";ssize_t res=0;int s_res=-1;//创建读集合fd_set readfds,tempfds;FD_ZERO(&readfds);FD_ZERO(&tempfds);FD_SET(0,&readfds);FD_SET(cfd,&readfds);while(1){   tempfds=readfds;s_res=select(cfd+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__);//能运行到这代表集合中有文件描述符准备就绪//判断哪个文件描述符准备就绪,运行对应函数if(FD_ISSET(0,&tempfds)){printf("触发键盘输入事件\n");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; }printf("发送成功\n");}else if(FD_ISSET(cfd,&tempfds)){printf("触发服务器交互\n");bzero(buf,sizeof(buf));//接收数据res=recv(cfd,buf,sizeof(buf),0);if(res<0){                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      ERR_MSG("recv");return -1; }else if(0==res){printf("[%s:%d]cfd=%d 服务器掉线\n",IP,PROT,cfd);break;}printf("[%s:%d]cfd=%d : %s\n",IP,PROT,cfd,buf);}}   //关闭所有文件描述符close(cfd);return 0;
} 

 使用poll函数实现IO多路复用的客户端:

#include<stdio.h>
#include<head.h>
#include<poll.h>
#define PROT 1112//服务器绑定的端口
#define IP "192.168.125.232"//服务器绑定的IP端口
int main(int argc, const char *argv[])
{//创建流式套接字int cfd=socket(AF_INET,SOCK_STREAM,0);if(cfd<0){ERR_MSG("socket");return -1;}printf("cfd=%d\n",cfd);//绑定客户端的IP和端口--->非必须绑定//连接服务器//先填充服务器的地址信息结构体,真实地址信息结构体根据地址族制定struct sockaddr_in sin;sin.sin_family   = AF_INET;sin.sin_port     = htons(PROT);//服务器绑定的端口号sin.sin_addr.s_addr     = inet_addr(IP);//服务器绑定的本机IP//连接服务器if(connect(cfd,(struct sockaddr*)&sin,sizeof(sin))<0){ERR_MSG("connect");return -1;}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              printf("连接服务器成功\n");char buf[128]="";ssize_t res=0;int p_res=-1;//定义集合struct pollfd fds[2];//将需要监测的文件描述符添加到集合fds[0].fd=0;//制定监测0号文件描述符fds[0].events=POLLIN;fds[1].fd=cfd;fds[1].events=POLLIN;while(1){p_res=poll(fds,2,-1);if(p_res<0){ERR_MSG("poll");return -1;}else if(0==p_res){printf("time out...\n");break;}//能运行到这代表集合中有文件描述符准备就绪//判断哪个文件描述符准备就绪,运行对应处理函数//判断集合中的每个文件描述符中是否有pollin//从revents中将代表pollin的那一位单独提取出来,判断是1还是0if((fds[0].revents&POLLIN)!=0){printf("触发键盘输入事件\n");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;}printf("发送成功\n");}if(fds[1].revents&POLLIN){printf("触发服务器交互\n");bzero(buf,sizeof(buf));//接收数据res=recv(cfd,buf,sizeof(buf),0);if(res<0){ERR_MSG("recv");return -1;}else if(0==res){printf("[%s:%d]cfd=%d 服务器掉线\n",IP,PROT,cfd);break;}printf("[%s:%d]cfd=%d : %s\n",IP,PROT,cfd,buf);}}//关闭所有文件描述符close(cfd);return 0;
}

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

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

相关文章

29 | 广州美食店铺数据分析

广州美食店铺数据分析 一、数据分析项目MVP加/价值主张宣言 随着经济的快速发展以及新媒体的兴起,美食攻略、美食探店等一系列东西进入大众的眼球,而人们也会在各大平台中查找美食推荐,因此本项目做的美食店铺数据分析也是带有可行性的。首先通过对广东省的各市美食店铺数量…

对话即数据分析,网易数帆ChatBI做到了

大数据产业创新服务媒体 ——聚焦数据 改变商业 在当今数字化快速发展的时代&#xff0c;数据已经成为业务经营与管理决策的核心驱要素。无论是跨国大企业还是新兴创业公司&#xff0c;正确、迅速地洞察数据已经变得至关重要。然而&#xff0c;传统的BI工具往往对用户有一定的…

初步认识OSI/TCP/IP一(第三十八课)

1 初始OSI模型 OSI参考模型(Open Systems Interconnection Reference Model)是一个由国际标准化组织(ISO)和国际电报电话咨询委员会(CCITT)联合制定的网络通信协议规范,它将网络通信分为七个不同的层次,每个层次负责不同的功能和任务。 2 网络功能 数据通信、资源共享…

MTK Android非常用分辨率修改充电动画

非标准分辨率的屏,配置MTK Android的关机充电动画. 环境 芯片 MTK 系统 Android 服务器 ubuntu 屏幕分辨率356*400,不是常见的分辨率. 原始充电动画显示异常,画面扭曲. 方法 确定使用的图片 vendor/mediatek/proprietary/bootable/bootloader/lk/dev/logo 这个目录下…

springboot多模块打包方式

明确子父模块结构 父目录是带modules 大致结构如下&#xff1a; <modules><module>ruoyi-admin</module><module>ruoyi-framework</module><module>ruoyi-system</module><module>ruoyi-quartz</module><module>…

htmlCSS-----高级选择器

目录 前言 伪类选择器 状态类 结构类 伪元素选择器 属性选择器 前言 前面我们学习了CSS中的相关选择器&#xff08;链接html&CSS-----CSS选择器&#xff08;上&#xff09;_灰勒塔德的博客-CSDN博客 html&CSS-----CSS选择器&#xff08;下&#xff09;_灰勒塔…

计算机视觉中的Transformer

几十年来&#xff0c;理论物理学家一直在努力提出一个宏大的统一理论。通过统一&#xff0c;指的是将被认为是完全不同的两个或多个想法结合起来&#xff0c;将它们的不同方面证明为同一基础现象。一个例子是在19世纪之前&#xff0c;电和磁被看作是无关的现象&#xff0c;但电…

【大数据之Kafka】三、Kafka生产者之消息发送流程及同步异步发送API

将外部传送给过来的数据发送到kafka集群。 1 发送原理 &#xff08;1&#xff09;创建main()线程&#xff0c;创建producer对象&#xff0c;调用send方法&#xff0c;经过拦截器&#xff08;可选&#xff09;、序列化器、分区器。 &#xff08;2&#xff09;分区器将数据发送…

【Android Framework (十二) 】- 智能硬件设备开发

文章目录 前言智能硬件的定义与应用智能硬件产品开发流程智能硬件开发所涉及的技术体系概述关于主板选型主板CPU芯片的选择关于串口通信 总结 前言 针对我过往工作经历&#xff0c;曾在一家智能科技任职Android开发工程师&#xff0c;简单介绍下关于任职期间接触和开发过的一些…

DDPM: Denoising Diffusion Probabilistic Models

DDPM: Denoising Diffusion Probabilistic Models 去噪扩散模型前向过程-加噪声反向过程-去噪声 去噪扩散模型 论文题目&#xff1a;Denoising Diffusion Probabilistic Models (DDPM) 论文来源&#xff1a;NIPS, 2020 论文地址&#xff1a;https://arxiv.org/abs/2006.11239 论…

13.3 目标检测和边界框

锚框的计算公式 假设原图的高为H,宽为W 详细公式推导 以同一个像素点为锚框&#xff0c;可以生成 (n个缩放 m个宽高比 -1 )个锚框 锚框的作用&#xff1a; 不用直接去预测真实框的四个坐标&#xff0c;而是&#xff1a; 1.先生成多个锚框。 2.预测每个锚框里是否含有要预测…

【Linux】【驱动】杂项设备驱动

【Linux】【驱动】杂项设备驱动 Linux三大设备驱动1. 我们这节课要讲的杂项设备驱动是属于我们这三大设备驱动里面的哪个呢?2.杂项设备除了比字符设备代码简单&#xff0c;还有别的区别吗?3.主设备号和次设备号是什么? 挂载驱动 杂项设备驱动是字符设备驱动的一种&#xff0…

小程序制作教程:从零开始搭建企业小程序

在如今的数字化时代&#xff0c;企业介绍小程序成为了企业展示与推广的重要工具。通过企业介绍小程序&#xff0c;企业可以向用户展示自己的品牌形象、产品服务以及企业文化等内容&#xff0c;进而提高用户对企业的认知度和信任度。本文将介绍如何从零开始搭建一个企业介绍小程…

域名配置HTTPS

一、注册域名 这个可以在各大平台注册&#xff0c;具体看一下就会注册了&#xff0c;自己挑选一个自己喜欢的域名。 步骤一般也就是先实名&#xff0c;实名成功了才能注册域名。 二、办理SSL证书 这里使用的是阿里云的SSL免费证书 1、申请证书 二、填写申请 三、域名绑定生…

公司电脑三维图纸加密、机械图挡加密软件

机械图纸加密软件的问世&#xff0c;让很多的网络公司都大受其带来的工作中的便利。在安装了机械图纸加密软件后&#xff0c;不仅可以很好的管理员工在工作时的上网娱乐&#xff0c;在对整个公司员工的工作效率上也有着明显的提高&#xff0c;那么对于机械图纸加密软件的具体特…

【C#】静默安装、SQL SERVER静默安装等

可以通过cmd命令行来执行&#xff0c;也可以通过代码来执行&#xff0c;一般都需要管理员权限运行 代码 /// <summary>/// 静默安装/// </summary>/// <param name"fileName">安装文件路径</param>/// <param name"arguments"…

word 应用 打不开 显示一直是正在启动中

word打开来显示一直正在启动中&#xff0c;其他调用word的应用也打不开&#xff0c;网上查了下以后进程关闭spoolsv.exe,就可以正常打开word了

机器学习:特征工程之特征预处理

目录 特征预处理 1、简述 2、内容 3、归一化 3.1、鲁棒性 3.2、存在的问题 4、标准化 ⭐所属专栏&#xff1a;人工智能 文中提到的代码如有需要可以私信我发给你&#x1f60a; 特征预处理 1、简述 什么是特征预处理&#xff1a;scikit-learn的解释&#xff1a; provide…

linux系统服务学习(六)FTP服务学习

文章目录 FTP、NFS、SAMBA系统服务一、FTP服务概述1、FTP服务介绍2、FTP服务的客户端工具3、FTP的两种运行模式&#xff08;了解&#xff09;☆ 主动模式☆ 被动模式 4、搭建FTP服务&#xff08;重要&#xff09;5、FTP的配置文件详解&#xff08;重要&#xff09; 二、FTP任务…

Python基础语法入门(第二十天)——文件操作

一、基础内容 在Python中&#xff0c;路径可以以不同的表现形式进行表示。以下是一些常用的路径表现形式&#xff1a; 1. 绝对路径&#xff1a;它是完整的路径&#xff0c;从根目录开始直到要操作的文件或文件夹。在Windows系统中&#xff0c;绝对路径以盘符开始&#xff0c;…