当前位置: 首页 > article >正文

为什么说Tcp是面向字节流的以及(Tcp粘包问题、TCP/UDP对比、listen函数的backlog参数的意义)

为什么说Tcp是面向字节流的:

Tcp通信的本质是创建一个tcp的socket,同时就会对应的创建一个发送缓冲区和接收缓冲区。

  • 调用write时, 数据会先写入发送缓冲区中;
  • 如果发送的字节数太长, 会被拆分成多个TCP的数据包发出
  • 如果发送的字节数太短, 就会先在缓冲区里等待, 等到缓冲区长度差不多了, 或者其他合适的时机发送出去
  • 接收数据的时候, 数据也是从网卡驱动程序到达内核的接收缓冲区;然后应用程序可以调用read从接收缓冲区拿数据;
  • 另一方面, TCP的一个连接, 既有发送缓冲区, 也有接收缓冲区, 那么对于这一个连接, 既可以读数据, 也可以写数据. 这个概念叫做 全双工
  • 而其中的缓冲区,因为本质就是数组,而从数组上进行读、写操作,和河流比较像在流中进行数据的读取和写入!

Tcp协议的粘包问题

tcp协议将数据都放到了缓冲区中,而缓冲区中具体有几个报文是不确定的(因为发送的数据可大可小,可能一次报文就能把数据全部发过来,也可能一次只能发送半个 。。。),所以就类似于粘着的样子,对此我们就需要将数据分出来
对此就需解决上述问题,方案:

  1. 对于变长的包, 还可以在包和包之间使用明确的分隔符(应用层协议, 是程序猿自己来定的, 只要保证分隔符不和正文冲突即可在。报文特殊字符(\r\n)。
  2. 对于定长的包, 保证每次都按固定大小读取即可; 例如上面的Request结构, 是固定大小的, 那么就从缓冲区从头开始按sizeof(Request)依次读取即可。定长报文(确定报文长度)。
  3. 通过组合的策略解决问题
  4. 而对于UDP来说就不会有这种问题,因为UDP有明确的数据边界,并且站在应用层来看使用UDP的时候要么收到完整报文,要么不收。

TCP/UDP对比

  • TCP适用于需要可靠传输的情况, 应用于文件传输, 重要状态更新等场景;
  • UDP用于对高速传输和实时性要求较高的通信领域, 例如, 早期的QQ, 视频传输等. 另外UDP还可以用于广播
  • 各自有各自的优点,TCP的可靠性是中性词表示着它们适用于不同的场景。

用UDP如何实现可靠传输(经典面试题)

其实就是参考TCP协议实现可靠性的办法

  1. 超时重传,若隔一段时间后没收到应答,就重发数据
  2. 序列号,确保数据顺序,以及去除重复的数据
  3. 确认应答,确认数据确实发送过去

连接其他机器指令:telnet

telnet + ip + port

TCP层面相关实验理解listen的第二个参数backlog

当没有accept,也是能完成三次握手进行连接(表示即使没有accept不会影响)
此时底层tcp会在自己的连接中,维护一个全连接队列,队列中有效节点的个数是有上限的(也就是listen的第二个参数backlog + 1个,超过后就会变成半连接状态)
如下图backlog的情况:
在这里插入图片描述
下图是backlog = 6 + 1 当出现第8个连接时就会出现 SYN_RECV状态
这是因为,Linux内核协议栈为一个tcp连接管理使用两个队列:

  1. 半链接队列(用于保存处于SYN_SENT和SYN_RECV状态的请求)
  2. 全链接队列(Accept队列)用于保存established状态,但是应用层没有调用accept取走的请求

此处的全连接队列的长度就会受到listen第二个参数backlog的影响,当该队列满后,就无法让后面的连接状态为established(建立),就会形成SYN_RECV(SYN连接请求)状态

在这里插入图片描述
该半连接状态并不会持续很久,它会等待一会尝试连接,当有全连接状态退出时,就能变成全连接状态,否则就会消失


http://www.kler.cn/news/363975.html

相关文章:

  • Node.js实现文件上传下载
  • C#探索之路基础夯实篇(6):C#在Unity中的自定义特性
  • rootless模式下istio ambient鉴权策略
  • 面经之一:Synchronized与ReentrantLock区别
  • python pandas 1
  • nginx------HTTP模块配置详解
  • Kafka高可用性原理深度解析
  • 信息安全工程师(69)数字水印技术与应用
  • k8s-service详解
  • 使用python,自动实现将多个 JPG 文件转换为一个 PDF 文件
  • 11106 操作(c)
  • 【动态规划】子序列问题(上)
  • yarn的安装与使用以及与npm的区别(安装过程中可能会遇到的问题)
  • 动态规划-动归基础
  • 基于neo4j的新冠治疗和新冠患者轨迹的知识图谱问答系统
  • Hallo2 长视频和高分辨率的音频驱动的肖像图像动画 (数字人技术)
  • k8s 配置私有镜像仓库认证
  • repo将每个仓库回退到第一个commit的状态
  • 工具_Nginx
  • 学习记录:js算法(七十四):跳跃游戏II
  • Linux 移植_Home_Record
  • 【Linux系统】缺页中断机制
  • springboot餐厅点餐系统
  • hi3536上ffmpeg带rtmp移植
  • 【C++复习】经典笔试题
  • 【Linux系统内核探索】进程调度