TCP/IP协议三次握手和四次挥手之抓包详解

1、TCP/IP: 传输控制协议/网际协议

它是互联网的核心技术,并不是某一个协议而且协议的一个集合T![ (1)源端口和目的端口:各占16bit,端口是传输层与应用层的服务端口。
TCP/IP协议三次握手和四次挥手之抓包详解
以HTTP为例,从下往上走分 物理链路层(802.3,802.11,eth)-IP网络层 -传输层(TCP/UDP)-应用层( HTTPFTP TELNET TFTP)
TCP/IP协议三次握手和四次挥手之抓包详解TCP头20字节:
(1)源端口和目的端口:各占16bit,端口是传输层与应用层的服务端口。
(2)序号字段:seq序号(小写),占32bit。TCP连接中传送的数据流中的每个字节都编上一个序号。序号字段值指的是本报文段所发送的数据的第一个字节的序号。
(3)确认号:ack序号(小写),占32bit。 是期望收到对方的下一个报文段的数据的第一个字节的序号。只有ACK标志位为1时,确认号字段才有效,ACK=SEQ+1.
(4) 标志位(大写): 共六个,即URG、ACK、PSH、RST、SYN、FIN。
a、紧急比特URG:当URG=1时,表明紧急指针字段有效。它告诉系统 此报文段中有紧急数据, 应尽快传送。
b、确认比特ACK:只有当ACK=1时确认号字段才有效,等于零时无效。
c、推送比特PSH:接收TCP收到推送比特 置1的报文段,就尽快交付给接受应用进程,而不用等到整个缓存都填满了后再向上交付。
d、复位比特RST:当RST=1时,表明TCP连接中出现严重差错(如由于主机崩溃或其他原因),必须释放连接, 然后再重新连接。
e、同步比特SYN:SYN为1时,表示 这是一个连接请求或连接接受报文。
f、 终止比特FIN:用来释放一个连接。当FIN=1时,表明此报文段的发送端的数据已发送完毕,并要求释放运输连接。
(5) 数据偏移:占4bit,它指出TCP 报文段的数据的起始处 距离TCP报文段的起始处有多远。
(6) 窗口字段:占16bit,窗口字段用来控制对方发送的数据量,单位 为字节。
(7)检验和:占16bit,检验和字段检验的范围 包括首部和数据两部分。在计算检验和 时,要在TCP报文段的前面加上12字节的伪首部。
(8)紧急指针字段:占16bit,紧急指针指出在本报文段中的紧急数据的最后一个字节的序号。
(9)选项字段:长度可变,TCP只规定一种选项,即最大 报文段长度MSS(Maxinum Segment Size)。
(10)保留字段:占6bit,目前应置为0。

二、TCP建立连接时有三次握手,断开连接时候为四次分手

三次握手:

网络上很多的解释三次握手有很多解释错误的,这里我使用抓包工具,让大家看着报文来说明这个过程
先上图:
TCP/IP协议三次握手和四次挥手之抓包详解
注:理解三次握手的过程首先要理解上文中TCP报文段头部格式的几个名词
文字过程:

第一次握手:

首先客户端和服务器都是出于关闭状态(CLOSE),客户端A首先发起连接给B服务器,A会将请求报文中的标志位(大写)SYN=1 ACK =0(ACK缺省0),随机生成一个***(小写)seq = x(通常在建立连接时候为0,如下图),服务端recv到报文识别SYN=1,得知这是一个TCP连接请求数据报文(需要在内核申请fd,开辟空间),序号seq=x,表示传输数据时的第一个数据字节的序号是x(TCP是有序传输);
客户端A进入:SYN_SENT状态
TCP/IP协议三次握手和四次挥手之抓包详解有兴趣的朋友可以使用我方法也试一试,过滤设置为:tcp.flag
第一行就是A----->B请求报文,通常第一个***seq=0,即X为0;
SYN 占1bit位 Set 为1

第二次握手:

服务器B端收到请求报文,回复收到确认包,SYN=1,ACK=1(表示这是一个TCP连接响应数据报文),ack=seq+1,seq=y(同时包含主机B的初始***seq(B)=y,以及主机B对主机A初始***的确认号ack(B)=seq(A)+1=x+1,表示我下一个要收到的报文是x+1)
服务端B进入SYN_RCVD状态;
TCP/IP协议三次握手和四次挥手之抓包详解

第三次握手

主机A要收主机B的确认报文,检查ack是否为x+1,ACK是否为1,如果正确在给服务端发送一个***seq(A)=x+1和确认号为ack(A)=y+1的报文 (ack(A)=y+1 表示下一个报文需要收到这个***的包);
A和B都进入ESTABLISED状态
TCP/IP协议三次握手和四次挥手之抓包详解

四次挥手:

TCP/IP协议三次握手和四次挥手之抓包详解
四次挥手是可以两端任意发起的,因为TCP是全双工通信的,以客户端发起为例

第一次挥手

Client发送一个FIN = 1,序号seq=u,主动发起并停止再发送数据 ,关闭Client到Server的数据传送,等待B端的确认;
Client进入FIN_WAIT_1状态;

第二次挥手

B收到连接释放报文段后即发出确认报文段,(ACK=1,确认号ack=u+1,序号seq=v),B进入CLOSE-WAIT(关闭等待)状态,此时的TCP处于半关闭状态,A到B的连接释放,但是B到A还未释放;

第三次挥手

A收到B的确认后,进入FIN-WAIT-2(终止等待2)状态,等待B发出的连接释放报文段 FIN = 1 Seq=w, ACK=1 ack=u+1。

第四次挥手

A收到B的连接释放报文段后,对此发出确认报文段(ACK=1,seq=u+1,ack=w+1),A进入TIME-WAIT(时间等待)状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,A才进入CLOSED状态。

总结四次挥手过程:

起初A和B处于ESTABLISHED状态——A发出连接释放报文段并处于FIN-WAIT-1状态——B发出确认报文段且进入CLOSE-WAIT状态——A收到确认后,进入FIN-WAIT-2状态,等待B的连接释放报文段——B没有要向A发出的数据,B发出连接释放报文段且进入LAST-ACK状态——A发出确认报文段且进入TIME-WAIT状态——B收到确认报文段后进入CLOSED状态——A经过等待计时器时间2MSL后,进入CLOSED状态。
TCP/IP协议三次握手和四次挥手之抓包详解【问题】为什么连接的时候是三次握手,关闭的时候却是四次握手?
答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。
【问题2】为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。

TCP协议能够实现报文的拥塞控制和流量控制

下期总结