套接字连接功能使用4次握手?

socket connect function use 4 handshake?

我启动一个监听 9877 的服务器 然后我尝试在同一台机器上连接此服务器

但连接时 来回拍了4次,糊涂

kernel version Darwin sifang.local 19.6.0 Darwin Kernel Version 19.6.0: Mon Aug 31 22:12:52 PDT 2020; root:xnu-6153.141.2~1/RELEASE_X86_64 x86_64


machine :macbook pro  2020 

listening on lo0, link-type NULL (BSD loopback), capture size 262144 bytes
12:57:42.981579 IP localhost.51188 > localhost.9877: Flags [S], seq 4266424528, win 65535, options [mss 16344,nop,wscale 6,nop,nop,TS val 2395708763 ecr 0,sackOK,eol], length 0
12:57:42.981647 IP localhost.9877 > localhost.51188: Flags [S.], seq 3797230557, ack 4266424529, win 65535, options [mss 16344,nop,wscale 6,nop,nop,TS val 2395708763 ecr 2395708763,sackOK,eol], length 0
12:57:42.981656 IP localhost.51188 > localhost.9877: Flags [.], ack 1, win 6379, options [nop,nop,TS val 2395708763 ecr 2395708763], length 0
12:57:42.981661 IP localhost.9877 > localhost.51188: Flags [.], ack 1, win 6379, options [nop,nop,TS val 2395708763 ecr 2395708763], length 0

您的 tcpdump 输出的前 3 行是 3 次握手。

第四行只是服务器出于某种原因发出了ACK。注意第一行是51188端口到9877端口(client到server SYN),而第二行是9877端口到51188端口(server到client SYN+ACK),第三行是51188端口到9877端口( client to server ACK, ending the 3-way handshake), 第四行是9877端口到51188端口(server to client, not client to server ACK的copy)。

Ubuntu 服务器不会发生这种情况;这可能是 macOS 和 Linux TCP 实现之间的差异,或者是正在使用的 SSH 守护程序中的差异。

我通过 运行 tcpdump 在 Linux 机器上远程登录到 Mac 上的端口 22(因此不涉及环回设备)确定了这一点;出现了相同的四个数据包(3 次握手和额外的 ACK)。

(不,在所有操作系统上捕获流量时,在环回接口上发送的数据包不会被看到两次。如果您在 Linux 上捕获流量,它们会被看到两次,但 libpcap 会过滤掉其数据包读取代码中的传出副本。它们 not 在 macOS 或其他 BSD-flavored 操作系统上出现过两次。

Linux和macOS/*BSD的捕获机制不同:

  • Linux 使用 PF_PACKET 套接字,它在环回接口上传送数据包的传入和传出副本,但它们看起来相同,具有相同的源端口和目标端口,因此 如果 libpcap 没有丢弃传出副本,你会看到两个相同的数据包,但 libpcap 丢弃传出副本,所以你只能看到一个;
  • macOS/*BSD/Solaris11/AIX 使用 BPF 设备,它只在环回接口上传送一个数据包副本,因此没有副本可以丢弃。)