特定のポート(たとえば、80)でいくつのプロセスがリッスンできますか?同じポートでリッスンするアプリケーションのサブプロセスをどのように持つことができますか?ポートからのリスニングとリスニング接続の確立に違いはありますか?
答え1
Q:特定のポートでいくつのプロセスがリッスンできますか?
回答:できるだけ多く作成してください。
SOCK_STREAM
ただし、少なくともソケットの場合、このSO_REUSEPORT
オプション(Linux 3.9の新機能)を使用しないと、プロセスはソケットをローカルエンドポイント(TCPアドレス+ポート、Unixのファイル名...)(または次の受信ポート)にバインドできますありません。そのポートのワイルドカードアドレス)。
したがって、SO_REUSEPORTを使用しない限り、同じポートで別のプロセスをリッスンする唯一の方法は、そのファイル記述子が同じポートを指すようにすることです。ファイル説明を開く(同じソケットに)。
fork()
これはプロセスを作成すると自動的に発生します。 fd 3がワイルドカードアドレスとポート12345の着信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ドメインソケットを使用するプロセス間。
listen()
パラメータの1つは次のとおりです。バックログ。
与えられたエンドポイントでリッスンするソケットがある場合、カーネルはそのエンドポイントへの着信接続を受け入れ始めます(accept
バックログは、アプリケーションがまだ編集していない内容をカーネルがどれだけ受け入れられるかを示すヒントです。)。
accept()
次に、リスニングソケット(またはそれを持つリスニングソケット)を指すfdで動作する最初のプロセスが着信接続を取得SO_REUSEPORT
します。accept()
新しいソケットを作成し、ソケットに新しいfdを返しますsocket
。これにより、fdがコピーされ(新しいfdが同じソケットを指す)、子プロセスはfdを継承します。接続済みまるでリスナーにやっているかのように。
答え2
この回答では、IPv4 経由の TCP について説明します。
1つのプロセスのみ可能聞く新しい接続のため。複数のプロセスが同じポートを要求しようとすると、「すでに使用されているアドレス」エラーが発生します。
これは、そのポートを積極的に使用するプロセスの数とはまったく異なります。
次の出力を見てください。
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-tupleです(remote-ip, remote-port, local-ip, local-port)
。(remote-ip, remote-port)
LISTENING状態なので、1つ*:*
のプロセスしかListenできません。
受信アプリケーションは、着信接続ごとに新しいスレッド/タスク/プロセスを開始します。