S es un programa de servidor: digamos que es un servidor HTTP, por lo que utilizará el conocido número de puerto para HTTP , que es 80. Lo ejecuto en un host con la dirección IP 10.0.0.4
, por lo que escuchará las conexiones en 10.0.0.4:80
(porque ahí es donde todos esperarán encontrarlo).
Dentro de S , voy a crear un socket y enlazarlo a esa dirección: ahora, el sistema operativo sabe que las conexiones entran en 10.0.0.4:80
se debe enrutar a mi proceso S a través de ese zócalo en particular.
-
salida de netstat una vez que el socket está vinculado:
$ netstat --tcp -lan
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
NB. la dirección local es todos ceros porque a S no le importa cómo lo alcancen sus clientes
Una vez que S tenga este conector enlazado, aceptará conexiones: cada vez que un nuevo cliente se conecta, accept
devuelve un socket nuevo , que es específico para ese cliente
-
salida de netstat una vez que se acepta una conexión:
$ netstat --tcp -lan
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
tcp 0 0 10.0.0.4:80 10.0.0.5:55715 ESTABLISHED
-
10.0.0.4:80
representa el final de la conexión de S y está asociado con el socket devuelto por accept
-
10.0.0.5:55715
es el extremo de la conexión del cliente y está asociado con el socket que el cliente pasó a connect . El puerto del cliente no se usa para nada, excepto para enrutar paquetes en esta conexión TCP al proceso correcto: el kernel del cliente lo asigna de manera aleatoria desde el rango de puertos efímeros.
Ahora, S puede continuar aceptando más conexiones de clientes ... cada uno tendrá su propio socket, cada socket se asociará con una conexión TCP única, y cada conexión tendrá una única dirección remota S hará un seguimiento del estado del cliente (si lo hay) asociándolo con el socket.
Entonces, aproximadamente:
- la dirección IP es para enrutar entre hosts en la red
- el puerto es para enrutar al socket correcto en el host
- Casi dije proceso correcto , pero en realidad es posible tener múltiples procesos (generalmente secundarios) que acepten todos en el mismo socket ...
- sin embargo, cada vez que devuelve una de las llamadas simultáneas
accept
, lo hace en solo un proceso , el socket de cada conexión entrante es único para una instancia del servidor
- el socket es el objeto que utiliza un proceso para hablar con el sistema operativo acerca de una conexión en particular, como un descriptor de archivos
- como se mencionó en los comentarios, hay muchos otros usos para sockets que no usan puertos en absoluto: por ejemplo socketpair crea un par de sockets conectados que tienen un esquema de direccionamiento no en absoluto. La única forma de usar esa tubería es mediante el proceso que se llama
socketpair
, siendo un hijo de ese proceso y heredar uno, o haber pasado explícitamente uno de los sockets de ese proceso