tcp三次握手和四次揮手的描述不少,可是感受大部分文章看下來很難具象化這個過程,下面使用這個wireshark抓包工具,經過抓取到的數據包來理解一下,可以從另外一個角度理解tcp三次握手了html
完整案例代碼已上傳github: github.com/neatlife/my…java
wireshark下載地址:www.wireshark.org/download.ht…git
能夠在idea中建立一個maven項目,建立用來測試3次握手和4次揮手的兩個模塊,建立模塊在idea右鍵菜單裏就有: github
把握手和揮手分開測試是爲了防止客戶端在發送過程當中,服務端就提早關閉了,而後揮手的部分包可能會丟掉,這個丟包的效果能夠自行嘗試shell
創建一個socket服務器,並在8881端口上監聽,核心代碼以下:編程
ServerSocket socket = new ServerSocket(8881);
socket.accept();
TimeUnit.SECONDS.sleep(2);
socket.close();
複製代碼
鏈接上面的服務器,併發送幾回數據,每次發送幾個字節的數據,核心代碼以下:服務器
Socket socket = new Socket("127.0.0.1", 8881);
OutputStream outputStream = socket.getOutputStream();
outputStream.write("111".getBytes());
outputStream.write("1111l".getBytes());
outputStream.write("11111l111l".getBytes());
socket.close();
複製代碼
核心代碼以下:微信
ServerSocket serverSocket = new ServerSocket(8881);
Socket socket = serverSocket.accept();
socket.close();
serverSocket.close();
複製代碼
核心代碼以下:併發
Socket socket = new Socket("127.0.0.1", 8881);
socket.close();
TimeUnit.SECONDS.sleep(Integer.MAX_VALUE);
複製代碼
wireshark抓的包已經上傳到github,能夠直接使用wireshark打開案例項目裏的握手包:handshake.pcapng,和揮手包:wave.pcapngsocket
捕獲過濾器以下:
host 127.0.0.1 and port 8881
複製代碼
填寫到wireshark中:
啓動抓包
運行握手模塊的服務端和客戶端,查看wireshark抓到的包
注意上面這個[TCP Window Update]包能夠忽略,這個包是服務端用來控制客戶端發送包的頻率的,這個包不必定會有,具體能夠參考TCP傳輸協議抓包經驗
預備知識: 要看懂上面wireshark抓的包,下面的這個指令須要提早了解下
標誌位 | 做用 |
---|---|
SYN | 表示請求創建鏈接 |
FIN | 表示請求斷開鏈接 |
Seq | 表示曾經發送過數據的字節數+1,0表示以前沒有發送過數據 |
Len | 本次收到的數據字節大小,0表示本次沒有收到數據 |
ACK | 表示對對方過來的請求的確認 |
Ack | 表示期待下次對方發送過來的Seq指令的值 |
注意:
經微信讀者「R.飛」指正,4次揮手過程當中是能夠傳數據的(未驗證,有興趣的讀者能夠自行驗證)
經微信讀者「ヤキモチ」指正,3次握手過程當中的第三次握手也能夠傳數據的(未驗證,有興趣的讀者能夠自行驗證)
握手過程當中沒有隻有指令交互,沒有數據交互,因此開始的Len=0的全部交互都屬於握手,效果以下
經過這個圖,能夠得出如下結論
握手過程當中沒有隻有指令交互,沒有數據交互,經過這個特性,從後往前數,找到全部Len=0的包便可,能夠看到,只有4個這樣的包
即便這是個簡單的分析也參考了一些資料
ACK和Ack做用是不一樣的,ACK表示確認收到了數據,Ack表示下一次發過來的數據的序號
若是idea沒法識別子模塊中的java文件,可能須要從新import下模塊的pom.xml
若是在操做過程當中遇到問題,可加做者微信探討