2012-04-25 12 views
6

Tengo una aplicación que envía datos punto a punto desde un remitente al receptor a través de un enlace que puede operar en modo simple (transmisión unidireccional) o dúplex (bidireccional). En modo simple, la aplicación envía datos usando UDP, y en dúplex usa TCP. Dado que una escritura en el socket TCP puede bloquearse, estamos usando Non Blocking IO (ioctl con FIONBIO - O_NONBLOCK y fcntl no son compatibles con esta distribución) y la llamada al sistema select() para determinar cuándo se pueden escribir los datos. Se usa NIO para que podamos cancelar el envío antes de tiempo después de un tiempo de espera si es necesario si las condiciones de la red se deterioran. Me gustaría usar el mismo código básico para hacer el envío, pero en cambio cambiar entre TCP/UDP en una abstracción más alta. Esto funciona muy bien para TCP.¿Puede un retorno de escritura UDP sin bloqueo con menos bytes de los solicitados?

Sin embargo, me preocupa cómo funciona Non Blocking IO para un socket UDP. Puede que esté leyendo las páginas man incorrectamente, pero dado que write() puede regresar indicando menos bytes enviados que solicitados, ¿eso significa que un cliente recibirá menos bytes en su datagrama? Para enviar un búfer de datos dado, es posible que se necesiten varias escrituras, lo que puede ser el caso, ya que estoy usando IO no bloqueante. Me preocupa que esto se traduzca en múltiples datagramas UDP recibidos por el cliente.

Soy bastante nuevo en la programación de socket, así que por favor, perdónenme si tienen algunas ideas equivocadas aquí. Gracias.

+0

Probablemente quiera verificar los detalles del sistema con el que esté trabajando; su pila UDP puede tener limitaciones específicas (de hecho, sí, como ya ha dicho). – geekosaur

Respuesta

2

Suponiendo una implementación de UDP correcta (no rota), cada send/sendmsg/sendto corresponderá exactamente a un datagrama completo enviado y cada recv/recvmsg/recvfrom corresponderá exactamente a un datagrama completo recibido.

Si no se puede transmitir un mensaje UDP en su totalidad, recibirá un error EMSGSIZE. Un mensaje enviado puede fallar debido al tamaño en algún punto de la red, en cuyo caso simplemente no llegará. Pero no se entregará en pedazos (a menos que la pila de IP tenga errores graves).

Una buena regla empírica es mantener el tamaño de la carga UDP en 1400 bytes como máximo. Eso es muy aproximado y deja mucho espacio para varias formas de tunelización para evitar la fragmentación.

+0

Gracias. Hice algunas pruebas más y descubrí que mi carga completa o nada de eso se envía para una llamada write() dada con UDP, lo que realmente es lo único lógico que haya sucedido. Estoy en VxWorks 5.5 con una pila suministrada por un proveedor para soportar un TOE ... No me sorprende que no vea un EMSGSIZE en la plataforma de destino. De todos modos, gracias por la respuesta autorizada, definitivamente ayuda a brindar la confianza de haber cubierto las bases. – aig7761

Cuestiones relacionadas