web-dev-qa-db-ja.com

特定のポートでリッスンできるプロセスはいくつありますか?

80などの特定のポートでリッスンできるプロセスはいくつありますか?また、一部のアプリケーションの子プロセスが同じポートを使用してリッスンする方法を教えてください。ポートでの待機と待機接続の確立に違いはありますか?

7
faressoft

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であることがわかります。

与えられたエンドポイントでリッスンしているソケットがあるとすぐに、カーネルはそのエンドポイントへの着信接続の受け入れを開始します( バックログは、カーネルが受け入れていない可能性のある数に関するカーネルへのヒントですaccepted by applications )。

次に、リスニングソケット(または_SO_REUSEPORT_を使用したリスニングソケット)を指す任意のfdsでaccept()を実行する最初のプロセスが着信接続を取得します。 accept()は新しいソケットを作成し、そのsocketに新しいfdを返します。次に、そのfdを複製することができ(同じソケットを指す新しいfd)、子プロセスは、リスニングソケットと同じようにconnectedソケットを継承します。

8

この回答では、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つのプロセスだけがリッスンできます。

リスニングアプリケーションは、着信接続ごとに新しいスレッド/タスク/プロセスを開始します。

3
joepd