linux socket的阻塞和非阻塞设置方法

2023-11-13

非阻塞IO 和阻塞IO:

       在网络编程中对于一个网络句柄会遇到阻塞IO 和非阻塞IO 的概念, 这里对于这两种socket 先做一下说明:
       基本概念:

              阻塞IO::

                     socket 的阻塞模式意味着必须要做完IO 操作(包括错误)才会

                     返回。

              非阻塞IO::

                     非阻塞模式下无论操作是否完成都会立刻返回,需要通过其他方

                     式来判断具体操作是否成功。(对于connect,accpet操作,通过select判断,

                      对于recv,recvfrom,send,sendto通过返回值+错误码来判断)


IO模式设置:

                                                        SOCKET
       对于一个socket 是阻塞模式还是非阻塞模式处理方法::

       方法::

               fcntl 设置;用F_GETFL获取flags,用F_SETFL设置flags|O_NONBLOCK;

               同时,recv,send 时使用非阻塞的方式读取和发送消息,即flags设置为MSG_DONTWAIT

                                                         实现

 fcntl 函数可以将一个socket 句柄设置成非阻塞模式: 
      flags = fcntl(sockfd, F_GETFL, 0);                       //获取文件的flags值。

      fcntl(sockfd, F_SETFL, flags O_NONBLOCK);   //设置成非阻塞模式;

      flags  = fcntl(sockfd,F_GETFL,0);

      fcntl(sockfd,F_SETFL,flags&~O_NONBLOCK);    //设置成阻塞模式;

      并在接收和发送数据时:

     将recv, send 函数的最后有一个flag 参数设置成MSG_DONTWAIT

     recv(sockfd, buff, buff_size,MSG_DONTWAIT);     //非阻塞模式的消息发送

     send(scokfd, buff, buff_size, MSG_DONTWAIT);   //非阻塞模式的消息接受

 


                                                          普通文件

        对于文件的阻塞模式还是非阻塞模式::

        方法1、open时,使用O_NONBLOCK;

        方法2、fcntl设置,使用F_SETFL,flags|O_NONBLOCK;

                                  

 

                                              消息队列

        对于消息队列消息的发送与接受::

        //非阻塞  msgsnd(sockfd,msgbuf,msgsize(不包含类型大小),IPC_NOWAIT)

        //阻塞     msgrcv(scokfd,msgbuf,msgsize(**),msgtype,IPC_NOWAIT);

 

                                                              

 

                                                                                  

阻塞与非阻塞的区别:  //阻塞和非阻塞的区别在于没有数据到达的时候是否立刻返回.

读(read/recv/msgrcv):

       读的本质来说其实不能是读,在实际中, 具体的接收数据不是由这些调用来进行,是由于系统底层自动完成的。read 也好,recv 也好只负责把数据从底层缓冲copy 到我们指定的位置.

       对于读来说(read, 或者recv) ::

阻塞情况下::

       在阻塞条件下,read/recv/msgrcv的行为::

       1、如果没有发现数据在网络缓冲中会一直等待,

       2、当发现有数据的时候会把数据读到用户指定的缓冲区,但是如果这个时候读到的数据量比较少,比参数中指定的长度要小,read 并不会一直等待下去,而是立刻返回

       read 的原则::数据在不超过指定的长度的时候有多少读多少,没有数据就会一直等待

       所以一般情况下::我们读取数据都需要采用循环读的方式读取数据,因为一次read 完毕不能保证读到我们需要长度的数据,

       read 完一次需要判断读到的数据长度再决定是否还需要再次读取

非阻塞情况下::

       在非阻塞的情况下,read 的行为::

       1、如果发现没有数据就直接返回,

       2、如果发现有数据那么也是采用有多少读多少的进行处理

             所以::read 完一次需要判断读到的数据长度再决定是否还需要再次读取

 

对于读而言::   阻塞和非阻塞的区别在于没有数据到达的时候是否立刻返回.
       recv 中有一个MSG_WAITALL 的参数::

       recv(sockfd, buff, buff_size, MSG_WAITALL),
       在正常情况下recv 是会等待直到读取到buff_size 长度的数据,但是这里的WAITALL 也只是尽量读全,在有中断的情况下recv 还是可能会被打断,造成没有读完指定的buff_size的长度。

       所以即使是采用recv + WAITALL 参数还是要考虑是否需要循环读取的问题在实验中对于多数情况下recv (使用了MSG_WAITALL)还是可以读完buff_size

       所以相应的性能会比直接read 进行循环读要好一些。

 

注意::      //使用MSG_WAITALL时,sockfd必须处于阻塞模式下,否则不起作用。

               //所以MSG_WAITALL不能和MSG_NONBLOCK同时使用。

       要注意的是使用MSG_WAITALL的时候,sockfd 必须是处于阻塞模式下,否则WAITALL不能起作用。

 

 

                                                                          

 

 

