广州 网站建设公司,天津网站建设,中国石油网站建设在线第三次作业,网站备案流程和规则前言#xff1a;本文将简单介绍TCP协议的基本特征以及TCP是如何做到可靠传输的。 一、为什么需要TCP#xff1f; 原因#xff1a;互联网底层传输不可靠#xff0c;数据丢包#xff0c;乱序#xff0c;重复问题频繁出现TCP的定义#xff1a;TCP是一种有连接#xff0c;可…前言本文将简单介绍TCP协议的基本特征以及TCP是如何做到可靠传输的。一、为什么需要TCP原因互联网底层传输不可靠数据丢包乱序重复问题频繁出现TCP的定义TCP是一种有连接可靠传输面向字节流全双工的传输层通信协议核心价值在不可靠的IP层协议之上建立起可靠的通信链路二、TCP 协议段格式下面是一个TCP协议段的简图 :字段名称位数 (bits)说明源端口 (Source Port)16发送方的应用程序端口号。目的端口 (Destination Port)16接收方的应用程序端口号。序号 (Sequence Number)32本报文段所发送数据的第一个字节的序列号。用于解决网络包乱序问题。确认号 (Acknowledgment Number)32期望收到对方下一个报文段的第一个数据字节的序号。只有ACK 标志位为 1时才有效。首部长度 (Data Offset)4指出 TCP 报文段的数据起始处距离报文段起始处有多远。实际上就是TCP 首部的长度。保留位 (Reserved)6保留为今后使用目前置为 0。标志位 (Flags)6包含 6 个非常重要的标志位见下文。窗口大小 (Window Size)16用于流量控制告知对方从本报文段确认号开始接收方目前允许对方发送的数据量。检验和 (Checksum)16检验范围包括首部和数据两部分用于错误检测。紧急指针 (Urgent Pointer)16配合 URG 标志位使用指出紧急数据的末尾在报文段中的位置。选项 (Options)可变最常见的选项是最大报文段长度MSS、窗口扩大因子、时间戳等。核心标志位URG (Urgent): 紧急指针有效标志。告诉系统此报文段中有紧急数据应尽快传送。ACK (Acknowledgment): 确认序号有效。TCP 规定在连接建立后所有传送的报文段都必须把 ACK 置 1。PSH (Push): 推送标志。接收方应该尽快将报文段交付给应用层而不是等到缓存填满。RST (Reset): 重置连接标志。用于复位由于主机崩溃或其他原因而出现的错误连接。SYN (Synchronize): 同步序号用于建立连接在三次握手的前两次中使用。FIN (Finish): 终止标志。用于释放连接表示发送方数据已发送完毕。三、TCP的四大核心特征有连接机制UDP在正式传输业务数据报载荷数据之前会传输一个只包含TCP首部20字节的数据报进行三次握手来与接受方建立连接。目的校验通信双方是否具备正常的接受数据的能力同时还起到一个投石问路的效果可以验证通信链路是否畅通。好比火车发车前都需要先发一程空车用于检验路况是否畅通。状态维护连接状态会占用服务器资源如缓存、定时器等直到通过“四次挥手”释放连接。可靠传输TCP和UDP的最大区别显现于此TCP通过一系列复杂的机制来保证数据在传输的过程中不会出现丢包重传乱序等问题。序列号和确认应答ACK序列号使得TCP能够得知下一个需要传输的数据的起始序号如果数据没发生出去或者ACK未返回TCP还会进行超时重传操作来保证可靠传输校验和校验和帮助校验数据在传输的过程中是否出现bit位错误ACK值为1时代表数据无误否则传输有误流量控制流量控制是指在数据传输的过程中接收方需要根据缓冲区剩余大小动态调整发送方数据传输速率防止缓冲区溢出导致丢包这一机制还需要配合滑动窗口来实现下面会具体介绍。拥塞控制拥塞控制是通过维护拥塞窗口大小以防止过多数据注入到数据链路或者路由器导致网络拥塞的情况发生。面向字节流面向字节流使得TCP的数据间没有严格的边界划分在数据的发送传输接收时都可以像水流一样随意读取。发送时应用程序调用write写入数据时没有严格的数据大小规范你可以一次写1个字节也可以一次写入大量的字节。就像往水桶中倒水一样可以一次倒一小杯也可以一次倒一大瓶。传输时数据在通信的过程中依据拥塞控制来对传输的数据大小进行划分大的数据报会进行拆分为合适大小的数据段小的也会合并为大的数据报。接收时接收方从缓冲区read读取数据时无需按照发送时的数据报大小来严格规范读取的字节数可以任意读取。好比从木桶中取水你可以一次取一小勺也可以一次取一大盆这和你事前怎么向水桶中倒水的没有关系。全双工全双工使得通信的双方在同一时间既可以发送数据也可以接收数据。如此一来发送和接收这两个操作就可以并发完成无需等待另一个操作结束实现了双通道传输既可以发送也可以接收提高了传输效率。类似于一条公路划分为左右车道。四、基础可靠性机制确认应答ACK确认应答是TCP可靠性传输保障的基石TCP数据报整体可以划分为报头载荷两个结构其中报头中的序号中记载着TCP数据报的载荷末尾数据的序号无载荷时则以报头为结尾确认应答则与报首的确认序号相关。机制当接收到收到数据时会返回一个ACK给接收方含义向接收方表示已经收到数据捎带确认如果返回ACK独立发送的话又会占用网络资源同时发送方还得等待对端ACK返回为了优化这一过程。返回的ACK会与接收方的应答数据合并在一起也就是接收方返回数据的时候顺带把ACK给带着省点开销。确认应答ACK坐挂票顺路返回超时重传当发送方发送数据时在数据传输的过程中数据可能会在传输到接收方的过程中丢失也可能是接收方返回的ACK丢失。无论哪种情况发送这都是可靠性缺失的表现。为了解决这一问题TCP引入了超时重传。机制当发送方发送一个数据报时TCP会启动一个重传计时器计时器开始计时时间开始流逝。发送成功当接收方收到了数据并且成功把ACK返回给发送方时计时停止。发送失败一旦超出了这个最大时间限制就会触发超时重传发送方会再一次发送该数据报。以超时时间做为依据来判断数据是否丢包带来的一大问题就是超时时间如何设置时间设置太短发送的数据可能还在传输半途没到达接收方就被认定为丢包导致重传时间设置太长数据丢包了由于重传计时器的超绝反射弧导致过了好一会儿才能反应过来“哦数据丢了我要重传”导致传输效率低下。超时重传时间设置为了设立一个合理的超时重传时间,TCP会动态监测每一次数据报传输所消耗的往返时间当有一次传输触发了超时重传就会把超时重传时间进行放大。比如当初始的时间设为1s触发了超时就会把时间调整为2s如果再次触发超时就调整为4s1s - 2s - 4s - 8s…反复类推快速重传超时重传虽然解决了数据超时传输带来的传输问题但同时也隐藏一个问题当数据丢包了往往要等到超时重传时间到达了才能让发送方触发重传机制这样就会带来一定的网络卡顿。有无可以在数据丢包的情况下不用在等待那些无意义的重传时间呢这就能即使重传提高效率。有的快速重传的出现优化了这一问题当发送方连续发送了1,2,3,4,5多个数据包时假设2号数据报丢失五、连接管理一般情况下TCP要经过三次握手建立连接四次挥手断开连接这是保证传输可靠性基础的两大阶段建立连接在TCP正式传输业务数据包之前会进行三次握手尝试与服务端建立连接目的投石问路判断当前的网络传输链路是否畅通判断彼此之间的接收与发送能力进行参数协商确认TCP报头序号的起始序号过程第一次握手客户端发送 SYN报文序号为xxx进入 SYN_SENT 状态。意图“喂你能听到吗我想和你建立连接。”第二次握手服务端收到后回复SYN ACK报文确认号为x1x1x1序号为yyy进入SYN_RCVD状态。意图“听到了我也能听到你。你能听到我吗”第三次握手客户端收到后回复ACK报文确认号为y1y1y1进入ESTABLISHED状态。服务端收到此包后也进入该状态。意图“没问题我也能听到你那我们开始聊天吧。”为什么不是两次为了防止“已失效的连接请求报文”突然又传到了服务端。如果只有两次握手服务端回复后连接就建立了但这可能只是一个在网络中绕路太久的旧请求这会浪费服务端的资源。亦或是客户端返回服务端的响应之后倘若缺失第三次握手则无法判断正式发送信息前服务端的接收能力是否正常对于其能力的验证只是在第一次握手时确认但是经过第二次握手的间隔时间之后对于服务端接收能力仍需确认。断开连接目的断开连接保证数据传输的完整性不丢包释放TCP建立连接所占用的系统资源防止该连接结束产生的旧报文干扰后续连接过程由于 TCP 是全双工的双方都可以同时发数据所以每个方向的连接都需要单独关闭。第一次挥手客户端发起的FIN报文。客户端进入FIN_WAIT_1状态。意图“我的话写完了我要挂了。”第二次挥手服务端收到后回复ACK。此时服务端进入CLOSE_WAIT状态客户端收到后进入FIN_WAIT_2。意图“我知道了但我这边可能还有点数据没传完你等我一下。”第三次挥手服务端处理完数据后发送FIN报文。服务端进入LAST_ACK状态。意图“好了我也写完了挂吧。”第四次挥手客户端回复ACK进入TIME_WAIT状态。经过2MSL最大报文生存时间后连接彻底关闭。服务端收到 ACK 后直接进入CLOSED状态。意图“行拜拜。”客户端等一会儿确保对方收到了再走。TIME_WAIT 状态的作用客户端在第四次挥手后为什么要等 2MSL保证可靠关闭如果最后的 ACK 丢了服务端会重发第三次挥手的 FIN。客户端必须活着才能重发 ACK。防止旧包干扰确保这个连接中产生的所有报文都在网络中消失以免影响下一个相同端口的新连接。1.为什么通常需要“四次”默认情况下四次挥手是因为 TCP 的全双工性质和被动关闭方服务端可能还有数据要发客户端发FIN。服务端先回ACK表示收到了但我可能还没忙完。忙碌中服务端继续把剩下的一点数据发完。服务端发FIN表示我也忙完了可以挂了。2. 什么时候可以变成“三次”如果满足以下条件第二次和第三次挥手就可以合并条件一服务端在收到客户端的FIN后正好没有额外的数据需要发送给客户端了。条件二服务端开启了延时应答Delayed ACK机制。在这种情况下客户端发送FIN。服务端收到后由于没有数据要发它不急着回ACK而是等一小会儿通常是 40ms~200ms。就在这等待期间服务端的应用层也调用了close()发出了FIN。于是服务端就把ACK对客户端 FIN 的确认和自己发的FIN合并成一个包发出去。客户端回复最后一个ACK。结果整个过程变成了FIN-ACK FIN-ACK。一共三次。六、传输性能与效率优化滑动窗口滑动窗口初次听说可能会与双指针算法中的滑动窗口产生练习但是其实是两个东西。TCP的滑动窗口是实现效率传输流量控制的核心机制该窗口是一个虚拟的窗口用于控制窗口中的数据包的批量传输为什么需要滑动窗口在最初的TCP传输设计中发送方只能等到接收方返回对应的ACK确认应答才能进行下一个数据包的发送这在发送方来看其发送的操作就像是串行化发送的。如此一来发送方的大部分时间都可能用于等待接收方返回的ACK数据包这无疑是一个耗时的操作。于是就引入了滑动窗口来实现批量传输数据包机制当假设初始的窗口大小是4即最多能同步发送四个数据报给服务器。这里要注意一个细节有人可能认为窗口是一位一位的向后移动这样不就会导致只有初次进窗口的数据可以实现批量发送但是后续数据接收的ACK不是会接收到窗口中最左端的ACK数据包导致只能单个出单个进窗口吗这样看来似乎效率也没有提升多少实则不然要知道由于缓冲区存在数据重排序的问题以及服务器处理每个任务的耗时不同。返回的ACK数据包不一定按照发送的数据。比如发送了12345接收方先拿到了2不急返回对应ACK2而是先存在接收方缓冲区。随后又收到了1,4,5数据此时数据为1,2,4,5最后数据3珊珊来迟填补空位接受方就可以直接返回ACK6的确认应答表示12345已全部收到。窗口就会把6之前的数据全部出窗口实现批量入窗口批量发送数据。流量控制如果说引入滑动窗口批量发送数据包是为了解决数据传输太慢的问题那流量控制就是为了解决发送方和接收方“速度不匹配”的问题为什么会出现速度不匹配的问题有两个原因1发送方发的太快导致缓冲区被迅速填满后发的数据丢包2接收方处理数据太慢缓冲区的数据不能即使被处理导致数据堆积无论是哪一种情况都是发送方和接收方“速度不匹配”的表现流量窗口就是为了协调二者的发送速度由此而生。机制实现流量控制的机制还需要与上文的滑动窗口作为基础过程接收方收到数据时会观察缓冲区的剩余空间大小并把其量化为一个数值rwndReceiver Window于返回的ACK中一起发回给发送方。这样一来发送方就可以得知对方的剩余缓冲区空间还有多大。当发送方发送的速率过大时缓冲区内剩余空间迅速变小把对应信息返回给发送方时发送方就会把窗口调小来降低速率当发送的速率过大时窗口也会调大增加吞吐量提高速率零窗口情况当缓冲区被填满时剩余缓冲区大小为0此时会rwnd 0Receiver Window这个信息返回给发送方表示“我处理不过来了你先别发了”于是发送方就会暂时停止发送数据。等到缓冲区空间富余时会返回一个窗口更新的报文给发送方“我已经有空间了你可以发数据了”死锁问题此死锁非多线程的死锁问题。而是在接收方先把rwnd 0 返回给发送方的情况下之后打算像接收方发送更新窗口大小的数据包但是更新窗口数据包却出现丢包现象。这就会导致陷入发送方没收到更新窗口的数据一般保持窗口为0的状态不发数据接收方已经处理完手头上的数据但是迟迟等不到发送方发数据陷入进退两难的境地如何解决添加计时器反复询问很简单只需要给发送方添加一个计时器作用是发送方在接收到窗口 0的信息时计时器启动。如果接收窗口的数据报丢包了等到了计时上限会发送一个探测报文Zero Window Probe从而使得接收方发送窗口更新的数据打破死锁状态。就好比两个人正在线上聊天对方说先等会儿了我先处理手头上的一点事你不再发消息不发数据过了一会儿对方有空回了一句“好了”但是此数据却发送失败导致你也不知道对面是否有空对面也没等到你的消息。二者僵持住陷入死锁为了打破僵局你等了一会儿之后主动询问“现在有空没”从而触发对方的回应“OK了”拥塞控制如果说流量控制是防止接收方缓冲区被撑满那么拥塞控制就是避免路由器和交换机被堵死也可以说流量控制是端到端的保护接收端拥塞控制是全局的保护整个网络拥塞控制先使用少量的数据去试探当前网络的整体状态从而避免贸然发送大量的数据导致整个网络拥塞的情况出现以此来确定一个合适的发送数据包的速率原理拥塞控制是通过维护一个拥塞窗口来计算发送方具体可以发送多少的数据量。过程TCP拥塞控制是需要经过四个阶段分别是慢启动拥塞避免拥塞发生快速恢复这四个阶段。以下是一个拥塞控制的流程图关键控制变量变量名称英文原词功能定义cwndCongestion Window拥塞窗口发送方根据网络拥塞程度维护的状态变量。rwndReceiver Window接收窗口接收方通过 TCP 报文首部告知的剩余缓存大小。ssthreshSlow Start Threshold慢启动阈值决定何时从慢启动切换到拥塞避免算法。SWNDSend Window发送窗口实际发送量SWNDmin⁡(cwnd,rwnd)SWND \min(cwnd, rwnd)SWNDmin(cwnd,rwnd)。慢启动逻辑连接建立后从cwnd1cwnd 1cwnd1(或初始值 SMSS) 开始每收到一个确认帧 (ACK)cwndcwndcwnd增加 1。增长速率指数增长。每经过一个往返时间 (RTT)cwndcwndcwnd翻倍。终止条件当cwnd≥ssthreshcwnd \ge ssthreshcwnd≥ssthresh时进入拥塞避免阶段。拥塞避免逻辑每收到一个 ACKcwndcwndcwnd增加1/cwnd1/cwnd1/cwnd。增长速率线性增长。每经过一个 RTTcwndcwndcwnd仅增加 1。目的使窗口增长更缓慢探测网络带宽上限延缓拥塞发生。快重传逻辑当接收端收到失序报文段时立即发送重复确认 (Duplicate ACK)。触发条件发送端连续收到3 个冗余 ACK判定该报文丢失。动作不必等待超时计时器RTO结束立即重传丢失报文。快恢复逻辑配合快重传使用。计算公式ssthreshcwnd2ssthresh \frac{cwnd}{2}ssthresh2cwnd​cwndssthresh3cwnd ssthresh 3cwndssthresh3(加上收到的 3 个冗余 ACK 占用的空间)后续直接进入拥塞避免阶段线性增长而非回到慢启动。归根结底拥塞控制就是一个既想增加传输效率但是又担心初始吞吐量过大导致网络拥堵情况产生的一个控制方案七、进阶机制延时应答延迟应答是一种提高网络传输吞吐量的一种手段当接受方收到数据时不会立即返回一个ACK而是先等待一段时间等待目的1.期待捎带应答把多个ACK数据包合并返回减少网络资源占用2.提高吞吐量等待期间给接受方缓冲区腾空间返回一个更大的接收窗口触发条件1.时间限制等待时间通常不超过200ms。2.数量限制每收到2 个最大报文段 (MSS) 必须发送一次 ACK捎带应答在全双工 (Full-duplex) 通信中接收端在回复 ACK 的同时如果正好有数据要发往发送端就将 ACK 信息直接放入该数据报文的头部利用 TCP 报头中的 ACK 标志位和确认序列号字段合并返回。核心机制将控制信息ACK与数据信息Data合并在一个 TCP 段中发送。前提条件接收端必须有待发送的数据且发送时机恰好在延时应答的窗口期内。八、数据传输的本质与坑使用TCP字节流传输数据页带来了几个隐患面向字节流面向字节流使得接收到的数据无边界read操作可能出错这是粘包问题的本质原因粘包问题TCP面向字节流接收方read操作则以字节为基本单位并不是对方几次send 我就几次recv。比如一次读1.5个包或者一次读取多个数据报导致粘包。一次读取0.5个包就会导致拆包。解决方法添加分隔符以/n 或者 其他偏僻分割符 作为字节流中每个完整业务数据的边界当读到/n时,服务器读取到对应的字节流防止多读。在业务数据包头部前添加一个长度字符告示服务器向后该读取多少个字节。比如客户端两次send 操作传输hello cheems服务器接收到的就是4hello5cheems使得服务器每次从缓冲区read操作都能有一个明确的目的该read几个字节而不是盲读九、异常情况处理进程崩溃这是最“温和”的异常。内核介入操作系统内核Kernel会监控进程状态。当进程崩溃时内核会负责关闭该进程打开的所有文件描述符File Descriptors。动作内核自动发送FIN 包给对端触发正常的 **四次挥手断开连接。结果对端会收到连接关闭的信号能够优雅地释放资源。关机断电区分“有序关机”与“突发断电”有序关机系统会尝试终止所有进程回归到上述“进程崩溃”的逻辑发送 FIN。突发断电瞬间消失本端没有任何包发出。对端滞留对端Receiver完全不知道对方已掉线连接处于半开放 (Half-open)状态。触发机制只能依靠TCP Keep-alive默认 2 小时极慢或应用层的心跳检测 (Heartbeat)来发现并强行关闭连接。网线断开 / 网络中断这是最复杂的物理层异常。即时状态两端的内核状态均显示ESTABLISHED。数据传输中若此时有数据发送由于收不到确认应答 (ACK)会触发超时重传 (Retransmission)。重传达到最大次数由tcp_retries2决定后内核会返回错误并强制关闭连接。静默状态若无数据往来连接将无限期“假死”直到开启心跳检测。以上就是关于TCP协议内容的简单介绍如有纰漏还请指出~