80などの特定のポートでリッスンできるプロセスはいくつありますか?また、一部のアプリケーションの子プロセスが同じポートを使用してリッスンする方法を教えてください。ポートでの待機と待機接続の確立に違いはありますか?
Q:特定のポートでリッスンできるプロセスはいくつですか?
A:スポーンできる数だけ。
ただし、少なくとも_SOCK_STREAM
_ソケットの場合、および_SO_REUSEPORT
_オプション(Linux 3.9の新機能)を使用しない限り、プロセスはソケットをローカルエンドポイント(TCPのアドレス+ポート、UNIXのファイル名)にバインドできません。 ..)すでに別のソケットがバインドされている場合(またはワイルドカードアドレスを使用してそのポートでリッスンしているソケット)。
したがって、SO_REUSEPORTを使用しない限り、異なるプロセスが同じポートでリッスンする唯一の方法は、対応するファイル記述子が同じオープンファイルの説明を指す(同じソケットへ)ことです。 。
これは、プロセスをfork()
すると自動的に行われます。 fd 3がリスニングTCPソケットを指している場合、フォーク後の両方のプロセスはそのfdのそのポートでリッスンします(以下のzsh
構文)) :
_$ zmodload zsh/net/tcp
$ ztcp -ld 3 12345
$ sleep 10 &
$ lsof -ni tcp:12345
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
zsh 26277 stephane 3u IPv4 506354 0t0 TCP *:12345 (LISTEN)
sleep 26988 stephane 3u IPv4 506354 0t0 TCP *:12345 (LISTEN)
_
関連のないプロセスの場合、プロセスがそのリスニングソケットにアクセスするための(私が知っている)唯一の方法は、 _SCM_RIGHT
_メカニズム を使用してfdsを渡すことです(実際にはよりUNIXドメインソケットを使用するプロセス間でopen file description)。
listen()
の引数の1つがbacklogであることがわかります。
与えられたエンドポイントでリッスンしているソケットがあるとすぐに、カーネルはそのエンドポイントへの着信接続の受け入れを開始します( バックログは、カーネルが受け入れていない可能性のある数に関するカーネルへのヒントですaccept
ed by applications )。
次に、リスニングソケット(または_SO_REUSEPORT
_を使用したリスニングソケット)を指す任意のfdsでaccept()
を実行する最初のプロセスが着信接続を取得します。 accept()
は新しいソケットを作成し、そのsocket
に新しいfdを返します。次に、そのfdを複製することができ(同じソケットを指す新しいfd)、子プロセスは、リスニングソケットと同じようにconnectedソケットを継承します。
この回答では、IPv4でのTCPについて説明します。
1つのプロセスのみが新しい接続に対してlistenを実行できます。複数のプロセスが同じポートを要求しようとすると、「アドレスはすでに使用されています」というエラーが表示されます。
これは、そのポートをアクティブに使用しているプロセスの数とはまったく異なります。
次の出力を見てください。
remote local state
*:* - 4.3.2.1:5000 LISTENING
1.2.3.4:12345 - 4.3.2.1:5000 CONNECTED
4.5.6.7:83247 - 4.3.2.1:5000 CONNECTED
一意である必要があるのは、4タプル(remote-ip, remote-port, local-ip, local-port)
。 (remote-ip, remote-port)
リスニング状態の*:*
、1つのプロセスだけがリッスンできます。
リスニングアプリケーションは、着信接続ごとに新しいスレッド/タスク/プロセスを開始します。