【网络通信】关于TCP阻塞和非阻塞方式的总结

2023-05-16

关于TCP阻塞和非阻塞方式的总结

1、引言

在网络编程时,我们需要注意创建的socket是阻塞状态还是非阻塞状态的,这两种状态在编程时,对于每一个socket系统调用函数(connect、send、sendto、recv、recvfrom)都有一定的影响,socket的阻塞和非阻塞状态可以在每一个socket系统调用调用之前设置,对应着每一个socket系统调用是否是阻塞和非阻塞的;

2、发送操作:

(1)对于TCP的send系统调用发送数据,如果socket是阻塞的,我们需要这样理解:send操作将会等待所有数据均被拷贝到发送缓冲区后才会返回。
—如果发送缓冲区可用大小为0或者比要发送的数据长度要小,则会阻塞,直到发送缓冲区里的数据被系统发送出去后,可用缓冲区大小比要发送的数据长度大时,send返回成功,否则一直阻塞等待。因此,send返回的发送大小,一定是参数中发送长度的大小。
—例如:如果当前发送缓冲区总大小为8192,个字节,通过send已经拷贝到缓冲区的数据为8000字节,那缓冲区剩余大小为192字节,而现在上层应用需要发送2000字节的数据,那么send就会等待缓冲区足够把所有2000字节数据拷贝进去,如第一次拷贝进去192字节,当缓冲区成功发送出1808字节后,再把上层应用buf中剩余的1808字节拷贝到发送缓冲区,最后send返回成功拷贝到发送缓冲区的字节数。
(2)对于UDP的sendto系统调用发送数据,如果socket是阻塞的,sendto操作不会阻塞,UDP没有真正意义上的发送缓冲区,它只是把应用层的缓冲区数据拷贝到下层的协议栈,在此过程中加UDP头,IP头,所以不存在阻塞。
—UDP是不可靠连接,不必保存应用进程的数据拷贝,应用进程中的数据在沿协议栈向下传递时,以某种形式拷贝到内核缓冲区,当数据链路层把数据传出后就把内核缓冲区中数据拷贝删除。因此它不需要一个发送缓冲区。写UDP套接口的sendto返回表示应用程序的数据或者数据分片已经进入链路层的输出队列,如果输出队列没有足够的空间存放数据,将返回错误EBOBUFS。
—UDP套接口有发送缓冲区大小(SO_SNDBUF修改),不过它仅仅是写到套接口的UDP数据报的大小上限,如果应用程序写一个大于套接口发送缓冲区大小的数据报,内核将返回一个EMSGSIZE错误。
(3)对于TCP的send系统调用,如果socket是非阻塞的,send会立即返回。
—例如,当发送缓冲区中有192字节,但是需要发送2000字节,此时send调用立即返回,并且返回值为192。因此,非阻塞send仅仅是尽自己的能力向发送缓冲区拷贝尽可能多的数据。如果发送缓冲区剩余空间为0,这时send立即返回,send返回值为EAGAIN,这是应用层最好休息一下再尝试发送。
(4)对于UDP的sendto系统调用发送数据,如果socket是非阻塞的,sendto操作不会阻塞,跟阻塞方式一致的。

3、接收操作:

(1)在阻塞socket模式下,recv/recvfrom会一直阻塞到接收缓冲区里有一个字节或者一个完整的UDP数据报为止,然后再返回。
—如果socket发送缓冲区中有数据,或者接收缓冲区中无数据,或者协议正在接收数据,socket都阻塞等待,直到有数据拷贝到用户程序中,然后返回拷贝的字节数。(协议接收到的数据长度可能大于buf的长度(recvbuf长度),需要调用几次recv函数才能把socket接收缓冲区中的数据拷贝完)。
(2)在非阻塞socket模式下,recv/recvfrom会立即返回。
—如果接收缓冲区有任何一个字节数据(TCP)或者一个完整的UDP数据报,它们将会返回接收到的数据大小;如果缓冲区没有数据,则直接返回错误EWOULDBLOCK或者EGAIN,表示没有数据,休息一会儿再次接收操作。

4、连接操作:

(1)TCP的连接需要进行一个三路握手,调用tcp connect函数一直要等到调用方收到对于自己的SYN(同步TCP请求)的ACK为止才返回,因此,如果当前socket是阻塞方式的话,TCP的connect总会阻塞其调用至少一个到服务器的RTT的时间才返回。
(2)如果对一个非阻塞的socket,调用TCP connect建立连接,并且连接不能立即建立,这时connect会返回一个EINPROGRESS的错误,表示连接正在建立中,这种情况,后续需要使用select函数在检查连接建立成功。(这里套接字是非阻塞的,如果连接的服务器在同一个主机上,我们的connect调用可能会使连接立即建立成功)

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

