Socket缓冲区,可读可写条件

news2024/7/6 20:38:00

一 socket缓冲区

每个 socket 被创建后,都会分配两个缓冲区,输入缓冲区和输出缓冲区。

write()/send() 并不立即向网络中传输数据,而是先将数据写入缓冲区中,再由TCP协议将数据从缓冲区发送到目标机器。一旦将数据写入到缓冲区,函数就可以成功返回,不管它们有没有到达目标机器,也不管它们何时被发送到网络,这些都是TCP协议负责的事情。

TCP协议独立于 write()/send() 函数,数据有可能刚被写入缓冲区就发送到网络,也可能在缓冲区中不断积压,多次写入的数据被一次性发送到网络,这取决于当时的网络情况、当前线程是否空闲等诸多因素,不由程序员控制。

read()/recv() 函数也是如此,也从输入缓冲区中读取数据,而不是直接从网络中读取。

在这里插入图片描述

这些I/O缓冲区特性可整理如下:

I/O缓冲区在每个TCP套接字中单独存在;
I/O缓冲区在创建套接字时自动生成;
即使关闭套接字也会继续传送输出缓冲区中遗留的数据;
关闭套接字将丢失输入缓冲区中的数据。

输入输出缓冲区的默认大小一般都是 8K,可以通过 getsockopt() 函数获取:

unsigned optVal;
int optLen = sizeof(int);
getsockopt(servSock, SOL_SOCKET, SO_SNDBUF, (char*)&optVal, &optLen);
printf("Buffer length: %d\n", optVal);

运行结果:
Buffer length: 8192

对于TCP套接字(默认情况下),当使用 write()/send() 发送数据时:
1 首先会检查缓冲区,如果缓冲区的可用空间长度小于要发送的数据,那么 write()/send() 会被阻塞(暂停执行),直到缓冲区中的数据被发送到目标机器,腾出足够的空间,才唤醒 write()/send() 函数继续写入数据。

2 如果TCP协议正在向网络发送数据,那么输出缓冲区会被锁定,不允许写入,write()/send() 也会被阻塞,直到数据发送完毕缓冲区解锁,write()/send() 才会被唤醒。

3 如果要写入的数据大于缓冲区的最大长度,那么将分批写入。

4 直到所有数据被写入缓冲区 write()/send() 才能返回。

当使用 read()/recv() 读取数据时:
1 首先会检查缓冲区,如果缓冲区中有数据,那么就读取,否则函数会被阻塞,直到网络上有数据到来。

2 如果要读取的数据长度小于缓冲区中的数据长度,那么就不能一次性将缓冲区中的所有数据读出,剩余数据将不断积压,直到有 read()/recv() 函数再次读取。

3 直到读取到数据后 read()/recv() 函数才会返回,否则就一直被阻塞。

4 这就是TCP套接字的阻塞模式。所谓阻塞,就是上一步动作没有完成,下一步动作将暂停,直到上一步动作完成后才能继续,以保持同步性。

二 Socket 的可读可写条件 与 select()

接收缓存区低水位标记(用于读)
发送缓存区低水位标记(用于写)
每个套接字有一个接收低水位和一个发送低水位。他们由select函数使用。

接收低水位标记是让select返回"可读"时套接字接收缓冲区中所需的数据量。对于TCP,其默认值为1。

发送低水位标记是让select返回"可写"时套接字发送缓冲区中所需的可用空间。对于TCP,其默认值常为2048.

通俗的解释一下,缓存区我们当成一个大小为 n bytes的空间,那么:
接收区缓存的作用就是,接收对面的数据放在缓存区,供应用程序读。当然了,只有当缓存区可读的数据量(接收低水位标记)到达一定程度(eg:1)的时候,我们才能读到数据,不然不就读不到数据了吗。

发送区缓存的作用就是,发送应用程序的数据到缓存区,然后一起发给对面。当然了,只有当缓存区剩余一定空间(发送低水位标记)(eg:2048),你才能写数据进去,不然可能导致空间不够。

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

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

相关文章

从0到0.1学习 maven(一:概述及简单入门)

文章目录概述从没用的有趣小知识开始Maven是什么?为什么用Maven?使用与配置入门目录结构编写pom使用Archetype生成骨架小彩蛋:直接运行包含main的jar概述 从没用的有趣小知识开始 Maven可以翻译成“知识的累积”,“专家/行家”。…

数据质量管理深入浅出

质量是生活中最常关注的话题,我们都期望享用高质量的商品与服务,且企业也不断加大质量管理的投入,为了更好的用户体验。 在企业数字化转型浪潮下,传统手段已无法应对数字化转型中的数据质量管理需求,我们需要探索出一条…

千万级数据,如何做性能优化?分库分表、Oracle分区表?

目录一、Oracle是如何存储数据的?1、逻辑存储与物理存储2、进一步分析它们之间的关系3、Oracle逻辑数据块(1)块头(2)行数据(3)可用空间(4)致块头增长的原因有&#xff1a…

关于我给dumi2.0提pr的完整记

前言 博主最近一年时间在工作业余都在写开源组件库 concis ,其中文档站点生成框架采取了 dumi,前几天不久dumi2.0正式发布,博主也是顺势而为直接把项目升级(dumi1 -> dumi2) 由于dumi2 的站点设计比原来好看太多了…

备忘:收藏栏式的主页

