本番コードには「netstat」を使用するshスクリプトがあります。特定のポートでリッスンしているすべてのPIDを取得するには、「netstat -lntup」コマンドを使用します。コマンドをss -lntupに置き換えました。ほとんどの場合、両方のコマンドの出力は同じですが、場合によっては、ssは同じポートに対して複数のpidを返します。
# ss -lntup | grep http
tcp LISTEN 0 128 *:80 *:* users:(("httpd",pid=2355,fd=4),("httpd",pid=1962,fd=4),("httpd",pid=1961,fd=4),("httpd",pid=1960,fd=4),("httpd",pid=1955,fd=4))
tcp LISTEN 0 128 *:443 *:* users:(("httpd",pid=2355,fd=6),("httpd",pid=1962,fd=6),("httpd",pid=1961,fd=6),("httpd",pid=1960,fd=6),("httpd",pid=1955,fd=6))
このリストをどのように解釈する必要がありますか? PIDはどのように関係していますか?複数のプロセスが同時に同じPIDを受信できますか?
ありがとう
答え1
PIDはどのように関係していますか?
この場合は明らかにそうです。共通の親プロセスがあるか、プロセスの1つが別のプロセスの親です。
パブリックファイルハンドル(ポート80の場合4、ポート443の場合6)は、子プロセスを開始する前に親プロセスが「ソケット」を生成したことを示します。
複数のプロセスが同時に同じポートを受信できますか?
ポートを受信するプロセス(pid)ではなく、ポートが受信する「ソケット」です。
ソケットは、コンピュータのメモリ内のネットワーク関連オブジェクトです。
Eduardo Trápaniがすでに作成したように、SO_REUSEPORTを使用すると、複数のソケットがポートでリッスンできます。しかし、ここでは(おそらく)そうではありません。 2つのソケットのみが関連付けられているとします(ポート80に1つ、ポート443に1つ)。
プロセス(pid)がソケットを作成してから子プロセスを作成すると、そのプロセスとその子プロセスは通常、子プロセスが作成された後にソケットを共有します。
オペレーティングシステムはどのソケットがどのポートでリッスンしているかを知っていますが、ソケットは(少なくとも正式に)複数のPID間で共有されるため、実際にリッスンしているPIDを見つける方法はありません。
私は親プロセスだけが実際にソケットを使用していると仮定していますが、オペレーティングシステムはこれを知りません。
答え2
PIDはどのように関係していますか?
不要。ただし、ポートのハイジャックを防ぐには、同じ有効なユーザーIDに属している必要があります。
複数のプロセスが同時に同じPID /ポートを受信できますか?
はい、ソケットオプションSO_REUSEPORTを使用してください。このページ(Pythonの例を含む)動作とSO_REUSEADDR(サーバーでも使用)の関係を説明します。
以下はページから抜粋したものです。
SO_REUSEPORT
このオプションの動作はSO_REUSEADDRの概念と似ていますが、このオプションを使用すると、複数のTCP / UDPサーバーソケットをまったく同じIPと同じポートにバインドできます。
しかし、ソケットには1つの制限があります。 SO_REUSEADDRにない同じIPと同じポートを共有できます。 IP /ポートを共有するすべてのソケットは、同じ有効なユーザーを持つプロセスによって作成する必要があります。これはUDP / TCPプロトコルに適用できます。有効なユーザーの世話をすることなく、SO_REUSEADDRのみを使用して複数のUDPサーバーソケットをバインドできます(root open *:80で実行されたprocessAとuserAによって実行されたprocessBはSO_REUSEADDR open *:80を使用できます)。 )。ただし、SO_REUSEPORT は許可されません。この時点から、SO_REUSEPORTがより制限的であると考えることができます。