感觉不错的总结
史上最容易理解的:TCP三次握手,四次挥手
为什么要3次握手和4次挥手
如何通过Wireshark抓包深入的分析TCP 3次握手、4次挥手过程
基础知识
TCP协议的报文格式
TCP报文段的首部分为固定部分和选项部分,固定部分长20byte,而选项部分长度可变。(若整个首部长度不是4byte的整数倍的话,则需要用填充位来填充)在固定首部中,与本文密切相关的是以下几项:
- 位码即tcp标志位,有6种标示:
- SYN(synchronous建立联机)
- ACK(acknowledgement 确认)
- PSH(push传送)
- FIN(finish结束)
- RST(reset重置)
- URG(urgent紧急)
-
Sequence number(顺序号码) seq:TCP连接字节流中每一个字节都会有一个编号,而本字段的值指的是本报文段所发送数据部分第一个字节的序号。(本次发送的编号)
-
Acknowledge number(确认号码)ack:表示期望收到的下一个报文段数据部分的第一个字节的编号,编号为ack-1及以前的字节已经收到。(告知对方下次发送的编号,就是在收到的seq上+1)
TCP三次握手(建立连接)
握手是为了确保,连接双方的通信是无误的,正常应该是一次问答(SYN+ACK)两次;像下图一样,这样的话就需要四次;
但是出于优化的目的,在第一次的ACK上加入了SYN;这样就节省了一次握手的次数
电话情景剧
- Client—>Server:喂,喂,喂,听不听的见
- Server—>Client:没问题,你听的到我说话吗
- Client—>Server:O(jb)K!让我们开始愉快的聊天吧
- 吹牛大赛现在开始
TCP四次挥手(连接终止协议)
如上面所说,可以3次握手,为什么就不能3次挥手呢?
这是因为TCP连接是全双工的,因此每个方向都必须单独进行关闭。也即是说可以单独关闭一方的,保留另一方的;
如下图,第一次是关闭Client对Server的通道,第二次是关闭Server对Client的通道
(这一英语咋写呢,在线等,挺急的)
电话情景剧
- Client—>Server:我嘴巴哑了,说不了话了,但是我耳朵好使,可以听你继续BB
- Server—>Client:OK!继续我的表演~
- Server—>Client:我也说不动了,下次再聊,goobbye!
- Client—>Server:再见!(终于完事了,话费不要钱呢,不知道是谁花钱打电话呢)
- 各回各家,各找各妈
若通信双方同时请求连接或同时请求释放连接,情况如何?
这种情况虽然发生的可能性极小,但是是确实存在的,TCP也特意设计了相关机制,使得在这种情况下双方仅建立一条连接。双方同时请求连接的情况下,双方同时发出请求连接报文,并进入SYN-SENT状态;当收到对方的请求连接报文后,会再次发送请求连接报文,确认号为对方的SYN+1,并进入SYN-RCVD状态;当收到对方第二次发出的携带确认号的请求报文之后,会进入ESTAB-LISHED状态。 双方同时请求释放连接也是同样的,双方同时发出连接释放报文,并进入FIN-WAIT-1状态;在收到对方的报文之后,发送确认报文,并进入CLOSING状态;在收到对方的确认报文后,进入TIME-WAIT状态,等待2MSL之后关闭连接。需要注意的是,这个时候虽然不用再次发送确认报文并确认对方收到,双方仍需等待2MSL之后再关闭连接,是为了防止“已失效的连接请求报文段”的影响。 过程图如下:
Wireshark抓包分析
握手分析
- 第一次握手,Client端发送,[SYN] seq = x = 0,没有ack
- 第二次握手,Server端发送,[SYN,ACK ]seq = y = 0, ack = x+1 = 1(告知对方x及之前的已经收到了)
- 第三次握手,Client端发送,[ACK ]seq = x+1 = 1,ack = y+1 = 1(完成建交)
挥手分析
- 第一次挥手,Client端发送,[FIN,ACK] seq = x = 855,ack = y = 407(这两个序号的值都是传输过程的累计了)
- 第二次挥手,Server端发送,[ACK] seq = y = 407, ack = x+1 = 856(客户端向服务端连接断开)
- 第三次挥手,Server端发送,[FIN,ACK] seq = y = 407, ack = x+1 = 856(服务端向客户端准备断开)
- 第四次挥手,Client端发送,[ACK]seq = y = 856,ack = y+1 = 1(全部断开,关闭socket)