GNU/Linux >> Tutoriales Linux >  >> Linux

Linux, sockets, conexión sin bloqueo

Debe seguir los siguientes pasos para una conexión asíncrona:

  • crear socket con socket(..., SOCK_NONBLOCK, ...)
  • iniciar conexión con connect(fd, ...)
  • si el valor devuelto no es 0 ni EINPROGRESS , luego cancelar con error
  • espera hasta fd se señala como listo para la salida
  • verifique el estado del socket con getsockopt(fd, SOL_SOCKET, SO_ERROR, ...)
  • hecho

Sin bucles, a menos que desee manejar EINTR .

Si el cliente se inicia primero, debería ver el error ECONNREFUSED en el último paso. Si esto sucede, cierre el zócalo y comience desde el principio.

Es difícil saber qué está mal con su código, sin ver más detalles. Supongo que no abortas por errores en tu check_socket operación.


Hay algunas formas de probar si una conexión sin bloqueo tiene éxito.

  1. llame primero a getpeername(), si falló con el error ENOTCONN, la conexión falló. luego llame a getsockopt con SO_ERROR para obtener el error pendiente en el socket
  2. llamar a read con una longitud de 0. si la lectura falló, la conexión falló y el errno para read indica por qué falló la conexión; read devuelve 0 si la conexión tiene éxito
  3. llamar a conectar de nuevo; si el errno es EISCONN, la conexión ya está conectada y la primera conexión se realizó correctamente.

Ref:Programación en Red UNIX V1


D. J. Bernstein reunió varios métodos para verificar si un connect() asíncrono llamada exitosa o no. Muchos de estos métodos tienen inconvenientes en ciertos sistemas, por lo que escribir código portátil para eso es inesperadamente difícil. Si alguien quiere leer todos los métodos posibles y sus inconvenientes, consulte este documento.

Para aquellos que solo quieren la versión tl;dr, la forma más portátil es la siguiente:

Una vez que el sistema señale el socket como escribible, primero llame a getpeername() para ver si se conecta o no. Si esa llamada tuvo éxito, el enchufe se conectó y puede comenzar a usarlo. Si esa llamada falla con ENOTCONN , la conexión falló. Para averiguar por qué falló, intente leer un byte del socket read(fd, &ch, 1) , que también fallará, pero el error que obtiene es el error que habría obtenido de connect() si no fuera sin bloqueo.


Linux
  1. La llamada al sistema Linux más rápida

  2. Conéctese a Linux por nombre en lugar de IP

  3. ¿Administrador de conexión CLI de Linux?

  4. Cómo hacer sockets con nombre de Linux

  5. Fork vs Clone en 2.6 Kernel Linux

Cómo conectarse a un escritorio remoto desde Linux

Cómo conectarse a través de Bluetooth en GNOME en Linux

Cómo conectar iPhone a Arch Linux

Cómo conectarse a SQL Server desde Linux

Cómo conectarse con Samba a Linux Active Directory

verifique todos los sockets abiertos en el sistema operativo Linux