Linux 非阻塞网络IO模式

非阻塞网络IO模式介绍

当用户线程发起一个 read 操作后,并不需要等待,而是马上就得到了一个结果。如果结果是一个 error 时,它就知道数据还没有准备好,于是它可以再次发送 read 操作。一旦内核中的数据准备好了,并且又再次收到了用户线程的请求,那么它马上就将数据拷贝到了用户线程,然后返回。

所以事实上,在非阻塞 IO 模型中,用户线程需要不断地询问内核数据是否就绪,也就 说非阻塞 IO 不会交出 CPU,而会一直占用 CPU。

在这里插入图片描述

设置非阻塞常用方式:

方式一: 创建 socket 时指定

int s = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP);

方式二: 在使用前通过如下方式设定

fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL, 0) | O_NONBLOCK);

方式一 demo

#include <sys/un.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>#define BUFF_SIZE 1024int main(void)
{int server_sockfd;int client_sockfd;char ch;int ret;int recv_len;char buff[BUFF_SIZE];//用于 UNIX 系统内部通信的地址, struct sockaddr_unstruct sockaddr_in server_addr;struct sockaddr_in client_addr;int client_addr_len =sizeof(struct sockaddr_in);server_sockfd = socket(AF_INET, SOCK_DGRAM|SOCK_NONBLOCK, 0);// 设置服务器地址server_addr.sin_family = AF_INET;               //地址的域,相当于地址的类型,AF_UNIX 表示地址位于 UNIX 系统内部server_addr.sin_addr.s_addr = INADDR_ANY;       //inet_addr("10.10.0.9");server_addr.sin_port = htons(9000);// 绑定该套接字,使得该套接字和对应的系统套接字文件关联起来。ret = bind(server_sockfd, (struct sockaddr*)&server_addr,sizeof(server_addr));if (ret == -1) {perror("bind");exit(1);}// 创建套接字队列, 保存进入该服务器的客户端请求。// ret = listen(server_sockfd, 5);// 循环处理客户端请求while (1) {printf("server waiting\n");// 等待并接收客户端请求//client_sockfd = accept(server_sockfd, (struct sockaddr*)&client_addr, &client_addr_len);recv_len = recvfrom(server_sockfd, buff, sizeof(buff) , 0,(struct sockaddr*)&client_addr, &client_addr_len);if (recv_len < 0) {if(errno == EAGAIN ||errno == EWOULDBLOCK){sleep(2);continue;}perror("recvfrom");exit(errno);}printf("received: %s\n", buff);}close(server_sockfd);return 0;
}

在这里插入图片描述
方式二 demo

#include <sys/un.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>#define BUFF_SIZE 1024int main(void)
{int server_sockfd;int client_sockfd;char ch;int ret;int recv_len;char buff[BUFF_SIZE];//用于 UNIX 系统内部通信的地址, struct sockaddr_unstruct sockaddr_in server_addr;struct sockaddr_in client_addr;int client_addr_len =sizeof(struct sockaddr_in);server_sockfd = socket(AF_INET, SOCK_DGRAM, 0);// 设置服务器地址server_addr.sin_family = AF_INET;               //地址的域,相当于地址的类型,AF_UNIX 表示地址位于 UNIX 系统内部server_addr.sin_addr.s_addr = INADDR_ANY;       //inet_addr("10.10.0.9");server_addr.sin_port = htons(9000);// 绑定该套接字,使得该套接字和对应的系统套接字文件关联起来。ret = bind(server_sockfd, (struct sockaddr*)&server_addr,sizeof(server_addr));if (ret == -1) {perror("bind");exit(1);}// 创建套接字队列, 保存进入该服务器的客户端请求。// ret = listen(server_sockfd, 5);fcntl(server_sockfd, F_SETFL, fcntl(server_sockfd, F_GETFL, 0) | O_NONBLOCK);// 循环处理客户端请求while (1) {printf("server waiting\n");// 等待并接收客户端请求//client_sockfd = accept(server_sockfd, (struct sockaddr*)&client_addr, &client_addr_len);recv_len = recvfrom(server_sockfd, buff, sizeof(buff) , 0,(struct sockaddr*)&client_addr, &client_addr_len);if (recv_len < 0) {if(errno == EAGAIN ||errno == EWOULDBLOCK){sleep(2);continue;}perror("recvfrom");exit(errno);}printf("received: %s\n", buff);}close(server_sockfd);return 0;
}

在这里插入图片描述

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

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

相关文章

Android笔记(十八):面向Compose组件结合Retrofit2和Rxjava3实现网络访问

