在学习TCP协议的时候,接触最多的就是TCP的三次握手和四次挥手。关于这个的介绍大多数都是文字和图示来分析的,但是具体到协议的内容时,有可能还是不清楚,下面我就通过具体协议来分析一下这个过程。
这里使用Wireshark网络分析工具抓取了一组数据。
192.168.0.11为modbus服务器,192.168.0.18为modbus客户端,客户端首先连接服务器,连接成功后,客户端像服务器发送读取指令,然后服务器返回一组数据,最后客户端再断开和服务器的连接。
前三笔数据为三次握手过程,最后四组数据为四次挥手过程。
三次握手的过程如下:
第一次握手:
客户端将SYN信号置1,发起一个新的连接。此时客户端会随机生成一个序号1213270320,期望下一次收到的数据序号是当前序号加1。由于还没有和服务器建立连接,所以服务器的确认序号不知道,默认发送0。此时客户端进入SYN_SEND状态,等待服务器确认。
第二次握手:
服务器收到客户端的SYN包之后,必须确认客户的SYN,也就是将客户端的上次发来的序号加1,上次客户端发来的序号是1213270320,加上1之后是1213270320=1,同时自己也发送一个SYN包,即SYN+ACK包,由于由于服务器是第一次给客户端发送数据,所以服务器也会随机生成一个序号6510,此时服务器进入SYN_RECV状态;
第三次握手:
客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK,第二次握手时服务器发来的序号为6510,所以本次向服务器确认时,需要将服务器的序号加1返回,也就是返回6510。由于连接已经建立完成,所以将SYN信号清0,将ACK信号置1。此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
其中协议中具体数据含义如下:
四次挥手的过程如下:
第一次挥手:
客户端主动关闭,发送一个FIN(同时指定一个序列号)。用来关闭客户端到服务器的数据传送,也就是客户端告诉服务器:我已经不会再给你发数据了(当然,在fin包之前发送出去的数据,如果没有收到对应的ack确认报文,客户端依然会重发这些数据),但此时客户端还可以接受数据。之后客户端进入FIN_WAIT_1状态。
第二次挥手:
服务器收到FIN包后,发送一个ACK给客户端,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号)。接着服务器进入CLOSE_WAIT(等待关闭)状态,此时的TCP处于半关闭状态,客户端到服务器的连接释放。客户端收到来自服务器的ACK应答报文段后,进入FIN_WAIT_2状态。
第三次挥手:
服务器也打算断开和客户端的连接。向客户端发送一个FIN,用来关闭服务器到主客户端数据传送,也就是告诉客户端,我的数据也发送完了,不会再给你发数据了。之后服务器进入LASK_ACK(最后确认)状态,等待客户端的确认。
第四次挥手:
客户端收到来自服务器的连接释放(FIN)报文段后,会向服务器发送一个ACK应答报文段,以连接释放(FIN)报文段的确认序号 ack 作为ACK应答报文段的序列号 seq,以连接释放(FIN)报文段的序列号 seq+1作为确认序号ack。之后客户端进入TIME_WAIT(时间等待)状态,服务器收到ACK应答报文段后,服务器就进入CLOSE(关闭)状态,到此服务器的连接已经完成关闭。客户端处于TIME_WAIT状态时,此时的TCP还未释放掉,需要等待2MSL后,客户端才进入CLOSE状态。
这样通过Wireshark软件对传输的数据详细分析,可以使我们对TCP的三次握手和四次挥手过程有一个更深的了解。