网络——TCP协议

    TCP是一种面向有连接的传输层协议,它可以保证两端通信主机之间的通信可达。TCP能够正确处理在传输过程中丢包、传输顺序乱掉等异常情况。此外TCP还能够有效的利用带宽,缓解网络拥堵。

    然而,为了建立于断开连接,有时它至少需要7次的发包和收包(三次握手、四次挥手),导致网络流量的浪费。

TCP报头格式:


32位序列号:是指发送数据的位置,每发送一次数据,就累加一次数据字节数的大小。序列号不会从0或是1开始,而是在建立连接时由计算机生成的随机数最为其初始值,通过SYN包传给接收端主机。然后再将每转发过去的字节数累加到初始值上表示数据的位置。此外在建立和断开连接的时发送的SYN包和FIN包虽然没有数据,但是也会作为一个字节增加对应的序列号。

32位确认序号:指下一次收到数据的序列号,实际上,它是指已收到确认应答号减一为止的数据。发送端收到这个确认应答以后可以认为在这个序列号以前的数据都已经正常接收。

6位保留:新增功能

6位标志位

URG:该位为1时,表示包中有需要紧急处理的数据。

ACK:该位为1时,确认应答字段变为有效。TCP规定除了最初建立连接时的SYN包之外,该位必须设置为1.

PSH:该位为1时,表示需要将收到的数据立刻上传给上层应用协议。PSH为0时,则不需要立即传而是先进行缓存。

RST:该位为1时,表示TCP连接中出现异常必须强制断开连接。

SYN:用于建立连接。SYN表示希望建立连接,并在其序列号的字段进行序列号的初始值设定。SYN本身由同步的意思,意味着建立连接的双方,序列号和确认应答号要保持同步。

FIN:该位为1时,表示之后再不会有数据再发送,希望断开连接

16位窗口大小:用于通知从相同TCP首部的确认应答号所指位置开始能够接收的数据大小(8位字节)。TCP不允许发送超过此处所示大小的数据,不过,如果窗口为0,则表示可以发送窗口探测,以了解最新的窗口大小。但是数据必须是1个字节。

16位紧急指针:标识哪部分数据是紧急数据。


