一、socket缓冲区

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

以下用write()/send()表示写数据/发送数据,read()/recv() 表示读数据/接收数据进行说明。

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

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

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

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

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

二、阻塞模式

对于TCP套接字(默认情况下),当使用 write()/send() 发送数据时:

  • 首先会检查缓冲区,如果缓冲区的可用空间长度小于要发送的数据,那么 write()/send() 会被阻塞(暂停执行),直到缓冲区中的数据被发送到目标机器,腾出足够的空间,才唤醒 write()/send() 函数继续写入数据。
  • 如果TCP协议正在向网络发送数据,那么输出缓冲区会被锁定,不允许写入,write()/send() 也会被阻塞,直到数据发送完毕缓冲区解锁,write()/send() 才会被唤醒。
  • 如果要写入的数据大于缓冲区的最大长度,那么将分批写入。
  • 直到所有数据被写入缓冲区 write()/send() 才能返回。

当使用 read()/recv() 读取数据时:

  • 首先会检查缓冲区,如果缓冲区中有数据,那么就读取,否则函数会被阻塞,直到网络上有数据到来。
  • 如果要读取的数据长度小于缓冲区中的数据长度,那么就不能一次性将缓冲区中的所有数据读出,剩余数据将不断积压,直到有 read()/recv() 函数再次读取。
  • 直到读取到数据后 read()/recv() 函数才会返回,否则就一直被阻塞。

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

socket缓冲区以及阻塞模式(七)的更多相关文章

  1. socket缓冲区以及阻塞模式

    socket缓冲区 每个 socket 被创建后,都会分配两个缓冲区,输入缓冲区和输出缓冲区. write()/send() 并不立即向网络中传输数据,而是先将数据写入缓冲区中,再由TCP协议将数据从 ...

  2. 基于C++简单Windows API的socket编程(阻塞模式)

    1. 概述:简单的基于Windows API的socket点对点聊天程序,为了方便初学者,本文代码均采用阻塞原理编写. 2. 代码样例 Server.cpp(服务端) #include <cst ...

  3. Python socket(TCP阻塞模式)基础程式

    前置知识:Python基础语法,socket库 tips: 1. 默认HOST_IP:127.0.0.1 2. 默认HOST_PORT:7676 参考代码: 1. 客户端程式 #!/usr/bin/e ...

  4. socket异步通信-如何设置成非阻塞模式、非阻塞模式下判断connect成功(失败)、判断recv/recvfrom成功(失败)、判断send/sendto

    socket异步通信-如何设置成非阻塞模式.非阻塞模式下判断connect成功(失败).判断recv/recvfrom成功(失败).判断send/sendto 博客分类: Linux Socket s ...

  5. 看到关于socket非阻塞模式设置方式记录一下。

    关于socket的阻塞与非阻塞模式以及它们之间的优缺点,这已经没什么可言的:我打个很简单的比方,如果你调用socket send函数时: 如果是阻塞模式下: send先比较待发送数据的长度len和套接 ...

  6. Socket阻塞模式和非阻塞模式的区别

    简单点说: 阻塞就是干不完不准回来,    非组赛就是你先干,我现看看有其他事没有,完了告诉我一声 我们拿最常用的send和recv两个函数来说吧... 比如你调用send函数发送一定的Byte,在系 ...

  7. Python Socket单线程+阻塞模式

    Python之旅]第五篇(二):Python Socket单线程+阻塞模式 python Socket单线程 Socket阻塞模式 串行发送 摘要:  前面第五篇(一)中的一个Socket例子其实就是 ...

  8. 服务器编程心得(四)—— 如何将socket设置为非阻塞模式

    1. windows平台上无论利用socket()函数还是WSASocket()函数创建的socket都是阻塞模式的: SOCKET WSAAPI socket( _In_ int af, _In_ ...

  9. UE4 Socket多线程非阻塞通信

    转自:https://blog.csdn.net/lunweiwangxi3/article/details/50468593 ue4自带的Fsocket用起来依旧不是那么的顺手,感觉超出了我的理解范 ...

随机推荐

  1. vue-cli2 打包

    npm run build 打包安装 相当于静态资源 解决vue-cli项目打包出现空白页和路径错误的问题 路径错误的问题解决方式: 打开config文件夹下的 index.js 找到如下图所示区域: ...

  2. bioawk

    https://github.com/lh3/bioawk 1.基本思想 使用: usage: bioawk [-F fs] [-v var=value] [-c fmt] [-tH] [-f pro ...

  3. CF-weekly4 F. Kyoya and Colored Balls

    https://codeforces.com/gym/253910/problem/F F. Kyoya and Colored Balls time limit per test 2 seconds ...

  4. 机器学习之KNN

    KNN做回归和分类的主要区别在于最后做预测时候的决策方式不同.KNN做分类预测时,一般是选择多数表决法,即训练集里和预测的样本特征最近的K个样本,预测为里面有最多类别数的类别.而KNN做回归时,一般是 ...

  5. strcasecmp()函数

    函数介绍: strcasecmp用忽略大小写比较字符串.,通过strcasecmp函数可以指定每个字符串用于比较的字符数,strncasecmp用来比较参数s1和s2字符串前n个字符,比较时会自动忽略 ...

  6. html点击弹出QQ添加好友的窗口

    <a href="tencent://AddContact/?fromId=50&fromSubId=1&subcmd=all&uin=1377732948&q ...

  7. SpringBoot入门-SpringBoot性能优化

    SpringBoot启动优化 显示声明扫包范围: 即不使用@SpringBootApplication默认扫包,使用@ComponentScan(basePackages = { "com. ...

  8. idea配置热加载

    第一步:添加依赖 spring-boot项目中引入如下依赖 <dependency> <groupId>org.springframework.boot</groupId ...

  9. springboot只能一个main方法解决办法

    pom.xml修改properties,增加这行 <start-class>com.eshore.main.SpringBootStarter</start-class> 或者 ...

  10. ASP.NET MVC 中枚举生成下拉框

    最近公司在开发财务系统,在工作中遇到不少的地方需要下拉框. 但是枚举框中数据的内容又来自枚举. 枚举代码如下: public class EnumDemo { public enum Value { ...