この質問は、 「ネットワーク ポートが開いていますが、プロセスが接続されていませんか?」に似ています。netstat は pid のないリッスン ポートを表示しますが、lsof は表示しません。しかし、それらへの答えは私のものを解決することはできません。
lps
ポート 8588 で tcp 接続を待機するというサーバー アプリケーションがあります。
[root@centos63 lcms]# netstat -lnp | grep 8588
tcp 0 0 0.0.0.0:8588 0.0.0.0:* LISTEN 6971/lps
ご覧のとおり、リッスン ソケットに問題はありませんが、2000、3000、または 4000 の数千のテスト クライアント (別の同僚によって作成された) をサーバーに接続すると、常に 5 つのクライアントがありました (これもランダム) に接続してログイン要求をサーバーに送信しますが、応答を受信できません。例として 3000 クライアントを取り上げます。これはnetstat
コマンドが与えるものです:
[root@centos63 lcms]# netstat -nap | grep 8588 | grep ES | wc -l
3000
そして、これはlsof
コマンド出力です:
[root@centos63 lcms]# lsof -i:8588 | grep ES | wc -l
2995
その 5 つの接続がここにあります。
[root@centos63 lcms]# netstat -nap | grep 8588 | grep -v 'lps'
tcp 92660 0 192.168.0.235:8588 192.168.0.241:52658 ESTABLISHED -
tcp 92660 0 192.168.0.235:8588 192.168.0.241:52692 ESTABLISHED -
tcp 92660 0 192.168.0.235:8588 192.168.0.241:52719 ESTABLISHED -
tcp 92660 0 192.168.0.235:8588 192.168.0.241:52721 ESTABLISHED -
tcp 92660 0 192.168.0.235:8588 192.168.0.241:52705 ESTABLISHED -
上記の 5 は、ポート 8588 でサーバーに接続されているが、プログラムが接続されていないことを示しています。2 番目の列 ( RECV-Q
) は、クライアントが要求を送信するにつれて増加し続けます。
上記のリンクは、NFS マウントと RPC について述べています。RPCに関しては、コマンドを使用しましたrcpinfo -p
が、結果はポート8588とは何の関係もありません。そして、NFSマウント、nfssta
出力は言うError: No Client Stats (/proc/net/rpc/nfs: No such file or directory).
質問 : これはどのように起こりますか? 常に 5 であり、同じ 5 クライアントからではありません。他のクライアントも同じサーバーIPとポートに接続されており、それらはすべてサーバーによって適切に処理されるため、ポートの競合ではないと思います。
注:epoll
クライアントの要求を受け入れるために Linux を使用しています。accept
また、プログラムにデバッグ コードを記述し、返されたが 5 つの接続が見つからないすべてのソケットを (クライアントの情報と共に) 記録します。これはuname -a
出力です:
Linux centos63 2.6.32-279.el6.x86_64 #1 SMP Fri Jun 22 12:19:21 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
ご親切にありがとうございました! 私は本当に混乱しています。
2013 年 6 月 8 日更新: システムを CentOS 6.4 にアップグレードした後、同じ問題が発生します。最後に に戻ったところlisten fd をノンブロッキングに設定し、エラーが返るまでと書かれているページepoll
を見つけましそして、はい、それは動作します。保留中の接続はこれ以上ありません。しかし、それはなぜですか?Unix Network Programming Volume 1は言うaccept
EAGAIN
EWOULDBLOCK
accept is called by a TCP server to return the next completed connection from the
front of the completed connection queue. If the completed connection queue is empty,
the process is put to sleep (assuming the default of a blocking socket).
では、完了した接続がまだキューにある場合、プロセスがスリープ状態になるのはなぜでしょうか?
更新2013-7-1: リッスン ソケットを追加するときに使用遭遇するEPOLLET
まで受け入れを維持しないと、すべてを受け入れることができませんEAGAIN
私はちょうどこの問題に気づきました。私のせいです。覚えておいてください:ソケットをリッスンしている場合でも、alwaysread
またはaccept
untilEAGAIN
が出てきEPOLLET
テスト プログラムで私を証明してくれた Matthew に再び感謝します。