Llamadas de socket para TCP y UDP

En la capa de red, la función Socket debe especificar si es IPv4 o IPv6, y las configuraciones correspondientes son AF_INET y AF_INET6 respectivamente. Además, es necesario especificar si es TCP o UDP. El protocolo TCP se basa en flujos de datos, por lo que se establece en SOCK_STREAM, mientras que el protocolo UDP se basa en datagramas, por lo que se establece en SOCK_DGRAM.

El servidor TCP primero debe escuchar un puerto, generalmente llamando primero a la función de enlace para asignar una dirección IP y un puerto al Socket. ¿Por qué necesitamos un puerto? Debes saber que estás escribiendo una aplicación. Cuando llega un paquete de red, el kernel debe encontrar tu aplicación a través del puerto en el encabezado TCP y entregarte el paquete. ¿Por qué necesitas una dirección IP? A veces, una máquina tendrá múltiples tarjetas de red y múltiples direcciones IP. Puede elegir monitorear todas las tarjetas de red, o puede elegir monitorear una tarjeta de red. De esta manera, solo se le enviarán los paquetes enviados a esta tarjeta de red. . .

Cuando el servidor tiene la IP y el número de puerto, puede llamar a la función de escucha para escuchar. En el diagrama de estado de TCP, hay un estado de escucha. Después de llamar a esta función, el servidor ingresa a este estado y el cliente puede iniciar una conexión en este momento.

En el kernel, se mantienen dos colas para cada Socket. Una es una cola donde se ha establecido la conexión. En este momento, el protocolo de enlace de tres vías de la conexión se ha completado y está en el estado establecido; la otra es una cola donde la conexión no se ha establecido por completo. En este momento , el protocolo de enlace de tres vías no se ha completado y está en el estado syn_rcvd.

A continuación, el servidor llama a la función de aceptación y obtiene una conexión completa para su procesamiento. Si aún no está hecho, espera.

Mientras el servidor espera, el cliente puede iniciar una conexión a través de la función de conexión. Primero especifique la dirección IP y el número de puerto que se conectará en los parámetros y luego inicie el protocolo de enlace de tres vías. El kernel asignará un puerto temporal al cliente. Una vez que el protocolo de enlace sea exitoso, la aceptación del servidor devolverá otro Socket.

Hay dos Sockets de escucha y el Socket realmente utilizado para transmitir datos: uno se llama Socket de escucha y el otro se llama Socket conectado .

Una vez que la conexión se establece con éxito, ambas partes comienzan a leer y escribir datos a través de las funciones de lectura y escritura, como escribir en una secuencia de archivos.

Proceso de llamada de función de programa de socket basado en el protocolo TCP.

Es muy exacto decir que TCP Socket es un flujo de archivos. Porque Socket existe en forma de archivo en Linux. Además de esto, existen descriptores de archivos. La escritura y lectura también se realizan mediante descriptores de archivos.

En el kernel, Socket es un archivo, que corresponde a un descriptor de archivo. Cada proceso tiene una estructura de datos task_struct, que apunta a una matriz de descriptores de archivos para enumerar los descriptores de todos los archivos abiertos por este proceso. El descriptor del archivo es un número entero y es el índice de esta matriz.

UDP no tiene conexión, por lo que no es necesario un protocolo de enlace de tres vías y no es necesario llamar para escuchar y conectarse, pero la interacción UDP aún requiere IP y números de puerto, por lo que también se requiere vinculación. UDP no mantiene el estado de la conexión, por lo que no es necesario establecer un conjunto de Sockets para cada par de conexiones, sino que siempre que haya un Socket, puede comunicarse con múltiples clientes. Es precisamente porque no hay un estado de conexión que cada vez que se comunica, llama a sendto y recvfrom, y puede pasar la dirección IP y el puerto.

Número máximo de conexiones TCP = número de IP de cliente × número de puertos de cliente. Para IPv4, el número máximo de IP de cliente es 2 elevado a 32 y el número máximo de puertos de cliente es 2 elevado a 16, que es el número máximo de conexiones TCP para un solo servidor, que es aproximadamente 2 elevado a 48. fuerza.

Por supuesto, el número máximo de conexiones TCP simultáneas en el servidor está lejos de alcanzar el límite superior teórico. En primer lugar, es principalmente el límite de descriptores de archivos. De acuerdo con el principio anterior, los sockets son todos archivos, por lo que el número de descriptores de archivos debe configurarse primero a través de ulimit; el otro límite es la memoria. De acuerdo con la estructura de datos anterior, cada La conexión TCP debe ocupar una cierta cantidad de memoria. La memoria y el sistema operativo son limitados.

1. Modo multiproceso

Esto equivale a que usted sea un proxy y escuche las solicitudes entrantes. Una vez que se establece una conexión, habrá un Socket conectado. En este momento, puede crear un proceso hijo y luego transferir la interacción basada en el Socket conectado a este nuevo proceso hijo.

2. Método de subprocesos múltiples

En Linux, la creación de un hilo a través de pthread_create también llama a do_fork. La diferencia es que aunque el nuevo hilo creará un nuevo elemento en la lista de tareas, muchos recursos, como la lista de descriptores de archivos y el espacio de proceso, aún se comparten, con solo una referencia más.

Existe C10K, lo que significa que si una máquina quiere mantener 10.000 conexiones, debe crear 10.000 procesos o subprocesos y el sistema operativo no puede soportarlo. Si se necesitan 100.000 servidores para mantener a 100 millones de usuarios en línea, el costo es demasiado alto.

3. Multiplexación IO, un hilo mantiene múltiples sockets

Dado que Socket es un descriptor de archivos, todos los Sockets a los que apunta un determinado hilo se colocan en un conjunto de descriptores de archivos fd_set, que es el muro de progreso del proyecto, y luego se llama a la función de selección para monitorear si hay cambios en el conjunto de descriptores de archivos. Siempre que hay un cambio, cada descriptor de archivo se examina por turno.

4. Multiplexación de IO, desde "enviar personas para vigilar" hasta "notificar cuando sucede algo"

La función que puede lograr esto se llama epoll. Se implementa en el kernel no mediante sondeo, sino registrando una función de devolución de llamada. Cuando un descriptor de archivo cambia, se le notificará activamente.

Este método de notificación garantiza que cuando aumenten los datos de Socket monitoreados, la eficiencia no se reducirá significativamente y la cantidad de Sockets que se pueden monitorear al mismo tiempo también será muy grande. El límite superior es el número máximo de descriptores de archivos definidos por el sistema y abiertos por el proceso. Por lo tanto, se considera que epoll es una herramienta poderosa para resolver el problema del C10K.

Este artículo es una nota de estudio del día 13 de septiembre. El contenido proviene del "Protocolo de Internet" de Geek Time . Se recomienda este curso.

Supongo que te gusta

Origin blog.csdn.net/key_3_feng/article/details/132865034
Recomendado
Clasificación