【Linux后端服务器开发】TCP协议

news2024/10/5 13:03:25

目录

一、TCP报头结构

二、确认应答机制

三、超时重传机制

四、连接管理机制

五、滑动窗口

六、拥塞控制

七、应答策略


一、TCP报头结构

TCP全称为传输控制协议(Transmission Control Protocol),数据在传输过程需要严格的控制

TCP协议段落格式

4位TCP报头长度:表示该TCP头部有多少个32位bit,TCP报头的最大长度是 15 * 4B = 60B;TCP报头的标准长度是20字节,即在通信时拿到TCP数据后会先读取20个字节,将其转换成一个结构化数据之后,从标准报头中提取4位首部长度,得到完整报头长度(20~60字节)

完整报头 = 标准报头 + 选项

6个标志位

  • FIN:通知对方,本端要关闭了,携带FIN标识的是结束报文段
  • SYN:请求建立连接,携带SYN标识的是同步报文段
  • RST:对方要求重新建立连接,携带RST标识的是复位报文段
  • PSH:催促接收端应用程序立刻从TCP缓冲区把数据读走
  • ACK:确认序号是否有效
  • URG:紧急指针是否有效

16位检验和:发送端填充,CRC校验。接收方校验不通过,则数据丢弃。此处的检验和不光包含TCP首部,还包含TCP数据

16位紧急指针:紧急数据(1字节)的偏移量

32位序号&&32位确认信号:发送数据的编号&&应答数据的编号,防止数据丢包和乱序

