21

PAIRZMQ とのパターン (ノンブロッキング クライアント サーバー) 接続の実行中に Ctrl-C を押しました。後でREQ-REP(クライアントの単一サーバー接続をブロックする)パターンを実行しようとすると、Address already in useエラーが発生し続けます。netstat を実行してみましnetstat -ltnp | grep :<my port>たが、プロセスが一覧表示されません。

では、このアドレスを正確に使用しているのは誰でしょうか?

また、このようなソケット接続を適切にシャットダウンするにはどうすればよいでしょうか?

4

3 に答える 3

2

場合によっては、別の zeromq を使用するプロセスがポートを使用し続けており、netstat他のプロセスがリッスンしていることを示していないため (表示されませnetstat -lntpん)、両端で同じホスト/ポートを使用してポートで確立された接続を示しています。他のプロセスを強制終了すると、ポートが使用できるようになります。

理由 #1: 送信接続のローカル側として使用されるエフェメラル ポート (Linux では 32768-61000 など) の範囲内に zeromq リッスン ポートを設定し、サービスを接続する必要があるため、これが発生しました。同じボックスの他のサービスに。発信接続が、ボックスのリッスン ポートと同じエフェメラル ポートを取得し、突然「アドレスが既に使用されている」時間の割合。すべてのリッスン ポートをエフェメラル ポート範囲の邪魔にならないように移動しただけで、「既に使用されているアドレス」の問題はすべてなくなりました。

理由 #2: 憶測: 他の Python ネットワーク ライブラリで同様の問題に遭遇したとき、問題のプロセスは以前にサブプロセスなどを使用してリスニング プロセスから起動されており、ソケットが子プロセスにリークするという問題がありました。親プロセスがソケットを閉じずに終了した場合、ソケットは生きたままになり、子プロセスによって所有されます。子プロセスがソケットについて実際に何も知らなかったとしても、ソケットは保持されたままになるため、他のプロセスはできませんでした。これを使って。

それが問題である場合は、サブプロセスの前にソケットのフラグを調整することで修正できる可能性があります。たとえば、(unix 固有):

fd = sock.get(zmq.FD)
old_flags = fcntl.fcntl(fd, fcntl.F_GETFD)
fcntl.fcntl(fd, fcntl.F_SETFD, old_flags | fcntl.FD_CLOEXEC)

または、親プロセスでソケットをより適切に閉じる方法があるかもしれません。

于 2015-01-12T21:17:27.663 に答える