一、Retrofit2 Square公司推出的Retrofit2库&#xff08;https://square.github.io/retrofit/&#xff09;&#xff0c;改变了网络访问的方式。它实现了网络请求的封装。Retrofit库采用回调处理方式&#xff0c;使得通过接口提交请求和相应的参数的配置&#xff0c;就可以获得…

安装2023最新版Java SE 21.0.1来开发Java应用程序

安装2023最新版Java SE 21.0.1来开发Java应用程序 Install the latest version of Java SE 21.01 to Develop Java Applications By JacksonML 本文简要介绍如何下载和安装2023年最新版Java Development Kit (简称JDK&#xff0c;即Java开发工具包标准版&#xff09;21.0.1&…

开发人员必须掌握的几个高级命令

xargs命令 在平时的使用中,我认为 xargs 这个命令还是较为重要和方便的。我们可以通过使用这个命令,将命令输出的结果作为参数传递给另一个命令。 比如说我们想找出某个路径下以 .conf 结尾的文件,并将这些文件进行分类,那么普通的做法就是先将以 .conf 结尾的文件先找出…

通过51单片机控制SG90舵机按角度正反转转动

一、前言 本文介绍如何通过51单片机控制SG90舵机实现角度的正反转转动。SG90舵机是一种常用的微型舵机&#xff0c;具有体积小、重量轻、结构简单等特点&#xff0c;被广泛应用于机器人、遥控模型和各种自动控制系统中。 使用51单片机&#xff08;STC89C52&#xff09;作为控…

RPM包管理_YUM

8.1 RPM包管理 8.1.1 RPM概述 RPM Package Manager (原Red Hat Package Manager&#xff0c;现在是一个递归缩写&#xff09; ​ 由Red Hat公司提出&#xff0c;被众多 Linux 发行版所采用也称二进制( binary code) 无需编译,可以直接使用 ​ 无法设定个人设置&#xff0c;开…

在 Windows PC 上轻松下载并安装 FFmpeg

FFmpeg 是一种开源媒体工具&#xff0c;可用于将任何视频格式转换为您需要的格式。该工具只是命令行&#xff0c;因此它没有图形、可点击的界面。如果您习惯使用常规图形 Windows 程序&#xff0c;安装 FFmpeg 一开始可能看起来很复杂&#xff0c;但不用担心&#xff0c;它;很简…

【探索评估】记录小车运动轨迹,并在 rviz 上显示

本文主要是参考的博客&#xff1a;ROS 移动机器人运动轨迹记录&#xff0c;并发布在rviz上 但是由于订阅的话题不一样&#xff0c;在这里记录一下 在进行自主探索的时候将小车移动过程中的消息记录在 txt 或是 csv 文件中 在此记录的是小车的 /odom 消息&#xff0c;并且只记录…

2023-12-14 二叉树的最大深度和二叉树的最小深度以及完全二叉树的节点个数

二叉树的最大深度和二叉树的最小深度以及完全二叉树的节点个数 104. 二叉树的最大深度 思想&#xff1a;可以使用迭代法或者递归&#xff01;使用递归更好&#xff0c;帮助理解递归思路&#xff01;明确递归三部曲–①确定参数以及返回参数 ②递归结束条件 ③单层逻辑是怎么样…

Leetcode—172.阶乘后的零【中等】

2023每日刷题&#xff08;六十&#xff09; Leetcode—172.阶乘后的零 算法思想 实现代码 int trailingZeroes(int n) {int ans 0;for(int i 5; i < n; i 5) {for(int j i; j % 5 0; j / 5) {ans;}}return ans; }运行结果 之后我会持续更新&#xff0c;如果喜欢我的文…

郝斌C语言自学教程笔记

赫斌C语言——笔记目录 c语言编程预备知识流程控制函数变量指针结构体位运算符 前段时间康哥看我C语言基础不牢,推荐我学习郝斌老师的C语言课程&#xff0c;花2周看完之后发现确实是目前所看的C语言课程中最好的&#xff0c;不仅非常适合入门&#xff0c;而且对即使学了几年C语…

2021年数维杯国际大学生数学建模B题极端降雨的定量分析求解全过程文档及程序

2021年数维杯国际大学生数学建模 B题 极端降雨的定量分析 原题再现&#xff1a; 近两年来&#xff0c;我国河南、陕西、湖北等地遭遇了极为罕见的暴雨。与此同时&#xff0c;北方一些城市遭遇了历史上罕见的暴风雪。这些暴雨和降雪对当地人民的生命、安全和财产构成严重威胁。…

基于ssm点餐平台系统论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本点餐平台系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息&am…