<p><img alt="8782af16d1b44b428d6bfcc911b5557f.png" src="https://img-blog.csdnimg.cn/8782af16d1b44b428d6bfcc911b5557f.png" /></p>
讯享网
是一种面向连接的可靠传输协议。
面向连接:数据传输之前,收发双方需要先建立一条逻辑通路。(端到端)
无面向连接(UDP):指的是数据可以自由传输,无需建立逻辑通路。
TCP是在不可靠的IP层之上,实现可靠的数据传输能力。
可靠----数据有序、无丢失、不重复
发送缓存
1、存放发送应用程序传输给发送方TCP准备发送的数据。
2、存放TCP已发送但是尚未收到确认的数据。
接收缓存
1、不按序到达的数据
2、按序到达,但未被应用程序接收的数据
TCP是面向字节流的。(收—->字节块,发—->字节流)
四元组:源IP、源端口、目IP、目端口。四元组是用来建立一个完整的TCP连接。
套接字:IP(组合)+端口(组合)

tcp既可以运载数据,又可以用来建立连接、释放连接和应答。
序列号
可以理解为字节流的编号。每发送一个字节的数据,序列号+1
确认序列号
是收到的报文的序列号+收到的数据部分字节大小
确认机制
每收到一个发送方发出的数据,都需要回复一个确认报文。
1、表明接收方期望收到发送方发送的下一个字节的序号。
2、代表接收方已经收到了确认序列号之前的所有字节数据。
累计确认
数据偏移
TCP报文段的数据起始处距离TCP报文段的起始处的距离。其本质是在描述TCP首部大小。
紧急指针
与控制位中的URG字段共同使用,当URG=1时,紧急指针有效。
紧急数据会被TCP放置在数据部分的最前方,即从第0个字节开始,而紧急指针是为了表明紧急数据的结束位置。
例如:紧急指针为70,则紧急数据位置为0字节到69字节。
选项字段
最大报文段长度MSS;窗口扩大银子;时间戳;选择确认机制。安全摘要选项。
标志位
紧急位URG:报文段中包含紧急数据,是高优先级的数据,应尽快传输,不再缓存队列中排队。
确认位ACK:当确认位置位1,则确认序列号有意义。在连接连接以后所有传输的报文段都必须把ACK置为1。
推送位PSH:接收方应尽快将数据交付给应用程序,不再等待缓存填满再向上提交。
复位RST:表明TCP连接中出现错误,必须释放连接,然后重新建立连接
同部位SYN:表明这是一个连接请求报文
终止位FIN:表明发送方数据已完全发送,要求释放连接。
确认、重传、排序、流控。
最大字节数由MSS控制。该参数是需要在TCP连接握手的过程中,通过前两次SYN报文段来进行参数协商。
如果双方的MSS数值不同,则选择数值较小的作为传输标准。
MSS受到MTU的限制。
MTU:最大传输单元,指的是数据链路层在封装成帧时所允许携带的最大数据量,在以太网当中,MTU数值为1500字节。
MSS:数据段中携带的数据字节数。
分片:这个操作是由网络层的IP协议来执行。
分段:这个操作是由传输层的TCP协议来执行。
PMTU---路径MTU
在IP报头中,有一个DF字段,该字段表明了IP报文是否允许被分片,PMTU功能开启后,该字段为1,标识不能分片。
此时当需要进行分片时,发现该报文无法分片,设备会丢弃该报文,并向发送源回复一个ICMP报文(数据不可达),同时携带上当前设备的MTU。
发送方接收该ICMP报文后,因为TCP重传机制,会重新发送一次数据,但是会根据最新的MTU来生成新的分段报文。
通过序列号字段,保证分段的有序性。将根据序列号的大小,将乱序的报文段进行重组。
是TCP保障可靠性的核心点。
TCP协议保证对方能够收到本端发送的数据段的方式,就是让对方回复一个确认报文段。这是确认机制的做法。
确认报文是唯一一种不需要被确认的数据段信息。
RTT/RTO
超时重传
当超过一定时间未收到确认报文,则触发重传机制。
超时重传的判断时间依据RTT(往返时间)参数来判断。RTO被称为超时重传时间。
RTT
指的是发送端将数据发出后,到他接收到对端反馈的确认报文之间的这段时间。
RTO取值应该略大于RTT,但是也不能太大。RTT并非是固定数值,他是动态变化的数值。
当连续多次未收到确认报文,设备会认为是网络拥塞过大,将重传时间加倍,因为如果按照原本的重传时间发送报文,很可能造成网络拥塞的加剧。
在TCP中,发送方可以通过接收方的反馈,在超时时间到达前,意识到数据包丢失的现象,并进行重传。这种情况一般出现在接收端收到一个失序报文的情况下。
快速重传机制不是因为RTO时间到达而触发,这种重传机制是以数据包为驱动的一种重传机制。
当接收方意识到自己所期望的报文段丢失,服务器不能调取失序报文,并且不能确认这些报文信息。
因为TCP协议无法直接发送一个否认确认报文(没有办法直接发送一个数据报文段,告诉对端自己哪个报文没有收到),所以,TCP将采用冗余ACK的方式来完成缺失报文通告。
TCP在可选项字段中,添加了一个变量。该变量中携带的就是自己已经收到的数据信息。
TCP的确认是累积确认机制,正确接收失序的报文段是不会被接收方逐个确认的。因此,发送方在重传的时候,需要将冗余ACK报文及之后的报文段都重新发送一遍。----造成资源浪费。
选择确认机制,不是所有运行TCP协议的设备都支持的。该机制会在TCP三次握手的前两次SYN报文中进行协商。
是属于TCP的传输效率问题。
滑动窗口
TCP头部中的”窗口值“是TCP实现流控的核心参数。
窗口的大小是可以指定的,该参数的大小指的是无需等待确认应答,而可以继续发送数据包的最大量。
窗口的大小————>接收缓存区的大小。
TCP要求发送方依据对方的接收窗口(rwnd)来控制数据的发送量。最初,TCP的接口窗口===接收缓存区大小。接口窗口会随着时间的增长而动态变化。