16位窗口大小:填入自己的接收缓冲区的剩余空间的大小,让对方控制数据发送速度(流量控制

由于TCP是面向字节流传输,故TCP报头里面不包含有效载荷的长度。

TCP数据解包过程(传输层 ---> 应用层,报头和有效载荷分离)

TCP添加报头和UDP类似,将数据拷贝之后,在数据的前端添加结构化数据。

二、确认应答机制

网络传输和本地传输的本质区别就是数据的传输距离变长,这就引发了数据传输的可靠性问题。

当数据的传输距离变长,就容易出现丢包、乱序、校验错误、重复等情况,这些就是不可靠问题。

在网络通信中,如何确定通信的可靠性?收到应答,才能100%确定对方收到信息!

双方通信中,一定存在最新的消息,没有应答——最新的消息无法保证可靠性!

让最新的信息作为确认信息,保证历史信息的可靠性。

无论是是client向server发数据,还是server向client发数据,每一条数据都需要应答单一数据应答或者批量数据应答

数据应答的顺序和数据发送的顺序一样吗?未必一样,故每条数据都需要编号,来使每条应答都能对应到发送的数据(防止乱序和丢包) 

确认应答&&确认序号:接收方已经收到了ACK序号之前的所有(连续)的报文

序号&&确认序号,为什么要有两组信号?全双工,从TCP协议角度,client端和server端地位对等,通信本质都是数据的发送和应答(不再是请求和响应)

通信双方都有自己的发送缓冲区接收缓冲区,以实现全双工通信

接收缓冲区的本质是一个队列queue,保证数据的按序到达

TCP报文也是有类型的!

TCP的报文通过6个标志位区分类型,服务器会收到各种各样的TCP报文,根据报文的不同类型做不同处理。

  • SYN:同步序标志,进行三次握手建立连接
  • FIN:结束序号标志,进行四次挥手断开连接
  • ACK:确认信号标志,在3次握手成功之后,所有通信数据报的ACK都置1,承担对历史数据报可靠性的确认
  • PSH:推送序号标志,催促接收方尽快读取数据(尽可能让read/recv执行)
  • URG:紧急序号标识,需要被特殊处理的数据(尽快读取,插队处理),由紧急指针表示偏移量,紧急指针指向的数据只有1字节(进行TCP通信之外的管理工作)
  • RST:复位标志位,reset,处理双方链接认知不一致问题,使链接重新建立

三、超时重传机制

  • 数据丢包:主机A给主机B发送数据之后,可能因为网络拥堵等原因,数据无法到达主机B。如果主机A在一个特定的时间间隔内没有收到主机B的确认应答,就会重发数据。
  • 应答丢包:主机A给主机B发送数据成功,但是主机B收到数据之后发送给主机A的确认应答丢包了,导致了主机A在特定的时间间隔内没有收到主机B的确认应答,主机A仍会重发数据。

在发送方发送数据之后,在特定的时间间隔内没有收到确认应答,于是重发数据,这就是超时重传机制。其实发送过程中的数据究竟有没有丢包,发送方并不知道,所以策略就是超时没有收到确认应答就认为是丢包了。

因此接收方很可能会收到很多重复数据,那么怎么处理呢?因此TCP需要能够识别处重复的数据报,并且把重复数据丢弃,这就需要通过数据序号去重。

发送方发出去的数据,不能立刻移除,而是必须维持一段时间(收到确认应答之后再移除),数据维持在哪里?发送缓冲区。(计算里的数据移除,通常是覆盖,通过标志位限制缓冲区的有效性)

在超时重传机制中,特定的时间间隔与网络通信的效率相关联,我们如何设置确认信号的超时等待时间呢?最理想的情况下,找到一个最小的时间间隔,保证正常通信的确认应答信号一定能够在这个时间内返回。但是这个时间的长短,随着网络环境的不同,存在差异。

  • 如果超时时间设置太长,会影响整体的数据重传效率
  • 如果超时时间设置太短,有可能会频繁的发送重复的数据包

TCP为了保证无论在任何环境下都能比较高性能的通信,因此会动态计算这个最大超时时间

  • Linux中(BSD Unix和Windows也是如此), 超时以500ms为一个单位进行控制, 每次判定超时重发的超时时间都是500ms的整数倍
  • 如果重发一次之后, 仍然得不到应答, 等待 2*500ms 后再进行重传
  • 如果仍然得不到应答, 等待 4*500ms 进行重传. 依次类推, 以指数形式递增
  • 累计到一定的重传次数, TCP认为网络或者对端主机出现异常, 强制关闭连接
     

四、连接管理机制

服务端状态转换:

  • [CLOSE -> LISTEN]:服务端调用 listen 后进入LISTEN监听状态,等待客户端连接
  • [LISTEN -> SYN_RCVD]:服务端一旦监听到连接请求(同步报文段),就将该连接仿佛内核等待队列中,并向客户端发送SYN+ACK
  • [SYN_RCVD -> ESTABLISHED]:服务端一旦收到客户端的确认报文,就进入ESTABLISHED状态,接下来就可以进行通信了
  • [ESTABLISHED -> CLOSE_WAIT]:当客户端主动关闭连接(调用close),服务端会收到结束报文段,服务器返回确认报文并进入CLOSE_WAIT状态
  • [CLOSE_WAIT -> LAST_ACK]:进入CLOSE_WAIT状态后说明服务器准备关闭连接(需要处理尚未处理完的数据),当服务器真正调用 close 关闭连接时,会向客户端发送FIN,此时服务器进入LAST_ACK状态,等待最后一个ACK到来
  • [LAST_ACK -> CLOSED]:服务器受到了客户端对于与FIN的ACK,彻底断开连接

客户端状态转换:

  • [CLOSED -> SYN_SENT]:客户端调用connect,发送同步报文段
  • [SYN_SENT -> ESTABLISHED]:connect调用成功,则进入ESTABLISHED状态,开始读写数据
  • [ESTABLISHED -> FIN_WAIT_1]:客户端主动调用close时,向服务器发送结束报文段,同时进入FIN_WAIT_1状态
  • [FIN_WAIT_1 -> FIN_WAIT_2]:客户端收到服务器对结束报文段的确认,则进入FIN_WAIT_2,开始等待服务器结束报文段
  • [FIN_WAIT_2 -> TIME_WAIT]:客户端收到服务器发来的结束报文段,进入TIME_WAIT,并发出LAST_ACK
  • [TIME_WAIT -> CLOSED]:客户端要等待一个2MSL(Max Segment Life,报文最大生存时间)的时间,才会进入CLOSED状态

建立连接:三次握手

DDOS攻击:也称肉鸡攻击,黑客将木马病毒大量散播,潜入肉鸡电脑,设置时间在某一时刻同时对某一服务器发起请求,造成服务器资源耗尽而崩溃。

断开连接:四次握手

四次挥手动作完成,主动断开连接的一方为什么会维持一段时间的TIME_WAIT状态?

  1. 保证最后一个ACK尽可能被对方收到
  2. 双方在断开连接的时候,有可能网络中还有滞留的报文,保证滞留报文消散

TIME_WAIT状态一般维持多长时间的TIME_WAIT状态呢?2*MSL,MSL是单向传输数据时消耗的最大时间。

服务器有时候可以立即重启,有时候无法立即重启(bind error),为什么?因为有时候server是主动断开连接的一方,结束通信后进入TIME_WAIT状态。

在server的TCP连接没有完全断开之前不允许重新监听,某些情况下是不合理的:

  1. 服务器需要处理非常大量的客户端的连接(每个连接的生存时间可能很短,每秒都有很大数量的客户端来请求)
  2. 这个时候如果有很多客户端不活跃,就需要被服务器主动关闭连接清理掉,就会产生大量的TIME_WAIT状态连接
  3. 由于对服务器的请求量很大,就可能导致TIME_WAIT状态的连接数很多,每个连接都会占用一个通信五元组(源IP,目的IP,源端口,目的端口,协议),其中服务器的IP和端口是固定的,如果新来的客户端连接的IP和端口号和TIME_WAIT占用的连接重复了,就会问题。

那么我们怎么解决TIME_WAIT状态引起的bind失败问题呢?

在socket套接字创建之后,使用socketopt()设置socket描述符的选项SO_REUSEADDR为1,表示允许创建端口号相同但是IP地址不同的多个socket描述符。

int opt = 1;
setsocketopt(listenfd, SOL_SOCKET, SO_REUSERADDR, &opt, sizeof(opt));

对于服务器上出现大量的TIME_WAIT状态连接,原因就是服务器没有正确close(socket),导致四次挥手没有正常完成,这是一个BUG,需要给每次连接加上正确的close()。

五、滑动窗口

流量控制:接收端处理数据的速度是有限的,如果发送端发送太快导致接收端的缓冲区被写满,这个时候如果发送端继续发送数据,就会造成丢包,继而引起丢包重传等等一些列连锁问题。因此TCP支持根据接收端的处理能力,来决定发送端的发送速度。

  • 接收端将自己剩余的接收缓冲区大小放入TCP首部的“窗口大小”字段,通过ACK通知发送端
  • 窗口大小字段越大,说明网络的吞吐量越高
  • 接收端一旦发现自己的缓冲快满了,就会将窗口大小设置为一个更小的值发送给发送端,发送端读取到这个窗口大小信息之后,就会减慢发送速度
  • 如果接收端的接收缓冲区写满了,就会将窗口大小设置为0,这时发送端不再发送数据,但是需要定期发送一个窗口探测数据段,使接收端把窗口大小告诉发送端

那么第一次数据的发送,发送端如何知道接收端的窗口大小呢?三次握手。

在TCP首部中,有16位窗口大小字段,那么16位数字表示最大范围就是65535字节吗?实际上,TCP首部40字节选项中还包含了一个窗口大小扩大因子M,实际窗口大小是窗口字段的值左移M位。

TCP协议有确认应答机制,对每一个发送的数据段,都要给一个ACK确认应答,收到ACK应答之后再发送下一个数据段,这样就出现了一个缺陷,就是性能较差,尤其是数据往返的时间较长的情况下。

既然串行一发一收的方式性能较低,那么我们就采用并行发送多条数据,再等待多条数据应答的策略,这样就大大的提高了性能(将多个数据段的等待应答时间重叠在一起)。

  • 窗口大小就是指无需等待确认应答而可以继续发送数据的最大值,上图的窗口大小就是3000个字节(假设每个段1000字节)
  • 发送前三个段的时候,无需等待确认应答,直接连续发送
  • 收到第一个ACK之后,滑动窗口向右移动,继续发送第四个段,依次类推
  • OS内核为了维护这个滑动窗口,需要开辟发送缓冲区来记录当前还有哪些数据没有应答,只有确认应答过的数据,才能从缓冲区删除
  • 窗口越大,代表网络的吞吐量越高

在TCP通信过程中,数据分为三种状态:①已经发送并且收到确认应答;②正在发送但是尚未收到确认应答;③没有发送。

滑动窗口里的数据正是第②中状态的数据,已经发送但是尚未收到应答。

窗口的初始大小怎么设置?未来怎么变化? 滑动从窗口的大小与对方的接收能力有关,未来无论怎么滑动,都要保证对方能够正常接收。

窗口一定向右滑动吗?会向左滑动吗?由于左边是已经发送且收到确认应答的数据(需要删除),所以窗口一定不会向左滑动,但是不一定向右滑动,可能长时间保持不动。

窗口大小会一直不变吗?窗口大小是浮动变化的,可能会不变,但不会一直不变,变化的依据是对方的接收能力,当对方的接收缓冲区写满了,窗口大小变为0。

滑动窗口的丢包处理

  1. 数据没丢,应答丢包
  2. 数据丢包

序号&&确认序号也用于支持滑动窗口的规则制定!

我们发送的数据在尚未收到应答之前,需要暂时保证起来以支持超时重传,数据保存在哪?滑动窗口之中!

滑动窗口一直向右滑动,空间不够了怎么办?实际上,滑动窗口数组空间是一个循环队列结构

六、拥塞控制

TCP的可靠性不仅考虑双方主机的问题,还要考虑网络的问题。

如果数据丢包是双方主机的问题,那么会采用超时重传机制;如果数据丢包是网络问题,则不会进行超时重传。

虽然TCP协议通过滑动窗口能够高效可靠的发送大量数据,但是如果在刚开始阶段就发送大量数据仍然可能引发问题。因为网络上有很多计算机,可能当前网络已经进入拥塞状态了,在不清楚当前的网络状态时就贸然发送大量数据,是会加重网络拥塞的。

因此TCP协议引入慢启动机制,在不清楚当前网络状态的情况下,先发送少量数据试探当前网络的拥堵情况,再决定按多快的速度传输数据。

此处引用一个概念是拥塞窗口

  • 开始发送的时候,定义拥塞窗口大小为1,用于试探网络的拥堵状况
  • 每次收到一个ACK应答,拥塞窗口+1
  • 每次发送数据包的时候,将拥塞窗口和接收端主机反馈的窗口做比较,取较小的值作为实际发送的窗口

如此可见,拥塞窗口的增长速度是指数级的,慢启动只是初始速度慢,但是增长速度非常快。

为了不让增长速度过快,因此不能使拥塞窗口每次都是单纯的翻倍。于是设置了一个慢启动的阈值,当拥塞窗口超过阈值的时候,不再按照指数方式增长,而是按照线性方式增长。

  • 当TCP启动的时候,慢启动阈值等于窗口的最大值
  • 当每次发送网络拥塞时,慢启动的阈值降为原来阈值一半,同时拥塞窗口置回1

少量的丢包,触发超时重传机制;大量的丢包,触发拥塞控制机制。

当TCP通信开始后,网络吞吐量会逐渐上升,随着网络发送拥堵,吞吐量立即下降。

拥塞控制,归根结底是TCP协议想尽可能快的把数据传输给对方,但是又要避免给网络造成太大压力的折中方案。

七、应答策略

延迟应答

如果接收主机立刻返回ACK应答,这时候返回的窗口可能比较小

  • 假设接收缓冲区为1M,一次收到500K的数据,如果立刻应答,返回的窗口就是500K
  • 但是实际上可能处理端对数据的处理速度很快,10ms之内就把数据从缓冲区消费掉了
  • 在这种情况下,接收端处理还远没有达到自己的极限,即使窗口再放大一些,也能处理过来
  • 如果接收端稍等一会儿再应答,比如等待200ms再应答,若在此期间上层处理端把数据带走了,这个时候返回的窗口大小就是1M

窗口越大,网络的吞吐量就越大,传输效率就越高,我们的目的是在保证网络不拥堵的情况下尽快提高传输效率。

那么所有的数据包都可以延迟应答吗?并不是

  • 数量限制:每隔N个包就应答一次
  • 时间限制:超过最大延迟时间就应答一次
  • 具体的数量和超时时间,依操作系统的不同存在差异,一般N=2,超时时间=200ms

由于ACK确认序号的精妙设计,故延迟应答中被上层消费掉的数据不需要应答,可以通过应答下一个数据包的确认序号保证正常通信。

捎带应答

在延迟应答的基础上,我们发现,很多情况下,客户端服务器也是“一发一收”的,客户端和服务器之间互相发送和接收数据。

如此ACK就可以搭发送数据的顺风车,在发送给对方数据的时候完成确认应答的功能,因为ACK只是一个标志位,ACK确认序号存在每一个数据的报头里。

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

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

相关文章

CONNECT BY 介绍以及用法

CONNECT BY 介绍以及用法 CONNECT BY作用是,NNECT BY用来查询树形数据, CONNECT BY 语句的用法 语句格式: start with 条件A connect by prior orgid parentorgid 用法 情况1: start with 条件A connect by…

【树链】CF1702 G

Problem - G2 - Codeforces 题意: 思路: 首先,一条树链可以被分为两部分:左半部分和右半部分 我们可以把所有可能是链上的点排序,把深度最大的点默认成起点st,接下来去找终点ed ed在和st不同的链上 且 …

MSA【1】:Segment Anything Model for Medical Image Analysis: an Experimental Study

文章目录 前言1. Abstraction & Introduction1.1. Abstraction1.2. Introduction1.2.1. What is SAM?1.2.2. How to segment medical images with SAM? 2. Methodology2.1. SAM is used in the process of segmentation of medical images2.1.1. Semi-automated annotati…

【压力传感器】LPS22DFTR、LPS33KTR 绝对 压力,ADP5131 排气式压力计 50kPa 6-DIP

LPS22DFTR MEMS纳米压力传感器是一款超紧凑型压阻式绝对压力传感器,可用作数字输出气压计。LPS22DF的功耗更低,与上一代产品相比压力噪声更低。该器件包括一个传感元件和一个IC接口,通过I2C、MIPI I3CSM或SPI接口从传感元件向应用程序进行通信…

蒙德里安的梦想

题目 求把 NM 的棋盘分割成若干个 12 的长方形,有多少种方案。 例如当 N2,M4 时,共有 5 种方案。当 N2,M3 时,共有 3 种方案。 如下图所示: 输入格式 输入包含多组测试用例。 每组测试用例占一行&…

GO语言基础-04-数据类型-04-map(map的排序)

文章目录 1. 按value排序1.1 思路1.2 语法1.3 完整示例 2. 按key排序2.1 思路2.2 语法示例2.3 完整示例2.4 完整示例 1. 按value排序 1.1 思路 map本身的顺序不可控,我们考虑如下方法实现排队: 思路一:通过一个切片来接收拍好队的map成员思…

多线程应用场景

文章目录 前言一、CountDownLatch倒计时锁二、如何控制线程并发数?三、浅聊ThreadLocal1.ThreadLocal定义2.ThreadLocal源码解读3.关于ThreadLocal的一个案例 总结 前言 本篇介绍多线程中的应用场景,比如倒计时锁CountDownLatch、信号量Semaphore、以及…

【雕爷学编程】Arduino动手做(163)---大尺寸8x8LED方格屏模块5

37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的&#x…

一种简化的3D点云车道线自动识别标注一些思考

0. 简介 作为3D车道线训练来说,数据集是至关重要的,而使用点云的精确性来完成准确的车道线地图构建是一个非常重要且有趣的事情。下面我们将会从一个例子开始,分阶段来告诉大家该怎么样去完成一个简单的3D点云车道线自动识别标注工具。 1. …

WordPress作为可扩展的企业级解决方案

网络商业世界就像一片汪洋大海,大型企业是大海中最大的鱼。然而,只因为你比其他人都大,并不意味着你不能逆流而上。相反,企业业务面临的挑战更大,对网站的技术要求更高。 多年来,大型公司通常依赖最昂贵的…

爆肝整理,接口自动化测试面试题+答案,25k*15薪如何达成的...

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

MB10S-ASEMI迷你贴片整流桥50MIL芯片MB10S

编辑:ll MB10S-ASEMI迷你贴片整流桥50MIL芯片MB10S 型号:MB10S 品牌:ASEMI 芯片个数:4 封装:MBS-4 恢复时间:50ns 工作温度:-50C~150C 浪涌电流:30A 正向电流:1…

HttpRunner自动化测试之辅助函数debugtalk.py

辅助函数debugtalk.py Httprunner框架中,使用yaml或json文件进行用例描述,无法做一些复杂操作,如保存一些数据跨文件调用,或者实现一些复杂逻辑判断等,为了解决这个问题,引入了debugtalk.py辅助函数来进行一…

Linux操作系统升级低版本的OpenSSH到9.3的高版本

OpenSSH 9.3之前的版本存在各种各样的安全漏洞,为此,我们需要将OpenSSH升级到最新的9.3的版本。 执行:ssh -V,我们可以查看当前的openssh版本 为了避免升级过程中出现意外而导致服务器无法正常使用,建议操作前先对服务…

插槽的使用!!

什么是插槽 插槽(Slot)是 vue 为组件的封装者提供的能力。允许开发者在封装组件时,把不确定的、希望由用户指定的部分定义为插槽。可以把插槽认为是组件封装期间,为用户预留的内容的占位符 即:使用者来决定某一块区域…

开利网络拜访番禺前后仓国际珠宝基地,以数字化技术赋能产业升级

近日,开利网络拜访位于番禺的前后仓国际珠宝基地,对基地目前的数字化需求和产业升级方向进行了解和探讨。目前,基地拥有以数字贸易综合服务中心,以人才、流量、运营、金融为抓手,以供应链选品、直播电商、跨境电商为媒…

【C++医学影像PACS】CT检查中的三维重建是什么检查?

一、【PACS影像科普】CT检查中的三维重建是什么检查? 三维重建是多层螺旋CT的一个最大的优点,也是影像工作多年来,从横断解剖到多平面,乃至立体的一次飞跃,让抽象变的形象,大大地提高了准确性,为…

大数据测试之数据仓测试怎么做(下)

前面的文章我们为大家介绍了一个常见的互联网大厂的数据仓的技术框架,也就是下面这张图所展示的内容。 为大家介绍了从操作数据层,到DW层,再到汇总数据层,最后到维度层和数据应用层的整个流程。本文我们将整个架构打平来展示制作…

我们正在开发一套组件库,欢迎你的加入~

项目地址 github地址 可以先点进来康康~ 技术栈 目前我们整体采用的是vue3typescriptless作为整体的开发的选择 需要说的是,我们并没有采用很多组件库采用的TSX的写法,而是选择了SFC的写法,这是因为我们觉得对于大部分的vue开发者来说&am…

用得最多的企业文件加密软件【企业文件加密软件前十】

企业文件加密软件是一种专门设计用于保护企业敏感信息的软件工具。它通过使用加密算法将企业的文件、文件夹和移动设备上的数据转化为不可读的格式,以防止未经授权的访问和数据泄露。这些软件通常提供了多种加密算法和安全控制选项,以满足不同企业的安全…