阻塞与非阻塞的区别:     //
写(send/write/msgsnd)::

       写的本质也不是进行发送操作,而是把用户态的数据copy 到系统底层去,然后再由系统进行发送操作,send,write返回成功,只表示数据已经copy 到底层缓冲,而不表示数据已经发出,更不能表示对方端口已经接收到数据.
       对于write(或者send)而言,

阻塞情况下::                 //阻塞情况下,write会将数据发送完。(不过可能被中断)

       在阻塞的情况下,是会一直等待,直到write 完,全部的数据再返回这点行为上与读操作有所不同。

        原因::

              读,究其原因主要是读数据的时候我们并不知道对端到底有没有数据,数据是在什么时候结束发送的,如果一直等待就可能会造成死循环,所以并没有去进行这方面的处理;

              写,而对于write, 由于需要写的长度是已知的,所以可以一直再写,直到写完.不过问题是write 是可能被打断吗,造成write 一次只write 一部分数据, 所以write 的过程还是需要考虑循环write, 只不过多数情况下一次write 调用就可能成功.

 

非阻塞写的情况下::     //

       非阻塞写的情况下,是采用可以写多少就写多少的策略.与读不一样的地方在于,有多少读多少是由网络发送的那一端是否有数据传输到为标准,但是对于可以写多少是由本地的网络堵塞情况为标准的,在网络阻塞严重的时候,网络层没有足够的内存来进行写操作,这时候就会出现写不成功的情况,阻塞情况下会尽可能(有可能被中断)等待到数据全部发送完毕, 对于非阻塞的情况就是一次写多少算多少,没有中断的情况下也还是会出现write 到一部分的情况.


