Tengo un problema para entender qué devuelve recv()/recvfrom() de un socket UDP no bloqueado.programación de socket udp sin bloqueo en C: ¿qué obtengo?
un poco más específico y en comparación con TCP (por favor, corríjanme si me equivoco):
Un socket de bloqueo (TCP o UDP) no volverá a partir de un recv() hasta que haya hay algunos datos en el búfer. Esto podría ser una cantidad de bytes (TCP) o un datagrama completo (UDP).
Un socket TCP no bloqueante devuelve EWOULDBLOCK (linux)/WSAEWOULDBLOCK (Windows) o los bytes que están actualmente en el búfer. Como los datos TCP son una secuencia, no importa cuántos bytes se devuelvan.
Ahora la pregunta:
- un socket UDP no bloqueante también devuelve WOULDBLOCK (Linux)/WSAEWOULDBLOCK (Windows) Si no hay datos disponibles. Pero si hay datos disponibles, ¿un socket UDP sin bloqueo devuelve solo algunos bytes, lo que podría significar que solo obtiene la mitad de un datagrama O un socket UDP siempre devuelve datagramas completos?
Editar:
Lo que quiero decir con "la mitad de un datagrama" es: ¿qué ocurre si llamo a recv() sólo en el momento en que la toma está recibiendo actualmente un datagrama. En ese momento, hay algunos bytes en el búfer, pero el datagrama aún no está completo.
Sus explicaciones y comentarios son apreciados. ¡Gracias!
Parece que es posible pasar y recibir un indicador MSG_TRUNC a 'recvmsg' en Linux. Documentado en la página de manual 'recv (2)'. En otra nota, tal vez estoy malinterpretando, pero solo puedo encontrar el comportamiento de descarte documentado en la página de manual para 'socket (2)', que solo lo menciona para los sockets 'SOCK_SEQPACKET'. Nunca los he usado personalmente. –
'MSG_TRUNC' como argumento para' recv (2) 'no es estándar. No está disponible ni en FreeBSD ni en Mac OS X (los sistemas a los que tengo acceso en este momento, probablemente sean ciertos para otros). 'MSG_TRUNC' está disponible en Linux, FreeBSD y Mac OS X en el miembro' flags' de 'struct msghdr' pasado a' recvmsg (2) '. En cualquier caso, el datagrama se truncará si el búfer pasado no es lo suficientemente grande, incluso con 'recv (2)' en Linux. La persona que llama debe verificar el valor de retorno y compararlo con el tamaño del búfer si se usa 'MSG_TRUNC' allí. Sabrá que la información se perdió, pero aún está perdida. –
¡Gracias! Esto significa que UDP está ** realmente ** orientado a paquetes ... – Uwe