F: Wie viele Prozesse können einen bestimmten Port überwachen?
A: so viele wie du spawnen kannst.
SOCK_STREAM
Zumindest für Sockets und sofern Sie nicht die SO_REUSEPORT
Option (neu in Linux 3.9) verwenden, kann ein Prozess einen Socket nicht an einen lokalen Endpunkt binden (Adresse + Port für TCP, Dateiname für Unix ...), wenn bereits ein anderer Socket gebunden ist das (oder ein lauschender an diesem Port mit der Platzhalteradresse).
Wenn Sie SO_REUSEPORT nicht verwenden, können verschiedene Prozesse denselben Port nur abhören, indem die entsprechenden Dateideskriptoren auf dieselbe geöffnete Dateibeschreibung (auf denselben Socket) verweisen .
Das passiert automatisch, wenn Sie fork()
einen Prozess durchführen. Wenn fd 3 auf einen empfangenden TCP-Socket an der Platzhalteradresse und an Port 12345 zeigt, lauschen beide Prozesse nach dem Fork an diesem Port an diesem fd ( zsh
Syntax unten):
$ 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)
Für Prozesse, die nicht miteinander verbunden sind, besteht die einzige Möglichkeit (die ich kenne), dass ein Prozess Zugriff auf diesen Listening-Socket erhält, darin, den SCM_RIGHT
Mechanismus zu verwenden, um fds (eigentlich eher wie offene Dateibeschreibungen ) zwischen Prozessen mit Unix-Domain-Sockets zu übergeben.
Sie werden feststellen, dass ein Argument für listen()
das Backlog ist .
Sobald ein Socket auf einem bestimmten Endpunkt lauscht, akzeptiert der Kernel eingehende Verbindungen zu diesem Endpunkt ( das Backlog gibt dem Kernel einen Hinweis darauf, wie viele möglicherweise akzeptiert werden, die nicht accept
von Anwendungen bearbeitet wurden ).
Dann erhält der erste Prozess, der eine accept()
der fds ausführt, die auf den Listening-Socket (oder einen der Listening-Sockets mit SO_REUSEPORT
) zeigen, die eingehende Verbindung. accept()
erstellt einen neuen Socket und gibt einen neuen fd zurück socket
. Dieser fd kann wiederum dupliziert werden (ein neuer fd zeigt auf denselben Socket), und untergeordnete Prozesse erben diesen verbundenen Socket wie den abhörenden.
*
) und sich daran erinnern, dass IPv4 und IPv6 separate Stapel sind.