文章目录
- 前言
- 一.Tpc报头格式
- 源端口和目的端口:
- 序列号:
- 确认号:
- 数据偏移:
- 控制位:
- 窗口大小:
- 校验和:
- 紧急指针:
- 二.TPC原理
- 2.1 确认应答机制
- 2.2 超时重传机制
- 2.3 连接管理机制
- 2.3.1 三次握手
- 2.3.2 四次挥手
- 2.4 滑动窗口机制
- 第一种
- 第二种
- 2.4.1 滑动窗口的具体概念
- 2.4.2 窗口控制与重发控制
- 2.5 流量控制机制
- 2.6 拥塞控制机制
- 2.7 延迟应答机制
- 2.8 捎带应答机制
- 2.9 面向字节流
- 粘包问题发生的原因
- 解决方案
- 2.10 缓冲区
- 2.11 大小限制
- 三.TCP异常情况
- 1.进程关闭/进程崩溃
- 2.主机关机(正常流程关机)
- 3.主机掉电(拔电源,啪的一下,很快的)
- 4.网线断开
- 四 总结
前言
TCP(Transmission Control Protocol,传输控制协议)是互联网协议族中最重要的一种协议之一,它是面向连接的、可靠的、基于字节流的传输层协议,用于在网络上可靠地传输数据。TCP协议在网络中的应用非常广泛,尤其是在互联网上,几乎所有的网络应用都要依赖于TCP协议来完成数据传输。
一.Tpc报头格式
这里我会对tpc头部格式做出相应的解释
源端口和目的端口:
指定源主机和目的主机的应用程序端口号,用于区分不同的应用程序和服务。
序列号:
用于保证 TCP 连接的可靠性,标识本次数据段的第一个字节在数据流中的位置。
确认号:
用于确认收到的数据段,标识下一个期望收到的数据段的序号。
数据偏移:
指示 TCP 报文头的长度,以 4 字节为单位计算。
控制位:
TCP 头部中有 6 个控制位,包括 URG、ACK、PSH、RST、SYN 和 FIN,用于控制 TCP 的各种行为。
窗口大小:
用于流量控制,表示发送方能够接受的数据量,避免接收方处理不过来。
校验和:
用于检测传输过程中数据是否出错,若出错则会丢弃该数据段。
紧急指针:
在 TCP 连接中,紧急数据通常是指需要优先处理的数据,通过紧急指针标识出紧急数据的位置。
二.TPC原理
2.1 确认应答机制
确认应答机制是实现可靠性的最核心机制.
在TCP中,当发送端的数据到达接收主机时,接收端主机会返回一个已收到消息的通知。这个消息叫做确认应答( ACK)
我举一个生活的例子,就拿你和女生聊天来说,你认识一个女生,你们相处很久了,今晚你想约她出来吃饭,但你又想确认与她的关系,你发了俩句话,我们能一起出去吃饭吗?你能做我的女朋友吗?但是这两条消息一发出去,可能她是答应跟你一起出去吃饭,但没有想法跟你发展男女朋友关系,因为网络的原因,俩条消息倒置了,你看到的是她不跟你出去吃饭,但可以做你女朋友.
这里怎么解决呢?
自然而然就用到了确认应答机制
看下图的解决办法
为了解决上述问题,就需要针对消息进行编号!!给发送的消息分配一个"序号"同时应答报文,给出“确认序号.
可能大家对序列号不太了解,我们可以来认识一下.
序列号(Sequence Number):表示这个报文段中的数据的第一个字节在完整数据流中的序号。当一方发送一个 TCP 报文时,序列号就是发送数据时的第一个字节的序号。接收方收到这个报文后,确认应答号会设置成这个序列号加上数据长度。
确认应答号(Acknowledgment Number):表示期望接收到的下一个字节的序号。每次接收方接收到一个报文,都会将确认应答号设置成接收到的序列号加上数据长度。
这两个参数的作用是确保 TCP 可靠传输的关键。发送方和接收方通过交换序列号和确认应答号来确定哪些数据已经被成功发送和接收,从而保证传输的可靠性。
我们的tcp其实是针对每个字节去编号
具体的序列号与确认应答号的结合如下:
注意:
不是说,发送方的序号是啥,确认序号就是啥,
而是取的是发送方发过来的所有数据,最后一个字节的下一个字节的序号
确认序号1001的含义:1.< 1001的数据,我已经收到
⒉我接下来想向发送方索要从1001开始的数据
2.2 超时重传机制
我们先看一下超时重传在什么情况下会发生
超时重传是指当 TCP 发送方发送数据时,如果一段时间内没有收到接收方的确认应答,就会重新发送该数据。超时重传机制主要用于确保数据的可靠性,以及保证数据的顺序性。
下面这个示意图就展现了情况.
但是我们还是有解决方案的,如果发送的时候出现丢包的情况,丢包就以为着发送方发送不了确认应答.这个时候我们重新发一次就行了.
当然我们的超时重传有俩种情况,当然发送方,区分不了这俩种情况只能超时重传
1.数据直接丢了,接收方没收到,自然不会发ack
⒉接收方收到数据了,返回的ack丢了
淡当然我们这里实际上是重新发了一遍数据,但是说实话并不需要担心,TCP非常贴心的帮咱们处理好这个问题了,会在接收缓冲区中根据收到的数据的序号,自动去重心
最后来个小小的总结,有人会问,那要是超时重传会不会丢包呢?说实话,当然是有可能的,但如果我们出现了严重的丢包情况,那只能说明我们网络出现了故障,就必须进行检查了.
2.3 连接管理机制
其实说到TCP的连接管理策略,大家老生常谈的自然是TCP的三次握手和四次挥手,当然我们也是围绕着这个机制去讨论的,这个机制一样的是为了保障数据的可靠性.接下来我们就来介绍一下这俩种情况.
2.3.1 三次握手
我们可以看一下具体的三次挥手大概是一个什么情况
我举另外一个生活的例子来说明这个三次握手是怎么一回事.
但是大家就很奇怪,我们明明是四次行为,为啥是三次握手呢?
其实简单的解释就是如果使用四次握手,则在建立连接时需要多一个步骤,增加了连接的建立时间和网络负载,因此三次握手被广泛使用。
三次握手这个过程,本质上基投石问路}~验证了客户端和服务器,各自的发送能力和接收能力是否正常!!!
最核心的就是确定客户端和服务端是否正常
2.3.2 四次挥手
具体的过程入下:
要说三次握手是建立连接,那四次挥手就是断开连接,具体就是通信双方,各自给对方发送一个FIN(结束报文),再各自给对方返回ACK .
当然哈,这里又有会有问题,为什么不是三次挥手而是四次挥手,既然握手可以合并操作,那挥手为什么不能合并呢?
其实大家看了我接下来举的例子,你就知道为什么了
这样的三次挥手在这个场景中是不够的。如果你只和收银员完成了前两个步骤,而收银员并没有给你收据或确认你已经付款,那么你就无法离开。这就是为什么在网络连接的关闭过程中需要四次挥手,以确保双方都完成了必要的步骤。
其实还有一个重要的原因就是三次挥手的ack和syn都是同一时机触发的(都是内核完成的)
但是四次挥手,ack和fin的触发时机是不一样的,就好像男女朋友说分手一样,谁都有可能说分手.
其次,ack是内核完成的,会在收到fin的时候第一时间返回
fin测试应用程序代码控制的.
2.4 滑动窗口机制
另外TCP保证的不仅是可靠,他还要保证效率.
TCP窗口控制(TCP window control)是一种流量控制机制,它用于在网络中发送数据时,发送方和接收方之间动态地协商可用的缓存空间大小。这个缓存空间就是窗口(window),用来控制发送方和接收方之间的数据流量。在TCP协议中,每一个传输数据的报文段都有一个窗口大小的字段,用于表示发送方当前可以发送的字节数量,而接收方在每次确认报文段的时候也会告诉发送方自己当前能够接收的字节数量。
另外我们来看一下我们传数据的两种方式
第一种
此时A这边就花了大量的时间在等待ACK
想提高效率,就需要缩短等待时间
批量发送数据了!!就引入了第二种机制.
第二种
这里就是批量发送4条数据.发完之后,统一等待ack.
每次收到一个ack 就立即发下一条.(不是收到4个ack 再发下一组)
使用一份时间,等待多个ack.
这种机制我们就称为滑动窗口
2.4.1 滑动窗口的具体概念
说起来上面说过滑动窗口就是批量传输,但是我们还是解释一下,批量不是无限发送,是发送到一定程度,就等待ack ,不等待直接发送的数据量是有上限的,而且是回来一个ack 就立即发下一条,相当于总的要批量等待的数据是一致的.
实际上滑动窗口的概念是这样的.
2.4.2 窗口控制与重发控制
有时候,我们窗口控制会出现丢包的情况,我们列出了俩种情况
第一种
情况一:数据包已经抵达,ACK被丢了。
这种情况下,部分ACK丢了并不要紧,因为可以通过后续的ACK进行确认;
第二种
情况二:数据包就直接丢了。
上述重传过程,没有任何冗余的操作,丢了数据才会重传
不丢的数据不必重传
整体速度是比较快的
这个重传过程也称为快速重传
2.5 流量控制机制
TCP的流量控制是一种机制,用于控制发送方发送数据的速率,以确保接收方有足够的缓冲区空间来处理传输的数据。在TCP的流量控制中,接收方会在TCP报文段中的确认字段中指定其当前可用的缓冲区大小,发送方会根据接收方的缓冲区大小来调整发送数据的速率,从而避免发送速率过快导致接收方无法处理数据的情况。
简单来说,就是下面的这种情况
接收端处理数据的速度是有限的。如果发送端发的太快,导致接收端的缓冲区被打满,这个时候如果发送端继续发送,就会造成丢包,继而引起丢包重传等等一系列连锁反应。
然后我们就要对速度进行控制,但是具体怎么进行控制呢?
还是让我们回归一下一个具体的生活例子,我来描述,你们去想想.
假设你在超市购物时,你的购物车只有有限的容量,但你需要购买很多商品。在这种情况下,你需要控制购物车中的商品数量,以避免过载或超出购物车的容量限制。这就是一个流量控制的例子。
当然我们也可以也可以看一下,TCP头部的结构,看看流量控制是在哪里的.
如图所示,当接收端收到从3001号开始的数据段后其缓冲区即满,不得不暂时停止接收数据。之后,在收到发送窗口更新通知后通信才得以继续进行。如果这个窗口的更新通知在传送途中丢失,可能会导致无法继续通信。为避免此类问题的发生,发送端主机会时不时的发送一个叫做窗口探测的数据段,此数据段仅含一个字节以获取最新的窗口大小信息。
2.6 拥塞控制机制
虽然TCP有了滑动窗口这个大杀器,能够高效可靠的发送大量的数据。但是如果在刚开始阶段就发送大量的数据,仍然可能引发问题.
但是我们仔细回想滑动窗口的机制,就可以知道,滑动窗口的大小取决于流量控制和拥塞控制.
但是拥塞控制衡量了接受放的处理能力,拥塞控制衡量了传输路径的处理能力.接下来我们就来解释这个拥塞控制机制究竟是怎么工作的.
这是一个生活中的例子.
类比到网络领域,网络中的数据包就好比车辆,在网络传输过程中,如果数据包的数量过多,网络就会发生拥塞,导致数据包的丢失、延迟等问题。为了避免这种情况发生,TCP采取了拥塞控制机制,通过控制发送方发送数据的速率,从而避免网络拥塞。当网络出现拥塞时,TCP会通过减少拥塞窗口的大小、减少发送速率等方式来降低数据包的发送速率,以避免网络进一步拥塞。
来看一下我们具体的拥塞控制具体的一个流程是怎么样的.
看了这个不知道你有没有回忆起相同的经历,就是这仿佛就是你跟你女朋友相处的记忆曲线,可能我说出来,你可能不知道是怎么一回事,但我解释一下,你马上就明白了.
2.7 延迟应答机制
延时应答从字面上来理解就是,我等一会再回答你.具体的解释就是,TCP的延时应答机制是指在TCP通信过程中,接收方收到数据后不会立即发送确认(ACK)消息,而是会等待一定时间,以便在这段时间内接收到发送方发送的更多数据,从而减少发送确认的次数,提高通信效率。
至于为什么减少了发送确认的次数,就能提高效率了呢?大家且看我举一个生活的例子.
类比于TCP通信中,如果不采用延时应答机制,接收方在接收到数据后就立即发送确认信息,发送方就不能根据确认信息来进行数据发送的速率控制,这会导致网络拥塞和数据丢失。而采用延时应答机制,接收方会先将确认信息缓存一段时间,等待待发送的数据到达一定数量后再一次性发送确认信息,这样可以减少网络拥塞和提高数据传输效率。
延时应答的效果,就是通过这个延时,让接收方应用程序,趁机多消费点数据,此时反馈的窗口大小就会更大一丢丢此时发送方的发送速率也就能快一些.
2.8 捎带应答机制
其实捎带应答是基于延时应答的.我们还是来解释这个概念吧
捎带应答(piggybacking)是指在TCP通信中,当一台主机向另一台主机发送数据时,若在数据发送过程中,该主机接收到了对方主机发来的数据确认信息(ACK),则该主机可以利用这个数据确认信息,在不浪费网络资源的前提下,把自己要发送的数据也一并打包发送给对方主机。
这种方式可以减少网络传输的次数,从而提高网络的效率。如果不使用捎带应答,那么每个数据包都需要独立发送和确认,这样会浪费大量的网络带宽和时间。
我们还是举一个生活的例子,让大家去熟悉一下.
这就是一个捎带应答的例子,你将问题“捎带”在了你的朋友讲故事的过程中,这样可以提高通信效率。
当然我们在前面其实已经接触过捎带应答的例子了,就是TCP的四次挥手机制,这里就体现了它的捎带应答机制.我们再来回忆一下.
这种方式可以减少网络传输的次数,从而提高网络的效率。如果不使用捎带应答,那么每个数据包都需要独立发送和确认,这样会浪费大量的网络带宽和时间。
2.9 面向字节流
TCP面向字节流的机制是指,TCP把应用程序传送给它的数据看成一连串无结构的字节流,TCP并不知道所传送的数据单位是什么,而是根据TCP缓存区内的数据动态调整传输数据的大小,将数据切割成以报文段(Segment)为单位的数据包进行传输。
当然在我们前面去模拟TCP客户端和服务端的时候,我们就对字节流有了大概的印象,但其实我们使用字节流机制是会面临一个问题的.
这个问题就是粘包问题.
粘包问题发生的原因
使用字节流机制会出现粘包问题是因为发送方将多个消息一次性发送到接收方,导致接收方在处理消息时无法区分每个消息的边界。这会导致多个消息被粘在一起,形成一个大的消息,造成解析错误或数据不一致等问题。
举一个例子大家都明白了.
解决方案
为了解决粘包问题,可以采用以下方法:
消息定长:在传输之前对消息进行长度填充,保证每个消息的长度固定。接收方在接收消息后,根据预设的长度进行截取,确保每个消息的边界正确。
分隔符:在每个消息之间添加特殊字符,作为消息的分隔符。接收方在接收到分隔符后,就知道前面的数据是一个完整的消息。
消息头:在消息头中添加表示消息长度的字段,接收方先读取消息头中的长度字段,再根据长度读取消息内容,以此来区分每个消息的边界。
应用层协议:在应用层协议中定义消息的格式和规则,以此来区分每个消息的边界。
2.10 缓冲区
TCP的缓冲区指的是用于存储TCP数据传输中数据的缓冲区,TCP协议通过缓冲区实现数据的传输和接收。
在TCP通信中,数据从应用层通过发送缓冲区发送出去,在传输过程中会经过路由器等多个节点,每个节点都有自己的缓冲区来存储数据。当接收方收到数据时,TCP会将数据存储在接收缓冲区中,等待应用层读取。
TCP缓冲区的大小会影响数据传输的效率和速度,如果缓冲区过小,就会导致发送和接收的数据量不匹配,从而影响传输速度和数据完整性;如果缓冲区过大,会占用过多的内存资源,导致系统运行缓慢。
因此,在进行TCP通信时,需要根据网络状况和系统资源的情况来适当地调整缓冲区的大小,以达到最优的传输效果。
还是举一个生活的例子吧
假设你正在看电影,电影是通过流媒体服务传输到你的设备的。为了确保你可以流畅地观看电影,你的设备(比如电脑或手机)需要先将接收到的数据存储在一个缓冲区中。这个缓冲区可以看作是一个临时存储数据的区域,当你观看电影时,缓冲区中的数据会被逐渐地读取和播放。如果数据流量过大,而缓冲区的容量又过小,可能会导致数据读取不及时,从而出现卡顿或者停顿的现象。在TCP中,缓冲区也是类似的概念,它用于存储接收到的数据,以及等待发送的数据,以确保数据的顺序和完整性。
2.11 大小限制
TCP的大小限制指的是TCP报文段的最大长度限制,也就是说在进行TCP传输的过程中,一个TCP报文段的长度不能超过一定的值。
TCP的大小限制有两个方面的考虑,一个是传输层协议对TCP报文段长度的限制,另一个是网络传输的MTU(最大传输单元)的限制。
对于TCP报文段长度的限制,RFC 793中规定,TCP数据报文段的长度最大为2^16-1字节,也就是65535字节。这个限制是因为TCP首部中的长度字段只占16位,所以最大只能表示到65535字节的长度。
另外,TCP在传输过程中还需要考虑网络传输的MTU。MTU是指在网络中传输的最大数据包长度,不同网络中的MTU可能不同。当一个TCP报文段长度超过了网络中某个设备的MTU,就会被分割成多个分组进行传输,这就增加了网络传输的开销。因此,TCP传输中还需要考虑网络的MTU,将TCP报文段的长度控制在一个较小的值,避免出现分段传输的情况。
因此,为了避免TCP报文段长度超过网络传输的MTU,TCP会对发送数据进行拆分,将数据划分为合适的大小进行传输。这样可以保证TCP传输的稳定性和可靠性,避免因为报文段过长而导致传输失败的情况。
三.TCP异常情况
1.进程关闭/进程崩溃
进程没了,socket是文件,随之被关闭,虽然进程没了,但是连接还在,仍然可以继续四次挥手.
2.主机关机(正常流程关机)
先杀死所有的用户进程
也会触发四次挥手,如果挥完,更好.如果没挥完,比如,对方发的fin过来了,咱们没来得及ack就关机了~此时对端就会重传fin,重传几次之后,发现都没有ack,尝试重置连接,如果还不行,就直接释放连接
3.主机掉电(拔电源,啪的一下,很快的)
瞬间机器就关了,来不及进行任何挥手操作
1)对端是发送方
对端就会收不到ack =>超时重传=>重置连接=>释放连接.
2)对端是接收方
对端是没法立即知道,你这边是还没来得及发新的数据,还是直接没了,但是TCP内置了心跳包保活机制
4.网线断开
当 TCP 发生异常情况时,会根据具体情况采取不同的处理方式。如果网络连接中断,TCP 会通过超时重传机制进行恢复,即发送方发送的数据在规定时间内没有得到接收方的确认,就会被重传。同时,TCP 也会根据网络的拥塞情况调整自己的传输速率,以保证网络的稳定性和可靠性。如果 TCP 还是无法恢复,就会中断连接,同时向上层应用程序发送错误信息.
四 总结
TCP协议是一种面向连接的、可靠的传输协议,它的特点包括三次握手建立连接、流量控制、拥塞控制、可靠传输、延时应答、捎带应答等。
TCP协议采用字节流机制,将应用层的数据看成一连串的字节流,而不是独立的消息或数据包。这样可以在传输过程中更加灵活,但也可能导致粘包或拆包问题,需要采取一些措施进行解决。
TCP协议还使用缓冲区来缓存待发送或接收的数据,以提高传输效率。但是当网络发生异常或拥塞时,TCP协议会采取一系列措施来保证数据的可靠传输,包括重传、拥塞避免、快速重传等。
总的来说,TCP协议在可靠传输方面表现出色,但也存在一定的延迟和开销,因此在对实时性要求较高的应用场景中,可能需要使用其他协议。