使用 nodejs 我可以传输负载为 50000 个字符的 udp 数据包。但是我没有使用 socat(客户端和服务器上的 Linux ubuntu 20.04)这样做。
对于此测试,我一直在使用 vpn 将我的家庭主机连接到我的工作主机。我有点期待 socat 会丢失一些数据,但没有到那种程度!
在远程(工作)主机上,socat 服务器等待请求发回膨胀的 udp 响应 > 50000 字节。
cat <<EOF > sotest.sh
#!/bin/bash
head -c 50000 < /dev/zero | tr '\0' 'q'
EOF
chmod +x sotest.sh
socat udp4-listen:13000,reuseaddr,fork EXEC:"./sotest.sh" # server
#client
printf "trigger" |socat -T 5 -,ignoreeof udp4:10.50.1.184:13000,sndbuf=64000,rcvbuf=64000 > t.t
并检查消息大小wc -c t.t
给我大约 8k 个字符而不是 50k。
如果我使用我的 nodejs udp 客户端/服务器,则服务器发送的 50k 字符消息将由 nodejs 客户端完整接收。客户端:https ://jsfiddle.net/xtcpL63a/ 服务器:https ://jsfiddle.net/851fc7bp/
我唯一的线索是 socat 的错误消息,只能在调试模式下看到
022/12/03 22:37:40 socat[1051733] N forked off child process 1051734
2022/12/03 22:37:40 socat[1051733] N forked off child process 1051734
2022/12/03 22:37:40 socat[1051733] I close(7)
2022/12/03 22:37:40 socat[1051733] I resolved and opened all sock addresses
2022/12/03 22:37:40 socat[1051733] N starting data transfer loop with FDs [5,5] and [6,6]
2022/12/03 22:37:40 socat[1051733] I transferred 73 bytes from 5 to 6
2022/12/03 22:37:40 socat[1051734] I just born: child process 1051734
2022/12/03 22:37:40 socat[1051734] I close(4)
2022/12/03 22:37:40 socat[1051734] I close(3)
2022/12/03 22:37:40 socat[1051734] I close(6)
2022/12/03 22:37:40 socat[1051734] I dup2(7, 0) -> 0
2022/12/03 22:37:40 socat[1051734] I dup2(7, 1) -> 1
2022/12/03 22:37:40 socat[1051734] I close(7)
2022/12/03 22:37:40 socat[1051734] N execvp'ing "./sotest.sh"
2022/12/03 22:37:40 socat[1051733] I transferred 8192 bytes from 6 to 5
2022/12/03 22:37:40 socat[1051733] I transferred 8192 bytes from 6 to 5
2022/12/03 22:37:40 socat[1051733] I transferred 8192 bytes from 6 to 5
2022/12/03 22:37:40 socat[1051733] I transferred 8192 bytes from 6 to 5
2022/12/03 22:37:40 socat[1051733] I transferred 8192 bytes from 6 to 5
2022/12/03 22:37:40 socat[1051733] I transferred 8192 bytes from 6 to 5
2022/12/03 22:37:40 socat[1051733] I transferred 848 bytes from 6 to 5
2022/12/03 22:37:40 socat[1051733] E read(5, 0x5566b4417150, 8192): Connection refused
2022/12/03 22:37:40 socat[1051733] N exit(1)
2022/12/03 22:37:40 socat[1051733] I shutdown(5, 2)
2022/12/03 22:37:40 socat[1051733] I shutdown(6, 2)
这个问题在 Linux 方面不能与缓冲区相关,也不能与 mtu 相关。那么 socat 发生了什么?
解决方案:Tero Kilkanen 指出了这个问题。强制 socat 在客户端使用更大的缓冲区使我能够完整地接收消息;它解决了但并没有真正解释这种行为......
#client
printf "${MSG}" |socat -b100000 -T 5 -,ignoreeof udp4:10.50.1.184:13000,sndbuf=64000,rcvbuf=64000 > t.t
在服务器端,它确保发送一个数据包;您可以在调试日志中看到行为差异:
socat -b100000 -d -d -d udp4-listen:13000,reuseaddr,fork EXEC:"./sotest.sh"