我用的是 win10 下的 WSL2 环境。
下面示例基本流程是:
进入 WSL2 环境下,使用 ifconfig 查看网卡信息:
xiang@MSI:/mnt/c/Users/xiang$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.29.184.251 netmask 255.255.240.0 broadcast 172.29.191.255
inet6 fe80::215:5dff:fe5e:ed92 prefixlen 64 scopeid 0x20<link>
ether 00:15:5d:5e:ed:92 txqueuelen 1000 (Ethernet)
RX packets 2091 bytes 306842 (306.8 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 79 bytes 6426 (6.4 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 371 bytes 4049004 (4.0 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 371 bytes 4049004 (4.0 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
由于我们接下来直接在 127.0.0.1 下测试,所以我们只需要监听此 ip 下的数据即可。
sudo tcpdump -i lo # 再加上 -w filename 可以把抓包内容写到文件里;可以先不写文件,直接在命令行下查看结果
进入 WSL2 下,执行命令,启动监听 8000 端口的 tcp 服务。
nc -l 8000
打开新的 WSL2 窗口,执行命令,连接本机的 8000 端口
nc 127.0.0.1 8000
这时,我们看到 tcpdump 下有内容输出:
12:07:24.920952 IP localhost.47152 > localhost.8000: Flags [S], seq 2397915828, win 65495, options [mss 65495,sackOK,TS val 2047998107 ecr 0,nop,wscale 7], length 0
12:07:24.920972 IP localhost.8000 > localhost.47152: Flags [S.], seq 3312485390, ack 2397915829, win 65483, options [mss 65495,sackOK,TS val 2047998107 ecr 2047998107,nop,wscale 7], length 0
12:07:24.920979 IP localhost.47152 > localhost.8000: Flags [.], ack 1, win 512, options [nop,nop,TS val 2047998107 ecr 2047998107], length 0
这就是 tcp 的三次握手:
01 本机 47152 端口向 本机 8000 端口发送标志位 SYN 的数据包
02 8000 服务端发送 ACK 响应 SYN,同时也会发送 SYN
03 客户端的第三次 ack
我们在 nc 客户端下输入 hello,然后回车,这时候服务端会收到 hello,tcpdump 数据:
12:34:34.016955 IP localhost.47152 > localhost.8000: Flags [P.], seq 1:7, ack 1, win 512, options [nop,nop,TS val 2049627203 ecr 2047998107], length 6
12:34:34.017003 IP localhost.8000 > localhost.47152: Flags [.], ack 7, win 512, options [nop,nop,TS val 2049627203 ecr 2049627203], length 0
01 客户端发送 hello
02 服务端 ack
在 nc 客户端下按 ctrl + c 断开连接,tcpdump 的数据:
12:43:32.214698 IP localhost.47152 > localhost.8000: Flags [F.], seq 7, ack 1, win 512, options [nop,nop,TS val 2050165400 ecr 2049627203], length 0
12:43:32.214879 IP localhost.8000 > localhost.47152: Flags [F.], seq 1, ack 8, win 512, options [nop,nop,TS val 2050165401 ecr 2050165400], length 0
12:43:32.214949 IP localhost.47152 > localhost.8000: Flags [.], ack 2, win 512, options [nop,nop,TS val 2050165401 ecr 2050165401], length 0
只有三次挥手!所以说:tcp 断开连接 【一般】是四次挥手。这里是三次是因为 传统意义的 2、3 步骤合并了。
01 客户端主动断开,发送 FIN + ACK
02 服务端接收到后,发送 ACK(=客户端 seq+1),同时发送 FIN(因为服务端也没有数据要发送给客户端了,所以直接合并成一条了)
03 客户端 last ack
tcpdump 在命令行下输出只是简要信息,想要看整个数据包内容的话,可以先把数据包写入到文件,然后用 wireshark 分析。
使用命令监听 lo 网卡,并写入 dumpexample 文件里。
sudo tcpdump -i lo -w dumpexample
按照上述的步骤:打开监听,连接,发送 hello,断开。
然后在 dumpexample 下 ctrl+c 停止监听,得到 dumpexample 文件。
使用 wireshark 打开文件。
这里能够看到每个请求的非常详细的信息,包括 数据链路层头部、网络层头部,以及完整的 tcp 层头部。
比如,这次三次握手的 标志位的变化:
这是三次挥手的 标志位的变化:
这是发送了 hello 数据的那一条消息:
使用 netcat tcpdump wireshark 可以很方便的 构造 TCP 请求、监听 分析 TCP 报文。(netcat -u 还可以指定 UDP socket)
通过真实的 TCP 报文可以真切的感受到 TCP 的整个工作细节。
上述只是一个简单的例子,TCP 的很多技术点也都没有涉及到,比如:
纸上得来终觉浅,绝知此事要躬行。尝试以下吧。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。