网络原理——TCP协议

目录

一.TCP概念及其特性      

二.TCP原理

1.确认应答机制

2.超时重传机制

3.连接管理机制

三次握手的过程

四次挥手断开连接过程

四次挥手断开连接变形情况:

为什么连接阶段时三次握手,断开连接是四次挥手? 

服务器上面出现大量的CLOSE_WAIT状态的TCP连接,请问这种现象是否合理?

既然主动关闭端挥手的工作已经完成了,为什么还有TIME_WAIT状态而不直接进入CLOSED状态?

为什么是TIME_WAIT的时间是2MSL?

4.流量控制

5.滑动窗口机制

那如果在传输数据时出现了数据丢失,如何进行重传?

 6.拥塞控制

7.延迟应答机制

8.捎带应答机制


一.TCP概念及其特性      

传输控制协议:TCP(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能。 用户数据报协议(UDP)是同一层内另一个重要的传输协议。

特性:可靠性,有连接,面向字节流
什么是可靠性:
1.TCP会尽自己所能,尽量将数据发送给对方
2.TCP汇集那个数据没有发给对方的情况下,给应用层一个错误通知
3.TCP可以保证接收方(应用层)严格按照发送时的顺序接收
4.TCP保证数据不会无意间的损坏
5.TCP尽可能的维护网络质量  

二.TCP原理

1.确认应答机制

网络原理——TCP协议_第1张图片

发送方发送数据,如果收到了接收方的应答(确认),就代表了接收方收到了数据;

如果超过一定时间没有收到接收方的应答(确认),可以推测接收方未能收到数据。

*如果发送方同时发送了多条数据,如何确认接收方的确认信息是指的那一条数据?

答:对数据进行编号,接收方发出确认信息的时候也带上编号,就可以明确接受的数据。

对数据进行编号

1.发送的数据编号——序列号  SN(Sequence Number)  

2.确认时的数据编号——确认序列号  ASN(Acknowledge Sequence Number)

3.初始序列号ISN(initial sequence number):在 TCP 建立连接的时候,客户端和服务端都会各自生成一个初始序列号,它是基于时钟生成的一个随机数,来保证每个连接都拥有不同的初始序列号。

* 如果超过一定时间没有收到接收方的确认,该如何操作?

答:进行重发。进行重发需要触发的条件:超过一定时间没有收到接收方的确认

2.超时重传机制

先思考:如果没有收到对方发送的应答,可能的情况有哪些

        1.对方没有收到你的数据所以没有应答;又分为以下两种情况

        (1):数据还在路上,暂时还没有到达对方

        (2):数据在路上丢失了,所以不会有应答

        2.对方收到数据了发出来应答,但是应答我没有收到;又分为以下两种情况

        (1):应带还在路上,我们暂时还没有收到

        (2):应答在路上丢失,我们不会收到应答

如果是上面1(1),2(1)这两种情况,我们可以选择合适的时间差进行重发;

如果是1(2),2(2)这两种情况,我们是否能选择重发,还是需要进一步的辨别?

        答案是重发,看看下面的分析:

网络原理——TCP协议_第2张图片

        主机A发送数据给B之后,可能因为网络拥堵等原因,数据无法到达主机B;
        如果主机A在一个特定时间间隔内没有收到B发来的确认应答,就会进行重发;

网络原理——TCP协议_第3张图片

        主机B会收到很多重复数据。那么TCP协议需要能够识别出那些包是重复的包,并且把重复的丢弃掉。这时候我们可以利用前面发送数据时的序列号,就可以很容易做到去重的效果。

那该如何选择再次发送数据的时间?

        这个时间的长短,随着网络环境的不同,是有差异的。如果超时时间设的太长,会影响整体的重传效率;如果超时时间设的太短,有可能会频繁发送重复的包;

        一般来说会略大于往返时间RRT(Round Trip Time),RTT需要进行多次测量计算得来

新RTTS=(1−α)×旧RTTS+α×RTT

        a的取值为:0≤α≤1,RFC推荐的αα值为1/8,即0.125。通过上面的公式得出的加权平均往返时间RTTs就比直接测量得出的RTT更加平滑。TCP为了保证无论在任何环境下都能比较高性能的通信,因此会动态计算这个最大超时时间。

如果是网络(物理层)出现问题,会一直的重发下去吗?

        不会,TCP会尝试重发几次(重发的次数不同版本的操作系统会有不同),如果还是收不到应答,就会停止发送。然后需要通知应用层,发送失败。

3.连接管理机制

在正常情况下,TCP要经过三次握手建立连接,四次挥手断开连接。

三次握手的过程

网络原理——TCP协议_第4张图片

TCP的主动连接方一般为客户端

TCP的被动连接方一般为服务器

来看一看客户端和服务器在三次握手中的状态变化

客户端:

CLOSED -> SYN_SENT : 客户端调用connect,发送同步报文段;
SYN_SENT -> ESTABLISHED : connect调用成功,则进入ESTABLISHED状态,开始读写数
据;

服务器:

CLOSED -> LISTEN: 服务器端调用listen后进入LISTEN状态,等待客户端连接;
LISTEN -> SYN_RCVD: 一旦监听到连接请求(同步报文段),就将该连接放入内核等待队列
中,并向客户端发送SYN确认报文。
SYN_RCVD -> ESTABLISHED: 服务端一旦收到客户端的确认报文,就进入ESTABLISHED状
态,可以进行读写数据了。

三次握手阶段是否可以携带payload?

1.第一次握手,主动连接方发送syn,不可以携带数据

2.第二次握手,被动连接方发送syn+ack,不可以携带数据

3.第三次握手,主动连接方发送ack,可以携带数据

 原因:因为在第一次和第二次握手阶段时,不能确认连接一定建立成功,如果携带了数据,则会提升发送成本,还会接受失败,所以TCP协议设计时禁止了携带数据;第三次握手连接已经建立成功,所以第三次握手可以发送数据。

 TCP三次握手阶段SN与ASN的变换

主动连接方初始化序列号为:ISN : a ;

被动连接方初始化序列号为:ISN : b ;

 第一次握手阶段 :syn  len = 0; SN = a ;ASN = 0;

第二次握手阶段 :syn + ack len = 0; SN = b ; ASN = a+1;

第三次握手阶段 : ack  len = ? ; SN = a+1 ; ASN = b+1;

由于第一二次握手阶段不能携带数据,所以len = 0;第三次握手阶段中 "?"表示携带数据的长度;

四次挥手断开连接过程

网络原理——TCP协议_第5张图片

四次挥手断开连接的状态变化

客户端:

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状态。

服务器:

ESTABLISHED -> CLOSE_WAIT: 当客户端主动关闭连接(调用close),服务器会收到结束
报文段,服务器返回确认报文段并进入CLOSE_WAIT;
CLOSE_WAIT -> LAST_ACK:进入CLOSE_WAIT后说明服务器准备关闭连接(需要处理完之前
的数据);当服务器真正调用close关闭连接时,会向客户端发送FIN,此时服务器进入
LAST_ACK状态,等待最后一个ACK到来(这个ACK是客户端确认收到了FIN)
LAST_ACK -> CLOSED: 服务器收到了对FIN的ACK,彻底关闭连接。

四次挥手断开连接变形情况:

三次挥手

网络原理——TCP协议_第6张图片

 双方同时挥手

网络原理——TCP协议_第7张图片

为什么连接阶段时三次握手,断开连接是四次挥手? 

        当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可能未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。所以断开连接是四次挥手

 *CLOSE_WAIT一定出现在单方面分手的被动关闭端

服务器上面出现大量的CLOSE_WAIT状态的TCP连接,请问这种现象是否合理?

        无法确定是否合理;如果我们的程序设计时,会出现比较长时间的单方面关闭的情况时,会出现大量CLOSE_WAIT是合理的现象,但如果我们没有这种设计,则不合理,可能出现的原因是忘记调用socket.close()方法。

TIME_WAIT 状态发生在主动关闭端,出现在基本挥手已经结束的情况;

既然主动关闭端挥手的工作已经完成了,为什么还有TIME_WAIT状态而不直接进入CLOSED状态?

       (1) TIME_WAIT存在的理由之一是尽可能护送最后的ACK达到对端。

        因为不能确保发出去的ACK对方一定会收到,所以还需要等待一段时间,如果对方没有收到ACK,主动关闭端需要重发FIN,如果主动关闭端处于CLOSED的状态,对方就无法收到最后的ACK。

        (2)为了使就得数据包在网络中因过期而失效

        假设没有time_wait状态时,A刚刚与B断开连接,C又以和A相同的ip和port和B建立起连接,TCP协议栈无法区分A和C是不同的连接, 这时,A连接发送的数据到达B之后会被B的TCP传输层当做当下正常的连接发来的数据进行处理。

为什么是TIME_WAIT的时间是2MSL?

        MSL,Maximum Segment Lifetime,最大报文段生存时间。即任何TCP报文在网络中存在的最大时长,如果超过这个时间,这个TCP报文就会被丢弃。

        因为主动关闭端不知道对方是否能收到ACK应答数据包,如果没有收到ACK,会进行重传FIN,考虑最坏的一种情况:第四次挥手的ACK包的最大生存时长(MSL)+服务端重传的FIN包的最大生存时长(MSL)=2MSL。

现象:服务器上发现了大量的TIME_WAIT状态的TCP连接,是否合理?不合理,给出修复意见。

        理论上是合理的,但是如果影响了导致了新连接创建失败,就不太合理了

        一般来说客户端背负的连接比较少,服务器背负的连接远远多于客户端。由于维护连接是需要成本的,所以不建议服务器去主动关闭连接。

4.流量控制

接收端处理数据的速度是有限的。如果发送端发的太快,导致接收端的缓冲区被打满,这个时候如果发送端继续发送,就会造成丢包,继而引起丢包重传等等一系列连锁反应。
因此TCP支持根据接收端的处理能力,来决定发送端的发送速度。这个机制就叫做流量控制(Flow
Control);

 接受窗口:接收缓存区中剩余空间的大小

作为发送方,如何实时的知道接收方的接受能力?

        1.发送Segment Header,将自己的的接收能力(接收窗口的大小)填写到窗口字段中,发送给对方;

        2.TCP即使没有数据发送时 ,也会定期发送Segment Header ,传递最新的接受能力;

5.滑动窗口机制

先了解一下发送缓冲区的逻辑部分

网络原理——TCP协议_第8张图片

 连接建立阶段,通过三次握手,就可以知道对方的接收窗口

网络原理——TCP协议_第9张图片

 应用层写入了需要发送的数据

网络原理——TCP协议_第10张图片TCP发送一部分数据给对方

网络原理——TCP协议_第11张图片 收到了来自接收方的应答

          网络原理——TCP协议_第12张图片橙色部分:已应答部分,没必要在保留,可以视为可用空间

紫色部分:发送为应答部分

蓝色部分:应用层写入的还未发送的数据

 了解这些知识后,再来看看滑动窗口机制时如何实现的

       网络原理——TCP协议_第13张图片

 网络原理——TCP协议_第14张图片

应用层写入数据窗口增加,收到接收方的应答后减小窗口,实现滑动窗口机制。

那如果在传输数据时出现了数据丢失,如何进行重传?

分为两种情况:

1.接收方的应带丢失

网络原理——TCP协议_第15张图片

这种情况下,部分ACK丢了并不要紧,因为可以通过后续的ACK进行确认; 

 2.发送数据的数据包丢失(快重传机制)

网络原理——TCP协议_第16张图片

        当某一段报文段丢失之后,发送端会一直收到 1001 这样的ACK;
        如果发送端主机连续三次收到了同样一个 "1001" 这样的应答,就会将对应的数据 1001 -
2000 重新发送;
        这个时候接收端收到了 1001 之后,再次返回的ACK就是7001了(因为2001 - 7000)接收端
其实之前就已经收到了,被放到了接收端操作系统内核的接收缓冲区中; 

        这种机制被称为 "高速重发控制"(也叫 "快重传")。

 6.拥塞控制

        网络上有很多的计算机,可能当前的网络状态就已经比较拥堵。在不清楚当前网络状态下,如何发送数据;

拥塞控制:根据网络目前的承载能力来控制数据的发送量;

拥塞窗口 (cwnd):是发送方维护的一个 的状态变量,它会根据网络的拥塞程度动态变化的。

网络原理——TCP协议_第17张图片

横坐标:时间

纵坐标:当前计算出的拥塞窗口(cwnd)

慢开始:拥塞窗口的初始值非常小

指数增长->线性增长中间阈值(ssthresh) cwnd = cwnd^c ;上图中(c 为1)

线性增长->cwnd = cwnd + c(常数) 

当遇到了网络拥塞,慢启动阈值会变成原来的一半,同时拥塞窗口(cwnd)置回1;

7.延迟应答机制

 假设接收端缓冲区为1M。一次收到了500K的数据;如果立刻应答,返回的窗口就是500K;但实

际上可能处理端处理的速度很快,10ms之内就把500K数据从缓冲区消费掉了;在这种情况下,接

收端处理还远没有达到自己的极限,即使窗口再放大一些,也能处理过来;如果接收端稍微等一会

再应答,比如等待200ms再应答,那么这个时候返回的窗口大小就是1M;

网络原理——TCP协议_第18张图片

数量限制:每隔N个包就应答一次;

时间限制:超过最大延迟时间就应答一次;

具体的数量和超时时间,依操作系统不同也有差异;一般N取2,超时时间取200ms;

8.捎带应答机制

可以减少应答次数,将应答和数据一起发送,提高效率。

网络原理——TCP协议_第19张图片

 

你可能感兴趣的:(网络,tcp/ip,网络协议)