切り捨てられたメッセージを持つ Socat UDP クライアント/サーバー

切り捨てられたメッセージを持つ Socat UDP クライアント/サーバー

nodejs を使用すると、ペイロードが 50000 文字の UDP パケットを送信できます。しかし、socat (クライアントとサーバーの両方で Linux ubuntu 20.04) ではそれができません。

このテストでは、自宅のホストと職場のホストを接続する VPN を使用しました。socat でデータが失われることは予想していましたが、そこまでではありませんでした。

リモート (作業) ホストでは、socat サーバーは、50000 バイトを超える肥大化した UDP 応答を返す要求を待機します。

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.t50,000 文字ではなく約 8,000 文字になります。

nodejs udp クライアント/サーバーを使用する場合、サーバーから送信された 50,000 文字のメッセージは、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 

サーバー側では、1 つのパケットが送信されたことが保証されています。デバッグ ログで動作の違いを確認できます。

socat -b100000 -d -d -d udp4-listen:13000,reuseaddr,fork EXEC:"./sotest.sh"

答え1

socatデフォルトのバッファ サイズは 8k です。バッファ サイズはクライアント側でのみ設定します。したがって、サーバーはデフォルトの 8k バッファ サイズを使用します。パケットが 8k UDP データグラムで送信されるのはそのためです。

その後、何らかの理由で、クライアントはサーバーから送信された最初の UDP データグラムのみを読み取ります。

関連情報