窗口关闭
窗口的大小是接收端根据自己的缓存空间的剩余量来决定的一个动态变化的数值,那么这个剩余量就有归0的可能性。也就代表此时接收方所有缓存空间均已占用并且没能及时处理里面的资源。
所以,当接收方反馈窗口值为0时,那其实就是在通知发送方,别再发送数据,处理不过来。
该机制存在风险:接收方通过确认ACK报文来通知发送方自己的窗口大小。理论上,如果接收方将自己的缓存里的数据清空后,将反馈一个窗口值非0的报文来通知对端,可以继续发送数据了。但是如果这个非0的ACK报文在重传过程中丢失----会引发风险,因为确认报文丢失不会触发重传机制。所以,客户端依然处于窗口关闭状态,不会发送数据,在等待服务器的响应。而服务器也在等待客户端发送数据。此时,两者进入到死锁状态。
解决方式:客户端周期性发送窗口探测报文,该报文只包含TCP首部信息。通过触发TCP确认机制,来让服务端发送确认报文,从而告知客户端,此时的窗口大小。打破死锁现象。

窗口大小仅仅是实现了将TCP数据传输的效率提高(不需要确认);但是并没有看到所谓的流量控制,而真正的流量控制是由窗口关闭机制实现的。
窗口扩大因子
TCP选项字段中的窗口扩大因子,可以解决首部中窗口值过小的问题。因为首部中窗口值大小仅为16bit,最大值为65536。
窗口扩大因子占据3字节大小。取值仅为0-14。是用来将TCP的窗口的值左移的位数,使得原本的窗口值加倍。
窗口扩大因子,只能出现在同步报文段中,否则将被忽略。
中间链路的处理能力--->拥塞控制机制
网络中对资源需求量超过了资源的可用量的情况,被称为拥塞。
如果出现了拥塞情况--->分组丢失。重传--->网络的拥塞情况加剧。
流量控制是为了让接收方能够来得及接收,而拥塞控制是为了降低整个网络的堵塞程度。
TCP判断此时网络环境出现拥塞的方式
TCP将连接中出现的丢包行为,视为拥塞的表现。
一种是数据包确认超时。
收到来自接收方发送的三个冗余ACK报文。
TCP控制数据的发送量的方式
拥塞窗口--->跟接收窗口一样,都可以对发送的字节数大小进行限制。
发送方,发出未收到确认的报文的字节数,必须小于或等于拥塞窗口和接收窗口的最小值。
拥塞窗口的数值是依靠TCP拥塞控制算法得出。TCP是在保证能够支持的最大传输效率的情况下,来保证没有拥塞发生,被称为自计时--->通过收到的确认报文来增加拥塞窗口。
拥塞控制算法
1、慢启动
通常在开始传输数据时,拥塞窗口会被设置的很小。一般等于一个MSS数值。即一次只能发送一个数据报文段。
每收到一个新的ACK确认报文,就会增加一倍MSS的大小。
TCP会设定一个慢启动门限来评判。评判是否要停止慢启动的机制。
当拥塞窗口<门限,继续使用慢启动算法
当拥塞窗口>门限,此时将慢启动算法切换为拥塞避免算法。
当拥塞窗口=门限,两者均可使用。
2、拥塞避免
在一个RTT时间线内,拥塞窗口只增加一个MSS。
拥塞避免算法,不是说直接避免拥塞,而是通过降低窗口的增大速率而使得网络不容易出现拥塞
3、快速恢复

