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
若是在操做过程当中遇到问题,可加做者微信探讨