TCP协议广泛应用于可靠性要求较高的应用场景,如网页浏览、文件传输、电子邮件等。它提供了可靠的数据传输和流控制机制,能够确保数据的完整性和有序性。然而,由于TCP协议在传输过程中引入了较多的控制信息,因此相比于UDP协议,TCP的传输速度较慢。
TCP | UDP |
---|---|
有连接 | 无连接 |
可靠传输 | 不可靠传输 |
面向字节流 | 面向数据报 |
全双工 | 全双工 |
源端口:表示发送方的端口号。
目标端口:表示接收方的端口号。
4位首部长度: 用于描述TCP报头有多长,这里的单位是4个字节.如果这里是1111->15,表示报头的长度是60
注: TCP的报头长度是可变的,在下面有一个选项
(可有可无),可以有一个选项,也可以有多个.
TCP报头前面20个字节是固定的,后面的选项是可变的,选项可以是0个字节,最多是40个字节
保留位: 协议中预留的一些位,目前没有特定定义或使用规则。以便以后进行扩展或未来使用。
校验和:用于检测数据报的完整性
TCP是可靠的传输协议,确认应答机制是TCP保证可靠性的最核心机制!
在确认应答机制中,发送方在发送数据包后会等待接收方发送确认消息。如果发送方在一定的时间内没有收到确认消息,它会认为数据包丢失或发生错误,并会重新发送数据包。接收方通过发送确认消息来告知发送方数据包已成功接收,或者指示需要重发某个数据包。
普通报文: ACK这一位为0
应答报文: ACK这一位为1
特殊情况:如果客户端一次性给服务器发多条消息,那么浏览器的应答就会产生歧义
如下图:
在网络上有一种特殊情况,“后发先至”,后发的请求可能先到
因此就会产生上述两种情况.
为了解决上述问题,就可以针对请求和应答报文进行编号!
跟对编号就可以很明确的分出是哪个请求的应答.即使出现"后发先至"的情况也没有问题
而这个编号就对应TCP报文结构中的32位序号和32位确认序号
注: TCP报头只能存一个序号,存的是最后一个字节的序号,是根据报文长度来算的
上述数据的传输过程也不是一帆风顺的,可能会出现丢包,如果丢包,这就需要TCP的超时重传机制了
超时重传是当发送方发送数据包后,如果在一定的时间内未收到接收方的确认消息(ACK),发送方会认为数据包可能丢失或发生错误,并会重新发送该数据包。
超时重传机制的工作原理如下:
超时时间如何确定?
一般操作系统中有一个配置项,描述超时时间的阈值.
如果第一次出现丢包,超出时间阈值后,进行重传.第二次的超时时间阈值就会比第一次更长.
如果重传几次依旧无法传输,就会重置TCP连接,如果还是连不上,就会直接释放连接
超时重传会出现两种情况:
对于这两种情况发送方都区分不了这两种情况,对于第二种情况,接收方就会收到重复的数据,但可以根据序号进行去重
三次握手是在TCP协议中建立一个可靠的连接所使用的一种机制。它由发送方和接收方之间进行的三次通信组成,用于确保双方都愿意建立连接,并同步各自的初始序列号。
三次握手类似于打电话
如下图:
三次握手的过程本质上是四次数据的交互.只是中间两条数据可以合并到一起
如下图所示:
三次握手的步骤:
为什么要建立连接以及建立连接的意义:
两个重要的TCP状态:
1、阻⽌重复历史连接的初始化(主要原因)
两次握手在收到服务端的响应后开始发生数据,不能判断当前连接是否是历史连接。
2、同步双方的初始序列号
TCP 协议的通信双方,都必须维护一个[序列号], 序列号是可靠传输的一个关键因素
两次握手只保证了一方的初始序列号能被对方成功接收,没办法保证双方的初始序列号都能被确认接收。
3、避免资源浪费
四次挥手是在TCP协议中用于终止一个已建立的连接的机制。它是TCP连接的正常关闭流程,由发送方和接收方之间进行的四次通信组成。
以下是四次挥手的步骤:
两个重要的TCP状态:
TCP能保证可靠传输,但失去了效率.为了在保证可靠性的前提下,尽可能的提高效率,就有了滑动窗口机制
滑动窗口是在数据传输中用于流量控制和可靠传输的一种机制。它允许发送方在不等待接收方确认的情况下连续发送多个数据包,提高了传输效率。
在不引入滑动窗口的情况下:
发送方和接收方一应一答,可靠性确实能得到保证,但其实大部分的时间都消耗在等待ACK上了.
因此滑动窗口就是每次批量发送一波消息,然后在等一波ACK,再发一波消息
如下图所示:
上图中窗口大小是3000,主机A发送了3000字节的数据,主机B需要确认应答,如果第一个ack成功返回主机A,说明1~1000的数据发送成功,窗口就会向后移动,并发送下一条数据,保证窗口中的数据都是需要确认应答的,或者是没发出去的.
上述过程都是正常的情况下,但也会发送丢包或者乱序的情况
情况1:数据包到了,但是ACK丢了
如上图第二个ack丢了,不用做任何处理也没关系,对于可靠传输没有任何影响.右边ack的数字,1001表示1001之前的数据都受到了,2001表示2001之前的数据都受到了,3001表示3001之前的数据都受到了.(后者包括前者).
情况2:数据包丢了
假设11000的数据包丢了,.在11000的数据开始丢的时候,主机A并不知道丢了数据,会继续往下发数据.
那么主机B会在收到01000的数据前的应答中返回1001,主机A在接收到重复的几次确认之后,会重新发送11000的数据.当主机B收到11000的数据后,会把应答的数据变成最新的,例如在主机A重发01000的数据前又发了30006000的数据,并且没有丢包,在收到01000的数据后,下此应答的数字就是6001.
上述的重传过程,效率也是比较高的,并没有耽误后续数据的发送,这个称为"快速重传".
对于滑动窗口的大小,也并不是随意设置的.如果超出接收方的处理速度,就可能会丢失一些数据,那就还得重传这些数据.效率还得不到提升. 因为又有了流量控制机制
流量控制是在数据通信中的一种机制,用于控制发送方的数据发送速率,以适应接收方的处理能力,避免数据的丢失或拥塞。
接收方使用接收缓冲区的剩余空间大小,来作为发送方速率(滑动窗口大小)的参考数值
例如一个水桶,发送方就是往桶里放水,接收方就是出水.进水和出水的速度,就决定了 水位的高低
接收方会在收到发送方的数据后,会在返回的ACK报文中,把当前缓冲区的剩余空间大小,反馈给发送发
对应着TCP报文结构中的16位窗口大小.
在TCP报文结构的选项中,有一个用于调整窗口大小的扩展因子.用于跳转滑动窗口的大小,并不是说窗口的大小最大只能是16位(64KB)
拥塞控制是用于控制在网络中发生拥塞时的数据传输速率。当网络中的流量过大,导致网络拥塞时,TCP拥塞控制机制会自动减少发送方的数据传输速率,以避免进一步加剧网络拥塞。
流量控制只是考虑了接收方的处理速率,但数据的传输还要经过很多的交换机和路由器.因此我们也要考虑这些中间结点的速率.
拥塞控制机制主要包括四个算法:慢启动、拥塞避免、快重传和快恢复。
慢启动算法是在TCP连接建立时,发送方初始的数据传输速率较低,然后逐渐增加发送方的数据传输速率,直到网络出现拥塞为止。
拥塞避免算法是在慢启动阶段结束后,发送方以线性增加的方式增加数据传输速率,以避免过快地增加网络流量。
快重传算法是当接收方收到重复的数据包时,会立即发送一个重复确认,以通知发送方有数据包丢失,从而使发送方能够更快地重传丢失的数据包。
快恢复算法是在接收到重复确认后,发送方将拥塞窗口减半,然后继续进行拥塞避免算法,以减少网络拥塞的影响。
对于流量控制和拥塞控制,本质上都是在控制窗口的大小,在实际中较小的那个作为窗口的大小
延时应答是指在TCP通信中,当一方发送数据给另一方时,接收方需要向发送方发送一个确认应答,表示已经成功接收到数据。延时应答是指接收方在接收到数据后,不立即发送确认应答,而是等待一段时间后再发送确认应答。
如下图:
接收方在收到发送方的数据后,不会立即返回应答,而是接收方先进行一部分数据的处理然后再返回应答给发送方.
延时应答的主要作用是为了优化网络传输性能。TCP协议使用了滑动窗口机制,发送方会根据接收方发送的确认应答来确定下一次发送的数据量。如果接收方立即发送确认应答,那么发送方会立即发送下一批数据,造成网络拥塞。而延时应答可以让发送方在一定时间内累积多个数据包,然后一次性发送确认应答,有效减少了网络流量。
捎带应答是指在TCP通信中,接收方发送确认应答时,可以同时携带自己发送的数据。也就是说,在发送确认应答的同时,可以将自己需要发送的数据一起发送出去。
在网络通信中,典型的通信模型是一发一收
在TCP中,只要把数据发送过去,就会立即由内核返回一个ack报文.响应数据则是由应用程序里进行负责传输.
由于上述两个操作是不同时机传输的,原本是不能把这两个操作合并的,但是因为"延时应答"的存在,会等一会,因此就把上述两操作合并了
捎带应答的主要目的是为了减少网络传输的延迟和减少网络负载。在TCP通信中,接收方发送确认应答时会占用网络资源,而且会增加延迟。通过捎带应答,接收方可以在发送确认应答的同时,将自己需要发送的数据一起发送给发送方,减少了网络传输的次数和延迟。
面向字节流是指TCP协议在传输数据时将数据视为连续的字节流进行处理,而不是将数据分割成固定大小的块进行传输。
在TCP通信中,发送方将待发送的数据按照字节流的方式发送给接收方,接收方按照相同的字节流方式接收数据,并将数据重新组装成原始的数据块。
在面向字节流中,有一个问题,叫做"粘包问题"
粘包问题是指在TCP通信中,发送方将多个小的数据包连续发送给接收方时,接收方可能会将这些数据包合并成一个大的数据包,导致数据的粘连,造成数据解析错误。
就比如我们看一篇没有标点符号的文章,对于那些字是一句话是有很多看法的.TCP也是如此,无法确定哪些是一个完整的应用层数据报
要想解决"粘包问题",有两种办法:
上述方法在自定义的应用层协议,就有典型的实现:
}
TCP协议在连接异常处理方面主要涉及以下几个方法:
程序崩溃就是进程异常退出,操作系统会回收进程的资源,包括释放文件的描述符表,相当于调用了socket里的close方法,进而触发FIN报文进行四次挥手
正常关机,系统会强制结束所有进程,那么就和程序崩溃的情况是一样的,进行四次挥手
主机突然关机:
心跳包通常是一个小的数据包,由发送方定期发送给接收方。接收方在收到心跳包后,会立即发送一个确认应答给发送方,表示连接仍然活跃。如果发送方在一定时间内没有收到接收方的确认应答,就可以认为连接已经失效,可以进行相应的处理,如关闭连接或重新建立连接。
网线断开与主机突然关机的处理方式相同,分两种情况处理.