eg:假设,最开始传输数据时,慢启动门限为16
1、通过慢启动算法,逐步增加窗口大小
2、当窗口大小≥门限值,则切换为拥塞避免算法
3、当网络中出现拥塞情况后,因为确认报文超时而判断的拥塞--->被称为快重传
3.1、此时将慢启动门限值设定为上一次门限值的一半,此时为8
3.2、将窗口大小设定为1
4、此时重新启动慢启动算法,重复之前过程
5、如果拥塞是因为三次冗余ACK而判断--->快恢复
5.1、将慢启动门限值设定为上一次门限值的一半
5.2、将窗口大小设定为此时的门限值,直接开始使用拥塞避免算法进行扩大窗口
延迟确认应答机制
收到数据以后不立即返回确认报文,而是延迟一段时间。
在没有收到2*MSS的数据为止,不做确认应答。
其他情况,最大延迟0.5秒发送确认应答。
捎带应答
TCP的确认应答和回执数据可以通过一个数据包进行发送。
延迟确认机制和捎带应答一般共同使用。
连接建立、数据传输、连接释放

TCP连接的建立(三次挥手)
TCP建立的双方都需要知晓对方的存在
要允许双方协议参数协商
设备可以为TCP连接分配相应资源(缓存空间)
TCP规定SYN被设置为1的报文段不能携带数据,但是要消耗一个序号。
问题一:初始序列号是什么产生的?为什么是随机值,而不是固定值?
初始序列号--->ISN:初始序列号产生是通过源地址、目的地址、源端口、目的端口和一个随机因子通过哈希算法计算得出的。后续又加入了时间因子。
出于安全性考虑,如果被知道了初始序列号,那么很容易可以构造出一个在对方窗口内的序列号。从而伪造出TCP报文,实现TCP会话劫持。
TCP序号绕回问题。
重复序号:当序号绕回后,之前已经使用过的序号可能会再次出现,导致接收方错误的将重复的报文段当做新的报文段处理。从而丢弃正常的报文。
延迟确认:因为延迟确认是收到一定数量的数据后才发送,而序号绕回会导致延迟确认的触发时间延后,从而降低数据传输的效率。
解决思路:使用时间戳选项来增加序号的有效范围。
问题二:什么是时间戳?
TCP时间戳--->记录数据报文发送的时间,其中有两个字段,分别为发送方时间;回显时间。
发送方发送数据时,将本地时间记录在发送方时间中。
接收方收到数据报文后,将收到的时间戳原封不动的返回给发送方,并在其中记录自己发送报文的时间。
发送方收到回应报文后,根据报文中的回显时间字段来判断该报文是否是正确的报文,如果是,则根据该时间计算RTT数值,并计算RTO数值。
时间戳是双向选择,需要在TCP连接建立阶段进行协商。
问题三:是否可以使用“两次握手报文”建立连接
采用三次握手形式,不是因为两次握手无法建立连接,而是为了防止已经失效的连接请求报文突然又传送到TCP服务端,从而导致服务端回复信息,建立连接,凭空消耗资源。
问题四:三次握手如何阻止历史连接
当客户端发送连接建立请求报文后,因为网络阻塞,导致客户端重新发送一个连接建立请求报文,这两个报文的序列号不同(因为为初始序列号)。
当网络阻塞减小时,可能旧的报文先到达服务端,而导致服务端回复SYN+ACK报文。此时服务端处于同步已接收状态(SYN-RCVD),但是此时对于客户端而言,服务端回复的报文是错误的报文,因为其确认序列号与客户端将要发送的报文的序列号不匹配,则客户端发送RST报文,断开连接。
当连接断开,服务端恢复到侦听状态,此时客户端发送的第二个连接请求报文到达。之后,正常建立TCP连接。
如果是两次握手,那么服务端在收到旧的SYN报文后,会直接进入到连接已建立状态。在该状态意味着已经可以发送数据,可能会存在数据传输。但是又因为此时的连接对于客户端而言时错误的,所以此时服务端传输的数据客户端不会接收。
问题五:如果已经建立了连接,但是客户端突然故障,怎么办?
TCP设计了一个保活计时器。
如果客户端出现故障,服务端不能一直等待下去,因为会白白浪费资源。
服务端没收到一次客户端的请求后都会复位保活计时器,一般为2小时,当保活计时器为0时,服务端主动发送探测报文,并每隔75秒发送一次。如果连续十次报文都没有接收到对端回复,则服务端认为客户端出现故障,关闭连接。
Time-Wait状态:客户端的倒数第二个状态。
在等待2MSL时间以后,客户端切换状态,进入关闭状态。MSL是最长报文段寿命。默认建议时间为2分钟。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/159415.html