欢迎关注并加入物联网行业联盟,积累行业人脉和资源。


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux socket的阻塞和非阻塞设置方法 的相关文章

  • Linux系统安装配置curl

    1 获得安装包 从网上直接下载或者其他途径 这里直接wget wget http curl haxx se download curl 7 20 0 tar gz 2 解压到当前目录 或者 http www linuxidc com Lin
  • 贝叶斯方法应用:检测时间序列拐点

    随着时间推移 制造设备比如贴片机的位置由于各种原因会产生小的偏差 这些偏差可能是阶跃 也有可能是渐变的形式 由于偏差值很小 产线的自动光学检测设备并不会报警 然而小的偏差如果不经处理 经过一定时间累积会产生较大偏差 影响产品质量 为了能够提
  • 最好看的代码雨特效

    上代码
  • 2010年10大热门的开源NoSQL服务器软件

    NoSQL 就是反SQL 是一项全新的数据库革新运动 特别是在 2010 年得以迅猛发展 而各种开源的 NoSQL 软件突然间涌现在你面前 目前似乎没有对 NoSQL 给出一个标准的定义 也没有相应的规范 但从这些软件可以看出 NoSQL
  • WCF 第五章 一个单一实例中的多线程

    默认的InstanceContextMode行为设置指导WCF为每个请求创建一 个新的服务实例 然后在很多情况下 这不是最好的解决方案 例如 如果一个服务有一个代价很高的例行初始化 比如 一个构造器从一个数据库读取数据或者创 建一个大的内存
  • Linux OpenGauss 数据库远程连接

    目录 前言 1 Linux 安装 openGauss 2 Linux 安装cpolar 3 创建openGauss主节点端口号公网地址 4 远程连接openGauss 5 固定连接TCP公网地址 6 固定地址连接测试 前言 openGaus
  • carla二次开发(一)自定义创建地图

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 为什么创建carla地图很困难 二 官方创建方法 三 blender插件创建地图 四 City Engine创建地图 五 ue4创建地图 前言 carla
  • 某A类网络10.0.0.0的子网掩码255.224.0.0,请确定可以划分的子网个数,写出每个子网的子网号及每个子网的主机范围。

    某A类网络10 0 0 0的子网掩码255 224 0 0 请确定可以划分的子网个数 写出每个子网的子网号及每个子网的主机范围 可以确定划分的子网有2 3 2 6个 子网号 10 32 0 0主机范围 10 32 0 1 10 63 255
  • 数据结构计算题

    1 将下列函数按它们在 n 时的无穷大阶数 从小到大排列 n n n3 7n5 nlogn 2n 2 n3 log2n n1 2 log2n 3 2 n n n2 log2n 解答 log2n n1 2 log2n n nlog2n n2
  • c语言a b等于c的编程,简单的a+b (C语言代码)

    解题思路 题目中要求多次输入 所以需要一个死循环来进行控制 一般采用while 1 或者for 注意事项 scanf 函数需要加上取地址符 且它的返回值 它的返回值可以分成三种情况 1 正整数 表示正确输入参数的个数 例如执行 scanf
  • Java学习笔记——String类

    目录 API概述 案例 键盘录入字符串 String 概述 String类的常见构造方法 创建字符串对象的区别 String常见的面试题 字符串的比较 案例 用户登录 遍历字符串 案例 手机号屏蔽 字符串截取方法 案例 敏感词替换 字符串替
  • 决策树概述+模块介绍+重要参数(criterion+random_state&splitter+减枝参数+目标权重参数)+回归树(参数+实例+拟合正弦曲线)+泰坦尼克号生存者预测实例

    文章目录 什么是sklearn 一 决策树概述 一 概述 二 基础概念 三 决策树算法的核心是要解决两个问题 二 模块sklearn tree的使用 一 模块介绍 二 使用介绍 三 重要参数 一 criterion 二 random sta
  • JavaScript_day02

    文章目录 BOM与DOM操作 BOM操作 window子对象 history对象 location对象 掌握 弹出框 计时器相关 DOM操作 查找标签 节点操作 innerText 和 innerHTML 获取值操作 class css操作
  • 电机控制基础——定时器捕获单输入脉冲原理

    1 问题引出 在单片机与嵌入式开发中 某些场景需要捕获传感器的高电平 或低电平 信号的持续时间 如红外解码信号 编码器输入信号等 如下图 以单一的一段高电平输入信号为例 如何测量这段高电平的时间呢 从直观上理解 就是要不断的检测这个信号 当
  • IPv6与Volp

    文章目录 前言 1 IP v4与IP v6 1 1 IP v4的概念与存在的问题 1 2 ipv6概述 1 3 对比IP v4 IP v6的优点 1 3 ipv4与ipv6的包头比较 1 4 IP v6的基本术语 1 5 IP v6地址表示
  • 自主异常检测算法(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 Matlab代码 数据 4 参考文献 1 概述 文献来源 本文介绍了一种在实证数据分析
  • Java并发编程之CyclicBarrier详解

    简介 栅栏类似于闭锁 它能阻塞一组线程直到某个事件的发生 栅栏与闭锁的关键区别在于 所有的线程必须同时到达栅栏位置 才能继续执行 闭锁用于等待事件 而栅栏用于等待其他线程 CyclicBarrier可以使一定数量的线程反复地在栅栏位置处汇集
  • docker容器将系统盘空间占满的解决办法

    最近遇到一个问题 线上服务器的系统盘空间被占满了 导致服务不能正常运行了 docker启动时会报出下面这个错误 no space left on device 排查用到的命令 显示当前路径下占用空间超过1G的文件或文件夹 du h max
  • AD 原理图统一隐藏元器件的参数和序号

    AD 原理图统一隐藏元器件的参数和序号 如果隐藏元件参数 元件 右击 查找相似对象 确定 点击原理图 ctrl a 点击 属性对话框中 Part Conmment Hide 统一隐藏元件参数 如果隐藏元件序号 元件 右击 查找相似对象 确定

随机推荐

  • 用JAVA中的URL获取网页相关信息

    ava中有一个URL类 可以获取指定url的内容 import java io BufferedReader import java io InputStreamReader import java net URL public class
  • [Unity2D]在2D游戏里面实现人物的移动[消除抖动]

    Unity2D 在2D游戏里面实现人物的移动 先来一张效果图 一般的Unity2D游戏中 用WASD控制来移动人物角色的移动 缺陷 与含有碰撞器的强行碰撞时会发生抖动 原因 例如我人物要向左边走 利用脚本获取键盘输入 给人物角色一个向左边的
  • 一张图把DCDC电源拓扑“融会贯通”

    1 基本拓扑的由来 我们把一个电源电路抽象成一个黑盒电路模型 一个电源输入 一个电源输出 一个接地端口 对于非隔离电源 输入输出电路是共 地 的 所以非隔离电源的这个模型可以简化为图4 1 所示的模型 在所有的拓扑中 电感的一端需要连接到三
  • 使用docker部署golang编译环境

    前言 不想在windows上安装环境 打算docker部署 一拉一运行很方便 要注意的就是 官方的镜像跑起来后要改些参数再导成镜像 否则重启后改动消失 所以多一步 1 拉取镜像 运行镜像 docker pull golang docker
  • SpringBoot使用Swagger报NullPointerException

    第一次使用Swagger时报NullPointerException 在pom文件中引入Swagger 在启动项中加入注解 接口注解 运行出现NullPointerException 解决运行空指针问题 在pom文件中引入Swagger
  • Ini文件读取类,采用C++ STL实现

    背景 编程过程中经常会遇到读取Ini文件的场合 封装一个方便的类 能否避免重复编写 以后可复用 ini文件的格式很简单 并且不像xml之类的配置文件严谨 通常用于配置简单的键值对 本类测试文件如下
  • vuex的使用场景

    vuex的使用场景 首先 我们先来探讨一下 什么情况下vuex才是必须要到的呢 需要数据共享和行为进行拆分 复杂的异步逻辑 需要综合多个模块进行状态演进 需要用到第三方插件 需要综合考虑多个组件的生命周期 先后顺序 特定逻辑等等 vuex使
  • 如何在前端传递一个String 的变量和一个obj对象到后端,然后被Java后端接收

    首先我们通过post向后端发送请求 本篇博客仅纪录一下 在实际开发中需要从前端传递多值到后端 并且不存放到一个对象中进行传值处理 简单的一个案例展示该怎么做罢了 创建一个包含字符串和对象的数据 const postData stringVa
  • centos yum安装mysql出现的错误与解决办法

    1 InnoDB Error ib logfile0 of different size 错误的解决方法 查看Mysqld var log mysqld log 日志 发现以下错误 InnoDB Error log file usr loc
  • 冒泡排序--java(详解)

    对于一个数组 4 6 3 9 而言 首先进行第一轮 第一次比较 4 lt 6 所以不用交换两元素 数组不变为 4 6 3 9 第二次比较 6 gt 3 所以交换两元素 得到一个新数组为 4 3 6 9 第三次比较 6 lt 9 所以不用交换
  • 计算机维修培训教材,计算机芯片级维中心(芯片级维修培训教材)b.doc

    计算机芯片级维中心 芯片级维修培训教材 b 一 芯片的功能 作用及性能 具体内容 芯片组 南桥 北桥 BIOS芯片 时钟发生器IC RTC实时时钟 I O芯片 串口芯片75232 缓冲器244 245 门电路74系列 电阻R 电容C 二极管
  • Java笔记1:IntelliJ IDEA详细安装步骤

    安装IntelliJ IDEA 一 安装JDK 1 下载最新的jdk 这里下的是jdk 8u66 2 将jdk安装到默认的路径C Program Files Java目录下 二 安装IntelliJ IDEA 1 运行IntelliJ ID
  • Redis中SAVE和BGSAVE的区别

    Redis的这两个命令都是用于创建当前数据库的备份 因为Redis持久化选择RDB快照模式 所以Redis并不是实时的进行数据持久化 而是有一定的时间间隔 这个时候如果我们想要手动进行一次持久化 可以使用save或者bgsave命令 SAV
  • 如何使用sharemouse共享鼠标

    如何使用sharemouse共享鼠标 文章目录 如何使用sharemouse共享鼠标 1 Step 1 查看server IP 2 Step 2 配置Server的TCP UDP端口 设置密码 3 Step 3 client连接server
  • #ifndef/#define/#endif使用详解

    问题 想必很多人都看过 头文件中的 ifndef define endif 防止该头文件被重复引用 但是是否能理解 被重复引用 是什么意思 是不能在不同的两个文件中使用include来包含这个头文件吗 如果头文件被重复引用了 会产生什么后果
  • Linux系统安全——NAT(SNAT、DNAT)

    目录 NAT SNAT SNAT实际操作 DNAT DNAT实际操作 NAT NAT network address translation 支持PREROUTING INPUT OUTPUT POSTROUTING四个链 请求报文 修改源
  • magma测试与安装,使用(含docker配置)

    作者Ubuntu 18 04 Docker的配置与安装 Docker更改镜像源 docker下载ubuntu docker运行进入容器 通过Dockfile更改docker中ubuntu的apt源 docker容器中的ubuntu的配置 下
  • Macbook(M2 Air) 使用笔记/经验分享

    文章目录 如何选择配置 如何看待溢价 目前体验感受 目前玩过游戏 目前续航体验 如何选择配置 教育优惠时只看到了8 256版本 在开了下列软件时遇到了内存压力瓶颈 若您有生产力需求请16 512起步 IDEA 社区版用于Java Sprin
  • Java菜鸟教程 面向对象初步(一)

    最近 笔者初步接触了java中 面向对象 的概念 在此做一下简单的分享 简单的介绍 一开始的编程软件如c语言 是属于 面向过程 的编程软件 当事件比较简单 可以利用线性的思维解决的时候 面向过程 的语言和 面向对象 的语言都可以解决这些问题
  • linux socket的阻塞和非阻塞设置方法

    非阻塞IO 和阻塞IO 在网络编程中对于一个网络句柄会遇到阻塞IO 和非阻塞IO 的概念 这里对于这两种socket 先做一下说明 基本概念 阻塞IO socket 的阻塞模式意味着必须要做完IO 操作 包括错误 才会 返回 非阻塞IO 非