小さなファイル (約 100 KB) を送信するために、TCP を使用するシンプルな socat ファイルサーバーをセットアップしようとしています。
以下は、1 つのファイルに対する 1 行のサーバーとクライアントです。
サーバ:socat -u -d -d OPEN:file.dat TCP-LISTEN:<port>,reuseaddr,fork
クライアント:socat -u -d -d TCP:<server>:<port> OPEN:file.dat,creat
最初のデータ転送は常に機能しますが、その後は必ずしも機能するとは限りません。その後の転送のほとんどは、クライアント側に空のファイルを作成します。複数のクライアントが一度転送すると問題は解決せず、バグが発生したときにデータが転送されないことを確認しましたが、ログと戻り値はエラーを示しておらず、データ ループが短くなっているだけです。
ここで言及されているほぼすべてのオプションを試しました:http://www.dest-unreach.org/socat/doc/socat.html
これを複数回連続して動作させる唯一の方法は、サーバー リスナーから fork オプションを削除し、コマンド ライン全体を bash ループでラップすることですが、もちろん複数のクライアントでは失敗します。
Ubuntu、Fedora、Redhat、FreeBSD で試しました。
何か見落としているのでしょうか、それともバグでしょうか?
答え1
私も同じ問題を抱えていて、何が間違っているのか理解するのに何時間もかかりました。まだよく分かりませんが、少なくとも動作させる方法はわかっています。私は以下を使用していました:
socat -u FILE:/tmp/test.txt TCP-LISTEN:5778,reuseaddr,fork
そして、次のように切り替えると期待どおりに動作しました:
socat TCP-LISTEN:5778,reuseaddr,fork FILE:/tmp/test.txt
実際に何が変わるのかは分かりませんが、-u
フラグを削除してアドレスの順序を入れ替えると、複数のクライアント呼び出し用のソケットが開きます。複製しようとしたときに偶然見つけました。サーバーの既知の動作例。
また、私のクライアントは単純に でしたsocat -u TCP:localhost:5778 STDOUT
。 がなくても動作します-u
。
答え2
男 男
$ man socat | grep -m1 '\-u' -A3
-u Uses unidirectional mode. The first address is only used for
reading, and the second address is only used for writing (exam-
ple).
ただ助けるだけでも
$ socat -h | grep -m1 '\-u '
...
答え3
これは、サーバー上に 1 つのファイル ソースと複数のファイル シンク (TCP 接続、分岐) があるためです。最初のクライアントはすべてのファイルを消費し、ファイルの位置を EOF (ファイルの終わり) に残します。後続の TCP クライアントはすべて同じファイル ソースを使用しているため、読み取るものがありません。
これはバグというよりは、socat の設計上の側面です。新しい接続でソース ファイルのシーク位置をリセットする方法はわかりません。