【网络通信】关于TCP阻塞和非阻塞方式的总结 的相关文章

  • c 内存管理

    其他相关链接 xff1a https blog csdn net wind19 article details 5964090 一 几个基本概念 在C语言中 xff0c 关于内存管理的知识点比较多 xff0c 如函数 变量 作用域 指针等
  • Springboot操作MongoDB,包括增改查及复杂操作

    单条件查询 使用BasicDBObject配置查询条件 List span class token generics function span class token punctuation lt span AbstractMongoEn
  • 搭建Spark实战环境(3台linux虚拟机集群)(一)样板机的搭建

    系统及软件配置 系统配置 内存 xff1a 16g 2400 cpu xff1a i5 9400F 软件配置 Windows 10 1903版本VMware workstation 15 10CentOS centos release 7
  • 独立个人项目开发心得 - 任务切分、挑战性、实用性和半途而废

    在写文章前容许我啰嗦一下 xff1a 对于软件开发 xff0c 我走了不少弯路 xff0c 有时觉得自己作为API侠 xff0c 无所不能 xff0c 有时又觉得自己很多LeetCode题写不出来 xff0c 无能为力 我有一个博客 xff
  • 传统软件服务器与游戏服务器架构区别

    项目智能客服爬虫SLG游戏语言javapythonkotlin模型异步事件驱动可能没什么模型可言actor模型传输协议httphttptcp 43 netty传输结构jsonjsonprotobuf数据库oracle xff0c redis
  • Linux C++ Socket实战

    本文主要介绍Linux C 43 43 基础Socket网络编程 大部分知识来自于网站 xff1a https www geeksforgeeks org socket programming cc Socket编程状态图 从图中可以看到
  • CSAPP第二章-信息的表示与处理-随手记

    仅作为学习 深入理解计算机系统 第二章时的笔记 xff0c 仅记录对自己有启发的部分 xff0c 不作为知识整理 xff08 直接看电子书就可以了 xff09 因为这本书知识点非常多 xff0c 所以我会抽时间多次阅读 xff0c 本文也会
  • Vue的路由配置及手动改地址栏为啥又跳转回来??

    vue cli xff08 vue脚手架 xff09 超详细教程 xff1a https blog csdn net wulala hei article details 85000530 这个教程里面是使用 vue init webpac
  • GPS卫星轨道

    GPS卫星轨道周期几乎是24小时 xff0c 而自己的卫星在太阳同步轨道上的周期大概是1 5个小时 xff0c 那么就是说太阳同步轨道已经绕几周了 xff0c GPS卫星才饶一周 所以当算多普勒频移的时候只需要算出GPS一个周期时间内的多普
  • 快速了解S7-1200 PLC的存储器及存储区的寻址方式

    S7 1200 PLC的存储器地址包括输入I 输出Q 位存储器M 数据块DB xff0c 以及本地或临时存储器L eg xff1a 标识存储区M0 0 MB0 MW0 MD0 分别是 B位 字节B 8位 字W 16位 双字D 32位 输入过
  • 网络编程之UDP简单示例

    UDP编程函数recvfrom inet pton sendto UDP协议 user data protrol 用户数据协议特点 xff1a TCP xff1a 面向连接 gt 一定双方连接上了才能进行通信 xff01 UDP xff1a
  • 微信开发(二)http请求工具类

    说明 进行微信开发 xff0c 后台程序需要与微信服务器进行交互 xff0c 通过调用接口来完成服务 xff0c 阅读微信开发文档 xff0c 发现接口的调用都是通过http请求进行的 xff0c 所以必须有个HttpUtil来支撑 xff
  • STM32寄存器与结构体

    piaolin 发表于 2015 9 30 01 02 只看该作者 倒序浏览 阅读模式 第16集 蜂鸣器实验 这个实验和流水灯是一样的 xff0c 只是将相对应的IO口拉高拉低即可控制蜂鸣器 值得注意的是电路设计方面 xff0c 根据视频描
  • 字节序

    1 字节序 字节序 xff0c 又称端序或尾序 xff0c 指的是多字节数据在内存中的存放顺序 例如一个int型变量x占用4个字节 xff0c 假设它的起始地址 amp x为0x10 xff0c 那么x将会被存储在 0x10 0x11 0x
  • extern “C“的作用及理解

    1 意图 extern 34 C 34 是C 43 43 特有的指令 xff08 C无法使用该指令 xff09 xff0c 目的在于支持C 43 43 与C混合编程 2 作用 extern C 的作用是告诉C 43 43 编译器用C规则编译
  • Linux命令 nautilus

    nautilus是GNOME桌面下的一个文件管理工具 通过这个命令我们可以在终端下非常方便的打开指定目录的文件 nautilus 命令后面一个 xff0c 表示当前目录 命令模式为 nautilus pwd支持绝对路径和相对路径两种方式 x
  • windows下C语言实现TCP通信

    编译器 xff1a vs2017 语言 xff1a c语言 具体的原理可以在其他博客看到 在我学习winsock编程时 xff0c 发现那些博客代码居然在我机器上没一个能运行 xff0c 可能是我水平有限 于是我根据winsock相关知识
  • 关于USB转串口型设备的latency问题

    USB转串口型设备在通讯时默认有16ms延时 xff0c 这在控制任务中往往是不能接受的 xff0c 为了改善这个情况需要改变latency的值为最小值1 在Windows环境下 xff0c 可以如下操作 xff1a 右键属性 端口设置 高
  • 航模lipo锂电池过放抢救/处理方式

    实验室用的tattu航模电池经常因为疏忽导致过放 xff0c 逐渐也摸索出来过放的抢救方法 当然最好的方法还是不要过放 xff1a xff09 1 首先是检查电池剩余电压 xff0c 用普通的电压表就可以了 xff0c 今天刚搞崩了了一块
  • 基于DCT+huffman变换的图像压缩解压缩FPGA实现

    目录 一 理论基础 二 verilog程序 三 仿真结果 一 理论基础 整个算法涉及到DCT变换和Huffman编码两个部分 其整体流程图如下所示 nbsp 这里 我们将做三个方面的工作

随机推荐