作为从DOS时代过来的骨灰,早期的 Window 出于各种原因需要重装,而重装之后IE的收藏夹全丢了(不可能每次重装之前备份了收藏夹)。所以编程把收藏夹提取出来(当时就是目录结构下的 .lnk 文本内容)转为 myfav.html 作为主页,(不备份目录是为了)方…

eclipse快捷键

Eclipse常用快捷键1几个最重要的快捷键代码助手:CtrlSpace(简体中文操作系统是Alt/)快速修正:Ctrl1单词补全:Alt/打开外部Java文档:ShiftF2显示搜索对话框:CtrlH快速Outline:CtrlO打开资源&…

python时间-time模块

time是python自带的模块,用于处理时间问题,提供了一系列的操作时间的函数。 以下说明针对于 python2.7,其他版本可能有所差异。 模块提供了两个种表示时间的格式: 1.时间戳,是以秒表示从“新纪元”到现在的时间&#x…

代码随想录训练营第16天|104.二叉树的最大深度 559.n叉树的最大深度 ● 111.二叉树的最小深度 ● 222.完全二叉树的节点个数

104 二叉树的最大深度 看完题后的思路 后续遍历 深度 f(root)终止条件 rootnull return 0递归 if rootnullreturn 0; leftf(root.left); rightf(root.right); return max(left,right)1;思路 节点深度: 该节点到根节点的节点数,某个节点的深度一次就能求出来 节点高度:该节点…

爱因斯坦求和约定:torch/np.enisum

结论:爱因斯坦求和约定就是用来省略求和符号的;所以它的本质是求和运算,它并不能决定具体的运算到底是矩阵乘法,还是内积外积之类的,它所涉及的所谓的矩阵乘法之类的,其实是人为定义的,和它自身…

Java 并发编程(Ⅰ)

目录1. 概念1. 基本概念2. 线程的状态2. 线程的初始化1. new Thread()2. new Thread(new Runnable())3. Thread 和 Runnable 的关系4. new Thread(new FutureTask(new Callable()))3. 常用方法1. start1. 线程组2. start 和 run2. sleep1. TimeUtil2. InterruptedException3. s…

DCMM数据管理能力成熟度认证详解

第一部分:评估基础篇 First part DCMM定义 DCMM是《数据管理能力成熟度评估模型》GB/T 36073-2018国家标准,英文简称:(Data management Capability Maturity Model)。是我国首个数据管理领域正式发布的国家标准。旨在帮…

【ZooKeeper】

1.ZooKeeper是什么? 答: ZooKeeper是一个开放源码的分布式协调服务,它是集群的管理者,监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操作。最终,将简单易用的接口和性能高效、功能稳定的系统提供给用户…

100 家企业软件测试笔试面试题汇总(网友真实面试后征集)

目录 一、中科软 二、AURALOG 笔试面试(外企) 三、GWebs 公司笔试题 四、北京麒麟网信息技术有限公司笔试题 五、施惠特 六、总结 一、中科软 笔试题 1.谈谈你对测试的理解2.你三年的职业规划3.你对加班的看法?是否可以加班?4.你心…

推荐系统遇上深度学习(一四二)-[微软复旦]CTR预估中的对比学习框架CL4CTR

今天分享的论文为《CL4CTR: A Contrastive Learning Framework for CTR Prediction》,从特征表示角度入手,将多种对比学习损失引入到CTR预估的模型训练中,一起来看一下。1、背景主流的CTR预估模型大致可以分为两类,一类是传统的模…

【软件测试】遇到新产品的测试就懵了?这三部曲带你轻松快速上手新业务......

目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜)前言 初入一家公司&#…

FreeRTOS互斥量的实验

互斥量又称互斥信号量(本质是信号量),是一种特殊的二值信号量,它和 信号量不同的是,它支持互斥量所有权、递归访问以及防止优先级翻转的特性, 用于实现对临界资源的独占式处理。本章要实现的功能是&#xf…

算法训练营 day24 回溯算法 回溯算法理论基础 组合

算法训练营 day24 回溯算法 回溯算法理论基础 组合 回溯算法理论基础 回溯法也可以叫做回溯搜索法,它是一种搜索的方式。 虽然回溯法很难,很不好理解,但是回溯法并不是什么高效的算法。 因为回溯的本质是穷举,穷举所有可能&am…

钉钉微应用 - - - - 如何本地开发调试?

钉钉微应用 - 本地开发调试1. 安装DingTalk-Design-CLI2. 初始化代码模版3. 启动开发、调试功能4. 遇到的问题4.1 对应企业没有xxx域名微应用??4.2 history、location的表现异常??4.3 本地已经存在了H5微应用,也想使用…

软件体系结构与架构技术知识点万字总结

文章目录页面技术一、Spring框架1. 三层体系架构2. Spring的核心3. Spring 的Bean中主要的装配方式(1)基于XML的装配:(2)基于Annotation的装配:(3)自动装配:4. Spring框架…

Linux 中启用 SSH 密码登录

Linux 中启用 SSH 密码登录 文章目录Linux 中启用 SSH 密码登录1、更改配置文件2、设置登录密码3、完成1、更改配置文件 首先使用 管理员 权限打开/etc/ssh/sshd_config文件。 sudo vi /etc/ssh/sshd_config找到 PasswordAuthentication 选项,耐心查找。 当然&am…