He leído la documentación al menos 10 veces y también he leído alrededor de 10 fragmentos de código y programas completos donde los sockets no bloqueantes se utilizan para enviar datos. El problema es que algunos de los tutoriales son para principiantes (Beejs f.i.) o son bastante descuidados en sus suposiciones; y aquellos que no son complicados son ejemplos de códigos especializados que no explican por qué hacen lo que hacen. Incluso la base de conocimiento de SO no cubre exhaustivamente toda la gama de comportamiento de send
, en mi opinión. Lo que busco son detalles sobre f.e:¿Puede alguien darme una buena explicación del comportamiento de 'envío' para tomas sin bloqueo?
- ¿Qué significa el código de retorno de 0 indican exactamente, y es digno de la comprobación
errno
en ese momento o si uno simplemente descartar la conexión sin más investigación? - ¿Obtener un valor de retorno negativo justifica el cierre de una conexión que no funciona bien o solo a menos que
errno
seaEWOULDBLOCK
,EAGAIN
oEINTR
(... others)? - ¿Vale la pena consultar
errno
cuando el valor devuelto es> 0
? Aparentemente, el valor indica la cantidad de datos "enviados" (entre comillas porque es realmente un proceso largo, correcto), pero dado que el socket no es bloqueado, significa que se puede emitir otra llamada de inmediato o, dependiendo deerrno
otra vez , uno debe esperar la próxima ocasión de envío (usando select/poll/epoll)? - Básicamente, ¿se verifica primero el valor de retorno y solo luego el valor
errno
? ¿O quizássend
estableceerrno
en cada llamada, independientemente del valor de retorno? Eso haría que la comprobación de errores fuera algo más fácil ... - Si se obtiene
EINTR
, ¿cuál sería un comportamiento bueno y sólido para un programa? Simplemente registre el estado y vuelva a intentarlo en la próxima ocasión de envío, como conEWOULDBLOCK
yEAGAIN
? - ¿Tiene un cheque por tanto
EWOULDBLOCK
yEAGAIN
? ¿Podemos confiar en que ambos tengan el mismo valor o depende de la implementación? - ¿
send
devuelveEMSGSIZE
para las tomas de corriente? Si no es así, entonces el tamaño de la memoria intermedia no es demasiado grande, ¿verdad? - ¿El valor de retorno puede ser igual a cualquiera de los códigos de error conocidos?
Si pudiera proporcionar un ejemplo de código de envío sólido sin bloqueo, sería absolutamente apreciado.
send (2) puede devolver 0 si se pasa cero para 'len'. Para un protocolo de datagrama como UDP, esto incluso daría como resultado el envío de un paquete de cero bytes. Además, no se garantiza que errno no se modifique a través de una llamada exitosa a la biblioteca. – Anomie
@Anomie: la primera parte es bastante cierta, pero por el segundo, POSIX garantiza que ciertas llamadas a la biblioteca no modificarán errno si no hay ningún error, y 'enviar' es una de esas llamadas. –
¿Dónde ves eso? POSIX.1-2008 está en línea [aquí] (http://pubs.opengroup.org/onlinepubs/9699919799/). [La página en errno] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/errno.html) dice "La configuración de errno después de una llamada exitosa a una función no está especificada a menos que la descripción de esa función especifique que errno no se modificará ", y [la página para enviar] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/send.html) no parece decir tal cosa. – Anomie