4.28 poll API介绍及代码编写

4.28 poll API介绍及代码编写

#include <poll.h>
struct pollfd{
	int fd;//委托内核检测的文件描述符
	short events;//委托内核检测文件描述符的什么事件
	short revents;//文件描述符实际发生的事件
};
int poll(struct pollfd *fds,nfds_t nfds,int timeout);
	-参数:
		-fds:是一个struct pollfd结构体数组,这是一个需要检测的文件描述符的集合
		-nfds:这是第一个参数数组中最后一个有效元素的下标+1
		-timeout:阻塞时长
			0:不阻塞
			-1:阻塞,当检测到需要检测的文件描述符有变化,解除阻塞
			>0:阻塞的时长,单位毫秒
	-返回值:
		-1:失败
		>0:成功,返回n表示检测到集合中有n个文件描述符发生变化

在这里插入图片描述
当检测两个事件时,使用或操作:

struct pollfd myfd;
myfd.fd=5;
myfd.events=PLLIN|POLLOUT;//同时检测读事件和写事件

代码实现
client.c

#include <stdio.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

int main(){
    //1.创建一个用于通信的socket
    int fd=socket(PF_INET,SOCK_STREAM,0);
    if(fd==-1){
        perror("socket");
        return -1;
    }

    //指定连接的服务器的IP和端口
    struct sockaddr_in seraddr;
    inet_pton(AF_INET,"127.0.0.1",&seraddr.sin_addr.s_addr);
    seraddr.sin_family=AF_INET;
    seraddr.sin_port=htons(9999);

    //2.连接服务器
    int ret=connect(fd,(struct sockaddr *)&seraddr,sizeof(seraddr));
    if(ret==-1){
        perror("connect");
        return -1;
    }

    //3.连接成功了,客户端可以直接和服务端通信(接收数据,发送数据)
    int num=0;
    while(1){
        char sendBuf[1024]={0};
        sprintf(sendBuf,"send data %d",num++);
        //发送数据
        write(fd,sendBuf,strlen(sendBuf)+1);

        //接收数据
        int len=read(fd,sendBuf,sizeof(sendBuf));
        if(len==-1){
            perror("read");
            return -1;
        }else if(len>0){
            printf("read buf=%s\n",sendBuf);
        }else{
            printf("服务器已经断开连接...\n");
            break;
        }
        usleep(1000);
    }
    
    //4.通信结束,断开连接
    close(fd);
    
    return 0;
}

poll.c

#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <poll.h>