连接管理机制:(这篇博客——TCP通讯流程



注:客户端需要等待一个2MSL(报文最大生存时间)的时间才会进入CLOSED状态。


TIME_WAIT状态:

有时候当服务器的应用程序终止了,但是TCP协议层的链接并没有完全断开,因此不能再监听到服务器的端口,

TCP协议规定,主动关闭链接的一方要处于TIME_WAIT状态,等待一个2MSL(报文最大生存时间)的时间才会进入CLOSED状态。

使用2MSL在理论上也是保证最后一个报文的可靠到达。

TCP的可靠性:

为了实现TCP数据报可靠性传输,需要考虑好多事情,例如损坏、丢包重复以及分片混乱等问题,所以TCP通过检验和、序列号、确认应答、重发控制、连接管理以及窗口等机制实现可靠性传输。

通过序列号与确认应答提高可靠性

    在TCP中,当发送端的数据到达接收端的主机时,接收端主机会返回一个已经收到消息的通知,这个消息就是ACK(确认应答)。

        

    TCP通过肯定的ACK实现可靠的数据传输,当发送端将数据发送之后会进行等待对方的ACK,如果收到了对方的ACK,则代表数据已经成功被接收端接收。反之,数据就有可能已经丢失,发送端就重新发送该数据。

    但是,数据其实也不一定丢失,也有可能是接收端返回的ACK在传输途中丢失,那么发送端也会认为是数据包丢失,从而给接收端重发数据,这样就会造成接收端一直收到同样的数据,所以就会引入序列号。

    序列号是按照序号给发送的每一个字节都标上号码的编号。接收端查询TCP首部中的序列号和数据的长度将字节下一次要接收的序列号作为ACK返回给发送端,这样通过序列号和确认序号就能更好的提升TCP的可靠性传输。

 

重发超时:

    重发超时是指在重发数据之前,ACK来临之前的那个时间间隔,如果超过了这个时间还是没有收到ACK,才会重发数据。一般这个时间间隔会设置在6秒。但是发送端也不会一直重发,当重发达到一定的次数后,会判定对端主机发生了异常,强制断开连接,通知应用通信异常终止。

连接管理:上述连接管理机制;

 

TCP以段为单位发送数据:

    在建立TCP连接的同时,也可以确定发送数据包的单位,成为“最大消息长度”。最理想的情况是,最大消息长度刚好是IP中不会被分片处理的的最大数据长度。

TCP在传送大量数据时,是以MMS的大小将数据进行分割发送。重发时也是以MMS为单位。

MMS是在三次握手时,两端主机之间被计算得出。两端主机在发起建立连接的时候,会在TCP首部写入MMS选项,告知对方自己能适应的MMS的大小。

 

滑动窗口:

    TCP以一个段为单位进行传输,每发送一个段就进行一次确认应答的处理。这样有一个缺点,包的往返时间越长,那么通信性能就越低。为解决这个问题,TCP引入了窗口的概念。

        

     在这种情况下,确认应答是以更大的单位确认时,转发时间将会被大幅度缩短。也就是说,发送端主机发送数据后,不用在等待ACK,而是在继续发送数据。

    在滑动窗口以外的部分包括尚未发送的数据和已经确认接收端已收到的数据。当数据发出后,在规定时间收到了ACK,则不需要重发,同时将此数据从缓存区清除。

    收到确认应答的情况下,将滑动窗口滑到确认应答中的序列号的位置。这样可以顺序的 将多个段同时发送提高通信性能。

        

 

流量控制:

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

     接收端可以将可接收缓冲区大小放入TCP首部中的“窗口大小”,通过ACK返回给发送端。接收端一旦发现自己的缓冲区快满了,就会将窗口大小设置为一个更小的值通知给发送端。

 

拥塞控制:

    虽然TCP有了滑动窗口来提升传输速率,但是如果有刚建立连接就开始大量传输数据的话,也会引发一些问题。首先,先在发送端定义一个“拥塞窗口”的概念。然后,在慢启动的过程中将窗口大小设置为一个数据段(1MMS)。之后每收到一个ACK,则拥塞窗口大小就加一,将窗口大小与接收端主机通知的大小进行比较,选择其中的一个较小值,就发送一个比较小值还小的数据量。

          

     像上面这个拥塞窗口的增长速度是指数级别的,“慢启动”只是指初始时慢,但是增长速度还是挺快的。

为了使之不增长那么快,因此,不能使拥塞窗口单纯的加倍,所以要引入一个叫做慢启动的阈值,当拥塞窗口超过这个阈值后,就不按照指数的形式增长,而是按照一定的线性方式增长。

                                      

 少量的丢包,我们可以认为是触发了超时重传机制,但是大量的丢包,我们就可以认为是网络拥塞。拥塞控制,是TCP想快速高效的将数据发送给对方,但是又要避免造成网络压力的折中方案。

延迟应答:

                                     

捎带应答:

                                         

粘包问题(数据包):

站在传输层的角度,TCP是一个一个报文过来的,按序号排好放在缓冲区里的,站在应用层的角度,看到的只是一连串的字节数据,就不知道是从哪部分开始和结束是一个完整的数据包。

要避免粘包问题,必须明确两个包之间的边界。

1. 对于定长的包,保证每次都按照固定的大小读取即可,

2. 对于变长的包,可以在报头的位置,约定一个包总长度字段,从而就知道了包的结束位置,

3. 对于变长的包,还可以在包与包之间使用明确的分隔符。

保活定时器:定期的询问对方是否还在,如果不在就释放连接。

定时器(超时重传定时器,保活定时器,TIME_WAIT定时器)。













猜你喜欢

转载自blog.csdn.net/duckyloser/article/details/80763881