关于TCP的启动连接说明
一、TCP是什么?
二、TCP的头部解析以及说明
三、TCP的启动说明
3.1 TCP的启动流程
3.2 TCP的序列号和确认号
3.3 TCP的状态改变
四、TCP的关闭说明
4.1 TCP的关闭流程
4.2 TCP的序列号和确认号
4.3 TCP状态的改变
五、关于滑动窗口大小和最大发送值的概念区别
一、TCP是什么?
TCP是基于连接的,可靠的,基于字节流的传输控制。
二、TCP的头部解析以及说明
源端口(16位) |
目的端口(16位) |
||
序列号(32位) |
|||
确认号(32位) |
|||
TCP长度(4位) |
保留位(6位) |
SYN/URG/RST/FIN/ACK/CWR |
窗口大小(16位) |
TCP校验和(16位) |
紧急指针(16位) |
||
选项(40位) |
二、关于TCP的头部解析:
源端口,目的端口:在网络中有所谓的五元组(源端口号,目的端口号,源IP,目的IP,传输协议)。源端口和目的端口就是五元组中的源端口号和目的端口号。
序列号和确认号:
所谓序列号,就是每个发送包的序号,这个序号是按照时间来确定的,换句话说序列号不是从1开始的,它是根据时间的大小来进行确定的,从2的32次方-1循环递送。
确认号:所谓确认号就是指该包希望下一个接收包发送过来的数据,这个包也是用来检测是否接收到上一个数据,比如说如果当前发送的包是2048,那么我们可以认为1~2048号包已经全部被接收,此时下一个包传过来的序列号也应该是2048。
TCP长度:TCP的长度其实是本TCP头部的大小,TCP头部的大小不是固定的,它最小的包的大小是20,最大的包的大小是60(这是因为有40位的选项),所以TCP的长度是在20到60之间的。
在这之后就是各个指针的位置了。分别是SYN/URG/RST/FIN/ACK以及CWR等六种标志位,这里做一个简单的说明,后续TCP中对每一个标志位有更加详细的说明。
SYN:SYN是用于初始化连接的同步序列号,TCP连接中第一个数据包就是SYN。
URG:用于紧急指针,这一位与后面的紧急指针位相关联。
RST:用于复位功能,RST一共有三种功能,分别是:
1、一个就是在半关闭状态的时候所采用的方法。
2、一个是由于连接错误,需要强制取消的时候所采用的方法。
FIN:用于告知另一方请求终止服务,一般是TCP的最后一个包。
窗口大小:由于TCP采用的滑动窗口制,每一次的窗口大小都需要调整,因此需要该机制来解决。
TCP校验和:比较好理解,就是验证TCP传送的数据包是否正确,这个校验的方法跟UDP什么是一样的。
紧急指针:紧急指针就是告知另一方发送是否为紧急数据的最后一位,至于第一位是什么,由应用层协议设置。
选项:一般设置MSS,MSS如果是本地1460,不是本地536。
三、TCP的启动说明
3.1 TCP整体的启动说明
TCP的整体启动流程基本可以概括成三次握手。简单来说就是首先客户端发送一个SYN数据包请求和服务端连接,如果服务端同意连接,那么会发送一个ACK包并同时发送一个SYN包与客户端连接,之后客户端会发送一个SYN包和ACK包给服务器,确认其没有问题。此时表明TCP连接成功。它的流程图可以按照如下图示。
3.2 TCP的启动状态变迁
首先说一下TCP的启动状态变迁。在一开始的时候,客户端和服务端的状态都是关闭的,此时客户端发送连接请求,客户端的状态变成SYN_SENT,此时客户端发送第一个数据包SYN,此时客户端接收到数据包以后,如果接受了这个客户端的请求,此时客户端变成SYN_RCV状态,同时会向客户端发送一个数据包。当客户端接收到SYN(K)的数据包后,状态从SYN_SENT变成ESTABLISH,同时会向服务端发送一个ACK和SYN包,当服务器收到以后从SYN_RCV变成ESTABLISH。
3.3 TCP启动时的序列号和确认号分析
第一段TCP启动时的序列号和确认号:序列号为一个随机分配数值(随着时间变化而变化),这样做的原因是什么呢?如果说当前有一个连接此时的序列号为J,然后我们立即断开该连接,同时建立一个新连接,传送数据,由于我们之前的数据包还存在在系统中,那么此时系统就不知道到底这个数据是之前传送的还是之后传送的。而确认号此时为0。
第二段TCP启动时的序列号和确认号:那么此时就有一个确认号和序列号。此时序列号是K,而确认号的值是J+1。
第三段TCP启动时候的序列号和确认号:那么此时就有一个确认号和序列号。此时序列号是J+1,确认号的值是K+1。
假如有第四段,那么此时第四个包的确认号和序列号:序列号的值是K+1,确认号的值是J+2。
四 TCP的关闭说明
4.1 TCP的关闭流程分析
TCP的关闭流程是这样的,首先,当TCP关闭时,首先客户端发送一个FIN信号给服务器,服务器在接收到这个信号之后,其状态变成CLOSE_WAIT,此时会发送一个ACK数据给客户端,此时,从客户端到服务器的单向通道关闭。当过一段时间以后,服务器会向客户端发送一个FIN信号,当客户端接收到信号之后,会返回一个ACK数据给服务器,此时服务器关闭,通道关闭。其流程如图所示。
4.2 TCP的关闭状态改变分析
首先,第一步当客户端开始发送FIN信号时,客户端的状态变成FIN_WAIT1,之后将FIN信号发送给服务器时,服务器的状态变成CLOSE_WAIT,另外此时发送一个ACK信号,此时客户端的状态变成FIN_WAIT2。
第二步,服务器的状态变成LAST_ACK,此时发送一个状态给客户端,客户端的状态变成TIME_WAIT,之后客户端发送一个ACK的包给服务器,此时服务器关闭。
这里有一点要说一下,就是关于这个TIME_WAIT的状态,当客户端到达这个状态以后,并不是关闭状态,这是为什么呢?因为如果最后一个ACK发送出去以后,服务端没有接收到数据,而此时客户端关闭,服务端会一直开启,这是不可以的,所以客户端必须要等到服务器完全关闭以后,客户端才能关闭。具体流程是这样的:首先当客户端收到服务器发送的FIN操作时候,会启动一个定时器,这个定时器的长度设置成2MSL,MSL表示这个包到达另一端的时间,之所以是2倍是两次传输,如果服务器没有收到,他会继续发送FIN包,当客户端接收以后他会清空定时器,重新记时。
4.3 TCP的关闭序列号分析
TCP的关闭序列号分析:关闭序列号比较简单,首先第一步就是FIN包序列号为K,确认号为上一个包的序列号+1,接着服务器会回一个ACK包(确认号为K+1),另一端服务端向客户端发送FIN包,序列号为M,返回的ACK确认号为M+1。
五、关于滑动窗口大小和最大发送值的概念区别
关于TCP的几个概念分析:
MTU:就是链路层的最大容量,一般来说是1500。
MSS:MSS是TCP给发送数据的确认值,一般是1500-40=1460个大小。
窗口大小:我们传送窗口时,所决定的不单单是发送链路的大小,也跟对方能否接收的大小有很大的关系,即如果对方目前能够接收4096个字节,但是你目前却传送了5000个字节,对方无法接受,那么这次就是失败的。所以,这里面有如下说法:
我们假设A端目前的初始位置是0,此时b端发送过来的确认号码是4096,那么也就是说目前b端能够接受的最大数据量是4096,那么A端窗口此时的结束位置就是4096,此时我们开始发送,加入我们此时发送过去的值为1024,那么此时b端会有三种可能:
IF b端没有发送ACK
那么此时A端窗口的初始位置和中止位置是没有改变的,在一段时间以后TCP会重新传输数据。
ELSE IF b端发送ACK
如果此时B端发送ACK,但是窗口大小显示3072,那就说明此时数据目前存储在b端的缓冲区中,没有移动,此时初始值发生改变,为1024,结束值没有改变为4096。
ELSE IF b端发送ACK
如果此时B端发送ACK,而此时窗口大小显示4096,那就说明此时数据已经被取走,告知A端可以继续传送,此时A端窗口初始值是1024,结束端为1024+4096=5120了。此时进入到下一个循环。