int main(){
    //1、创建一个用于监听的套接字
    int lfd=socket(PF_INET,SOCK_STREAM,0);
    //本地服务器的地址信息(IP和端口)
    struct sockaddr_in saddr;
    saddr.sin_port=htons(9999);
    saddr.sin_family=AF_INET;
    saddr.sin_addr.s_addr=INADDR_ANY;

    //2、将监听文件描述符和本地IP和端口绑定
    bind(lfd,(struct sockaddr *)&saddr,sizeof(saddr));

    //3、设置监听,监听的fd开始工作
    listen(lfd,8);

    //初始化检测的文件描述符数组
    struct pollfd fds[1024];
    for(int i=0;i<1024;++i){
        fds[i].fd=-1;
        fds[i].events=POLLIN;//检测读事件
    }
    fds[0].fd=lfd;//下标0表示监听描述符
    int nfds=0;

    while(1){
        //调用poll系统函数,让内核帮忙检测哪些文件描述符有数据
        int ret=poll(fds,nfds+1,-1);
        if(ret==-1){
            perror("poll");
            exit(-1);
        }else if(ret==0){
            continue;
        }else if(ret>0){
            //说明检测到了有文件描述符的对应缓冲区数据发生改变
            if(fds[0].revents&POLLIN){
                //表示有新客户端连接进来
                struct sockaddr_in cliaddr;
                int len=sizeof(cliaddr);
                int cfd=accept(lfd,(struct sockaddr *)&cliaddr,&len);

                //将新的文件描述符加入到集合中
                for(int i=1;i<1024;++i){
                    if(fds[i].fd==-1){
                        fds[i].fd=cfd;
                        fds[i].events=POLLIN;
                        break;
                    }
                }

                //更新最大的文件描述符索引
                nfds=nfds>cfd?nfds:cfd;
            }

            for(int i=1;i<=nfds;++i){
                if(fds[i].revents&POLLIN){
                    //说明这个文件描述符对应的客户端发来了数据
                    char buf[1024]={0};
                    //接收数据
                    int len=read(fds[i].fd,buf,sizeof(buf));
                    if(len==-1){
                        perror("read");
                        exit(-1);
                    }else if(len==0){
                        printf("client closed...\n");
                        close(fds[i].fd);//通信结束,断开连接
                        fds[i].fd=-1;
                    }else if(len>0){
                        printf("read buf=%s\n",buf);
                        //发送数据
                        write(fds[i].fd,buf,strlen(buf)+1);
                    }
                }
            }
        }
    }

    close(lfd);

    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Learning C++ No.29 【右值引用实战】

引言&#xff1a; 北京时间&#xff1a;2023/6/7/9:39&#xff0c;上午有课&#xff0c;且今天是周三&#xff0c;承接之前博客&#xff0c;今天我又去帮我舍友签到早八&#xff0c;但愿这次不会被发现吧&#xff01;嘻嘻嘻&#xff01;并且刚刚发文有关对C11相关知识&#xf…

第八章 图像压缩

文章目录 第八章 图像压缩8.1基础知识8.1.1 编码冗余8.1.4图像信息的度量8.1.5保真准则8.1.6图像压缩模型8.17图像格式、容器和压缩标准 8.2一些基本的压缩方法8.2.1霍夫曼编码8.2.2Golomb编码8.2.3算术编码8.2.4LZW编码8.2.5行程编码8.2.6基于符号的编码8.2.7比特平面编码8.2.…

WebGIS 信息系统-系统实现

WebGIS 信息系统-系统实现 主界面基本模块地图基本管理模块地图属性主界面大纲视图实现创建选项菜单添加点击事件实现加载底图图层和定位图层完善这个类文件 主界面基本模块 (1 &#xff09;平移&#xff1a;单击按钮将鼠标置于平移状态&#xff0c;可用来清除当前图形操作工具…

人工智能 | 技能人才评价证书分析及人工智能/计算机类证书推荐

目录 简介技能人才评价证书相关介绍1. 国家职业资格证书2. 职业技能等级证书 推荐证书目录1. 计算机类的国家职业资格证书a. 证书推荐b. “软高***”和“PMP”的区别 2. 计算机类的职业技能等级证书a. 工信部认证b. 中国人工智能学会证书 专业证书的作用1. 抵税2. 领取职业技能…

全志V3S嵌入式驱动开发(USB camera驱动)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 soc和mcu的一个重要区别&#xff0c;就是soc会涉及到大量的音视频操作&#xff0c;当然音视频也就包括了camera摄像头这部分。v3s本身支持csi接口和…

ChatGPT:开放AI平台的最新进展和功能

第一章&#xff1a;引言 在过去的几年中&#xff0c;人工智能技术取得了长足的发展&#xff0c;其在各个领域的应用也日益广泛。而在AI技术中&#xff0c;自然语言处理&#xff08;NLP&#xff09;一直是备受关注的领域之一。ChatGPT作为OpenAI的开放AI平台上的一项重要技术&am…

慕课:笔记

课程链接&#xff1a;直面JavaScript中的30个疑难杂症_JavaScript面试题-慕课网 第二章&#xff1a;数据类型 数据类型是每门编程语言的必修之课&#xff0c;你是否对JavaScript的数据类型和检测存在困惑&#xff0c;本章节将为你揭晓其中的奥秘&#xff0c;让你对数据类型有…

【Tableau案例】神奇宝贝属性及实力强弱|数据可视化

提前声明&#xff1a;神奇宝贝的数据分析仅供参考&#xff0c;不涉及对于神奇宝贝的各种评价&#xff0c;另外我是初学tableau&#xff0c;涉及到使用的tableau操作可能很简单&#xff0c;复杂的还掌握不熟练&#xff0c;之后会拿时间系统学习tabelau。 数据预处理 该数据集有…

CODESYS模拟量超限报警功能块

博途PLC模拟量超限报警功能块详细介绍请参看下面文章链接: PLC模拟量超限报警功能块_RXXW_Dor的博客-CSDN博客模拟量偏差报警功能块请参看下面文章:模拟量偏差报警功能块(SCL代码)_RXXW_Dor的博客-CSDN博客工业模拟量采集的相关基础知识,可以查看专栏的系列文章,这里不再赘…

OSPF故障定位没思路?照这篇抄就行

我的网工朋友大家好。 好久没聊OSPF技术了&#xff0c;相关基础且经典的内容&#xff0c;公众号陆陆续续分享过一些&#xff0c;趣味科普&#xff0c;面试考题&#xff0c;实验操作&#xff0c;都有涉及。 按照惯例&#xff0c;先给你整一波优质的往期内容&#xff1a; 《 5个…

Spring Boot之静态资源映射 | 超级详细,建议收藏

写在前面&#x1f525; 上几期&#xff0c;我们重点讲解了Spring Boot集成Swagger-UI实现在线API文档及美化UI界面&#xff0c;而这期&#xff0c;在 Web 应用中会都会涉及到大量的静态资源&#xff0c;例如 图片、JS、CSS 和 HTML 等。我们知道&#xff0c;Spring MVC 导入静态…

WebGIS 信息系统-主界面基本模块功能设计

文章目录 系统文件夹结构主界面地图基本管理模块功能设计手机定位模块功能设计经纬度路径生成功能设计导航模块功能设计用户管理模块功能设计 系统文件夹结构 为了使项目容易管理和维护&#xff0c;在开发之前需要确定项目的系统文件夹结构&#xff0c;即系统文件夹结构设计。…

C++ / QT 旅游产品管理系统

一、项目介绍 旅游产品管理系统 你是一家旅行社的 IT 主管&#xff0c;现在需要你设计并实现一个旅游产品管理系统。 1 &#xff09; 基本功能要求 * 实现基础界面&#xff1a; 参照现有的旅游产品管理系统&#xff1a;查看产品、选择产品、使用说明等内容 * 支持旅游产品…

用Python搭建监控平台详解

概要 监控和运维&#xff0c;是互联网工业链上非常重要的一环。监控的目的就是防患于未然。通过监控&#xff0c;我们能够及时了解到企业网络的运行状态。一旦出现安全隐患&#xff0c;你就可以及时预警&#xff0c;或者是以其他方式通知运维人员&#xff0c;让运维监控人员有时…

Springboot 核心注解和基本配置解读

目录 1. Springboot 入门与原理 1.1 Springboot 简介 1.1.1 什么是Springboot 1.1.2 Springboot 主要优点 1.2 Springboot 相关注解 1.2.1 元注解 1.2.1.1 Target 1.2.1.2 Retention 1.2.2 Configuration 1.2.3 Import 1.2.3.1 直接注入 1.2.3.2 实现 ImportSelector…

Error: Cannot find module ‘webpack‘ 问题解决办法

这句话的意思是&#xff1a;没有找到webpack模块。 就算之前你装了webpack&#xff0c;那肯定是非全局安装 所以要全局安装 npm install --save-dev webpack 问题解决

4.蜂鸣器

1.了解蜂鸣器&#xff1a; 蜂鸣器在使用3.3V无法驱动&#xff0c;需要借助到三极管的放大特性(IcβIb)将蜂鸣器驱动&#xff1b;本次原理图中&#xff0c;接R33电阻是因为当STM32单片机复位时处于浮空状态&#xff0c;防止小电流让蜂鸣器响而添加的。 2.蜂鸣器原理图&#xf…

剖析Linux文件系统

Linux 文件系统体系结构是一个对复杂系统进行抽象化的有趣例子。通过使用一组通用的 API 函数&#xff0c;Linux 可以在许多种存储设备上支持许多种文件系统。例如&#xff0c;read 函数调用可以从指定的文件描述符读取一定数量的字节。read 函数不了解文件系统的类型&#xff…

Java——《面试题——Redis篇》

前文 java——《面试题——基础篇》 Java——《面试题——JVM篇》 Java——《面试题——多线程&并发篇》 Java——《面试题——Spring篇》 Java——《面试题——SpringBoot篇》 Java——《面试题——MySQL篇》​​​​​​ Java——《面试题——SpringCloud》 Java…

使用Nginx的反向代理来访问服务器例子——Nginx笔记

因为网站上的视频加载过慢&#xff0c;想使用nginx服务器实现HLS视频播放服务。顺便记录一下通过Nginx的方向代理来访问服务器。这里在原先的项目上进行改造。原先的项目已经部署在公网&#xff0c;使用tomcat服务器&#xff0c;可以直接用地址进行访问。 1.这里使用的8080端口…