¿Cómo funciona la función socket API accept ()?


La API de socket es el estándar de facto para las comunicaciones TCP/IP y UDP/IP (es decir, el código de red tal como lo conocemos). Sin embargo, una de sus funciones principales, accept() es un poco mágica.

Para tomar prestada una definición semi-formal:

Accept() se usa en el lado del servidor. Acepta un intento entrante recibido para crear una nueva conexión TCP desde el cliente remoto, y crea un nuevo socket asociado con el socket par de direcciones de este relación.

En otras palabras, accept devuelve un nuevo socket a través del cual el servidor puede comunicarse con el cliente recién conectado. El viejo socket (en el que accept fue llamado) permanece abierto, en el mismo puerto, escuchando nuevas conexiones.

¿Cómo funciona accept? ¿Cómo se implementa? Hay mucha confusión sobre este tema. Muchas personas afirman aceptar abre un nuevo puerto y se comunica con el cliente a través de él. Pero esto obviamente no es cierto, ya que no se abre ningún puerto nuevo. Usted en realidad puede comunicarse a través del mismo puerto con diferentes clientes, pero ¿cómo? Cuando varios hilos llaman recv en el mismo puerto, ¿cómo saben los datos a dónde ir?

Supongo que es algo similar a la dirección del cliente que está asociada con un descriptor de socket, y cada vez que los datos vienen a través de recv se enrutan al socket correcto, pero no estoy seguro.

Sería genial obtener una explicación exhaustiva del funcionamiento interno de este mecanismo.

Author: Eli Bendersky, 2009-01-28

4 answers

Su confusión radica en pensar que un socket se identifica por la IP del servidor : Puerto del servidor. Cuando en realidad, los sockets se identifican de forma única por un cuarteto de información:

Client IP : Client Port y Server IP : Server Port

Así que mientras la IP del Servidor y el Puerto del Servidor son constantes en todas las conexiones aceptadas, la información del lado del cliente es lo que le permite realizar un seguimiento de hacia dónde va todo.

Ejemplo para aclarar las cosas:

Digamos que tenemos un servidor a las 192.168.1.1: 80 y dos clientes, 10.0.0.1 y 10.0.0.2.

10.0.0.1 abre una conexión en el puerto local 1234 y se conecta al servidor. Ahora el servidor tiene un socket identificado de la siguiente manera:

10.0.0.1:1234 - 192.168.1.1:80

Ahora 10.0.0.2 abre una conexión en el puerto local 5678 y se conecta al servidor. Ahora el servidor tiene dos sockets identificados de la siguiente manera:

10.0.0.1:1234 - 192.168.1.1:80
10.0.0.2:5678 - 192.168.1.1:80

 112
Author: 17 of 26,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-19 01:31:55

Solo para añadir a la respuesta dada por el usuario" 17 de 26 "

El socket en realidad consiste en 5 tupla - (ip de origen, puerto de origen, ip de destino, puerto de destino, protocolo). Aquí el protocolo podría TCP o UDP o cualquier protocolo de capa de transporte. Este protocolo se identifica en el paquete desde el campo' protocol ' en el datagrama IP.

Por lo tanto, es posible tener diferentes aplicaciones en el servidor que se comunican con el mismo cliente en exactamente las mismas 4 tuplas pero diferentes en el campo de protocolo. Por ejemplo

Apache en el lado del servidor hablando (server1. com:880-client1: 1234 en TCP) y World of Warcraft hablando en (server1. com: 880-client1: 1234 en UDP)

Tanto el cliente como el servidor manejarán esto como campo de protocolo en el paquete IP en ambos casos es diferente incluso si todos los otros 4 campos son iguales.

 56
Author: Methos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-28 23:30:53

Lo que me confundió cuando estaba aprendiendo esto, fue que los términos socket y port sugieren que son algo físico, cuando en realidad son solo estructuras de datos que el núcleo utiliza para abstraer los detalles de la red.

Como tal, las estructuras de datos se implementan para poder mantener separadas las conexiones de diferentes clientes. En cuanto a cómo se implementan, la respuesta es a.) no importa, el propósito de la API de sockets es precisamente que la implementación no debería importar o b.) solo echa un vistazo. Aparte de los libros altamente recomendados de Stevens que proporcionan una descripción detallada de una implementación, echa un vistazo al código fuente en Linux o Solaris o uno de los BSD.

 6
Author: a2800276,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-30 11:04:43

Como dijo el otro tipo, un socket se identifica de forma única por una 4-tupla (IP del Cliente, Puerto del Cliente, IP del Servidor, Puerto del Servidor).

El proceso del servidor que se ejecuta en la IP del servidor mantiene una base de datos (lo que significa que no me importa qué tipo de tabla/lista/árbol/matriz/estructura de datos mágica utiliza) de sockets activos y escucha en el Puerto del Servidor. Cuando recibe un mensaje (a través de la pila TCP/IP del servidor), comprueba la IP y el Puerto del Cliente con la base de datos. Si se encuentran la IP del Cliente y el Puerto del Cliente en una entrada de base de datos, el mensaje se transmite a un controlador existente, de lo contrario se crea una nueva entrada de base de datos y se genera un nuevo controlador para manejar ese socket.

En los primeros días de ARPAnet, ciertos protocolos (FTP para uno) escuchaban un puerto especificado para las solicitudes de conexión, y respondían con un puerto de transferencia. Más comunicaciones para esa conexión pasarían por el puerto de transferencia. Esto se hizo para mejorar el rendimiento por paquete: las computadoras eran varios órdenes de magnitud más lentas en aquellos días.

 0
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-28 20:01:53