TCP 位于传输层,提供可靠的字节流服务。php
可靠的字节流服务:TCP 协议为了传输方便,将大块数据分割成以
报文段(segment)
为单位的数据包进行管理,并可以把这些数据准确可靠的传递给对方。
下面是一张 TCP 报文格式的图片:html
其中,几个比较重要的字段以下:缓存
每一个 TCP 报文内都有序号和确认号,结合重传机制保障数据传输的可靠性服务器
序号+1
,保证每发送不一样的数据包,数据包的序号都是不一样的网络
seq+1
,之前的字节已经收到过了,ACK标志位被设置为1的时候,才会发送ack确认号。TCP 报文共有6个标志位,每一个占1位,共6位,每一位的值只有0和1spa
TCP 链接的创建采用客户-服务器模式,主动发起链接创建的应用进程叫作客户,被动等待链接创建的应用进程叫作服务器,如下是创建 TCP 链接的过程:.net
客户端向服务端发送请求链接
报文,将报文同步标志位 SYN 的值设置为1
,表示要建立链接,等待服务器确认,并进入SYN_SENT
状态。(报文首部:SYN=1, 初始序号 seq=x(x为随机生成数值))
3d
服务端接收到客户端的请求,回复给客户端确认报文,将报文确认标志位 ACK 的值设置为1
,告诉客户端已收到它的请求,赞成建立链接,并进入SYN_RECV
状态。(ACK=1,确认号 ack=x+1,SYN=1,初始序号 seq=y)
指针
客户端接收到服务端的确认报文以后,为了防止意外,再次向服务端发出确认报文,将报文ACK 的值设置为1
,当服务端收到客户端发来的确认报文以后,TCP 链接创建,客户端和服务端都进入ESTABLISHED
状态,完成三次握手,之后就能够开森的传递数据了。(报文首部:ACK=1, 确认号 ack=y+1, 序号 seq=x+1(服务端传过来的ack的值)
code
因为 TCP 链接是双工
的,所以每一个方向都必须单独进行关闭。当一方完成它的数据发送任务后就能够发送一个FIN
终止标志位来终止这个方向上的链接,收到一个FIN
就意味着这一方向上没有数据流动
。一个 TCP 链接在收到一个 FIN 后仍能发送数据,首先进行关闭的一方将执行主动关闭
,而另外一方执行被动关闭
。
客户端主动向服务端发出断开 TCP 链接
的请求报文,将报文终止标志位 FIN 设置为1
,表示要释放 TCP 链接,并进入等待结束链接状态FIN_WAIT-1
。(报文首部:FIN=1,序号 seq=u(u为随机数))
服务端收到客户端的释放链接请求后,回复确认报文给客户端,将报文确认标志位 ACK 设置为1
,表示已收到客户端请求,关闭服务端读通道
并进入关闭等待状态 CLOSE-WAIT
。(报文首部:ACK=1,确认号 ack=u+1(收到的序号+1),序号 seq=v(v为随机数))
客户端收到确认报文后,会关闭客户端写通道
,此时客户端仍能经过读通道读取服务端的数据,服务器仍能经过写通道写数据。
服务端发送断开 TCP 链接
的请求报文,将报文终止标志位 FIN 设置为1
。表示服务端数据已发送完毕,要释放链接,不会再发送任何数据了。(报文首部:FIN=1,ACK=1,确认号 ack=u+1(收到的序号+1),序号 seq=w(w为随机数))
客户端收到服务端的断开链接请求后,回复确认报文,将报文确认标志位 ACK 设置为1
,关闭客户端读通道
,服务端收到客户端的确认报文
后,关闭服务端读通道
。双方读写通道所有关闭,完成四次挥手。(报文首部:ACK=1,确认号 ack=w+1(收到的序号+1),序号 seq=u+1(服务端传过来的ack的值))
为了防止已失效的链接请求报文段忽然又传送到了服务端,于是产生错误。
在结束链接的过程当中,为何在收到服务器端的链接释放报文段以后,客户端还要继续等待2MSL以后才真正关闭TCP链接呢?
这里有两个缘由:
第一个是:须要保证服务器端收到了客户端的最后一条确认报文。假如这条报文丢失,服务器没有接收到确认报文,就会对链接释放报文进行超时重传,而此时客户端链接已关闭,没法作出响应,就形成了服务器端不停重传链接释放报文,而没法正常进入关闭状态的情况。而等待2MSL,就能够保证服务器端收到了最终确认;若服务器端没有收到,那么在2MSL以内客户端必定会收到服务器端的重传报文,此时客户端就会重传确认报文,并重置计时器。
第二个是:存在一种“已失效的链接请求报文段”,须要避免这种报文端出如今本链接中,形成异常。这种“已失效的链接请求报文段”是这么造成的:假如客户端发出了链接请求报文,然而服务器端没有收到,因而客户端进行超时重传,再一次发送了链接请求报文,并成功创建链接。然而,第一次发送的链接请求报文并无丢失,只是在某个网络结点中发生了长时间滞留,随后,这个最初发送的报文段到达服务器端,会使得服务器端误觉得客户端发出了新的请求,形成异常。
🍃 资料1:史上最容易理解的:TCP三次握手,四次挥手
🍃 资料2:TCP三次握手原理