网络基础---TCP协调中的三次握手四次挥手

TCP全称为 “传输控制协议(Transmission Control Protocol”). 人如其名, 要对数据的传输进行一个详细的控制
TCP,面向有连接的通讯协议,在传送数据之前必须先建立连接,数据传送完成后要释放连接,正因如此才成就了它的可靠性,今天我们就来剖析它通讯的具体过程。


TCP协议段格式
网络基础---TCP协调中的三次握手四次挥手
图片出处http://blog.csdn.net/guyuealian/article/details/52535294


源/目的端口各占2字节 表示数据从那个进程中来,到那个进程中去;

序号(seq)占4字节 它的主要作用是标记数据段 TCP连接中传送的字节流中的每个字节都按顺序编号 序号就是该字段中的第一个编号

确认号(ack)占4字节 它表示接收端已收到上次发送过来的报文段中的数据并且返还给发送端一个序号 这个序号便是下次发送端发送报文数据的第一个编号。

数据偏移,占4位,它指出TCP报文的数据距离TCP报文段的起始处有多远

保留位:由跟在数据偏移字段后的 6 位构成, 全部为 0

URG:为1时表明紧急指针字段有效,意思是这是紧急数据

ACK:占1位,仅当ACK=1时,确认号字段才有效。ACK=0时,确认号无效

PSH:当两个应用进程进行交互式的通信时,有时在一端的应用进程希望在键入一个命令后立即就能够收到对方的响应。在这种情况下,TCP 就可以使用推送(push)操作,这时,发送方 TCP 把 PSH 置 1 ,并立即创建一个报文段发送出去,接收方收到PSH = 1 的报文段,就尽快地(即“推送”向前)交付给接收应用进程,而不再等到整个缓存都填满后再向上交付。

RST:当RST=1时,表明TCP连接中出现严重差错,必须释放连接,然后再重新建立连接

SYN:在TCP连接建立时用来同步序号.SYN=1 ACK=0表示这是一个TCP连接请求报文 ; SYN=1 ACK=1表示这是一个TCP连接响应数据包

FIN:FIN表示释放一个连接 FIN=1尝试断开连接

窗口:占2字节,指的是通知接收方,发送本报文你需要有多大的空间来接受

检验和:发送端填充, CRC校验. 接收端校验不通过, 则认为数据有问题. 此处的检验和不光包含TCP首部, 也包含TCP数据部分

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


三次握手的基本流程

客户端(A)——————>服务端(B)(客户端向服务端发送请求连接数据包 )序号seq=x,表明传输数据时的第一个数据字节的序号是x
服务端——————>客户端(服务端收到请求后发送确认连接数据包 SYN=1 ACK=1)主机B的初始***seq(B)=y,以及主机B对主机A初始***的确认号ack(B)=seq(A)+1=x+1
客户端——————>服务端(客户端收到确认连接报后还需要确认)(ACK=1 发送一个***seq(A)=x+1;确认号为ack(A)=y+1的报文 )
完成后进入 estable (稳定状态) 然后可以进行数据传输

网络基础---TCP协调中的三次握手四次挥手
图片出处:https://blog.csdn.net/qzcsu/article/details/72861891

思考:tcp连接的建立为什么要进行3次握手?

有上面的分析可知,tcp在第二次握手完成的时候实际上已经建立了连接,可以进行数据传输了,但是为甚还要进行第三次握手。

这其实是为了防止已经失效的连接请求报文段突然又传给了服务器,因而产生错误,你想想假如现在Client端向Server端发送请求连接,而这个报文段却在网络结点中迷路了 ,(于是乎Client再次向server端发送请求连接,这次连接进行的很顺利,正常上班-工作-然后下班 )但在连接释放以后Client发送的这个迷路报文段才到达server,此时这个报文段就是一个已经失效的连接请求报文段。但Server收到这个报文段后并不知其失效,以为是Client又发送的一次请求,就会向Client发送同意建立连接的确认报文段。但问题是Client并没有给Server发送请求,因此也会对这个确认报文段不予理睬,也不会发送数据。但Server会以为连接建立了,并会一直处于等待状态,等待对方的数据,在这样的情况下,Server的一些资源就会浪费了。

但是采用三次握手就不一样了,你迷路的报文再次到达server,server同意后发送给client确认报文,client想着我没有发送请求啊,于是没有发送第三次确认,server没有收到确认,就知道client没有发送请求。


四次挥手的基本流程

怎样理解四次挥手
(断开连接是两个人的事情所以我们必须双方向上共同断开连接)

客户端————>服务器 (客户端发送释放连接请求FIN=1和seq=u)客户端进入FIN_WAIT1状态
服务器————>客户端 (服务端发送响应报文ACK 和 ack=u+1) 服务端就进入了CLOSE-WAIT(关闭等待)状态
服务器————>客户端 当服务器的数据传递完后就向客户端发送连接释放报文,FIN=1,ack=u+1 服务器进入last_ack(最后确认)状态 等待客户端确认
客户端————>服务器 发送一个确认ACK 然后进入Time_wait(防止ACK丢失) 如果丢失就重新发送ACK
time_wait等待时间=2MSL 一般为120s

网络基础---TCP协调中的三次握手四次挥手

为什么要进行4次挥手?

TCP建立连接要进行三次握手,而断开连接要进行四次。这是由于TCP的半关闭造成的。因为TCP连接是全双工的(即数据可在两个方向上同时传递)所以进行关闭时每个方向上都要单独进行关闭。这个单方向的关闭就叫半关闭。当一方完成它的数据发送任务,就发送一个FIN来向另一方通告将要终止这个方向的连接。

为什么time_wait还需要进行等待2MSL才进入close状态?

这是因为为了保证最后一个确认ACK能顺利到达 MSL是TCP报文的最长生存时间, 因此TIME_WAIT持续存在2MSL的话 就能保证在两个传输方向上的尚未被接收或迟到的报文段都已经消失(否则服务器立刻重启, 可能会
收到来自上一个进程的迟到的数据, 但是这种数据很可能是错误的); 同时也是在理论上保证最后一个报文可靠到达(假设最后一个ACK丢失, 那么服务器会再重发一个FIN. 这时虽然客户端的进程不在了, 但是TCP连接还在, 仍然可以重发LAST_ACK)