2010-08-26 19 views
6

Uso bloqueos C en Windows. Los uso para enviar actualizaciones de datos desde el servidor al cliente y viceversa. Envío actualizaciones a una frecuencia alta (cada 100 ms). ¿La función send() esperará a que el receptor recv() reciba los datos antes de finalizar?Enchufe C: ¿envía esperar a que termine el recv?

yo no asumo si entiendo bien la página del manual:

"La conclusión con éxito de send() no garantiza la entrega del mensaje."

Entonces, ¿qué va a pasar si se está ejecutando 10 send() ocurrencias mientras que el otro tiene sólo se completa 1 recv()?

¿Debo utilizar algún tipo de sistema de confirmación?

+0

¿Cuál es el tipo de protocolo del socket? TCP, UDP, algo más? – torak

+0

Uso el protocolo TCP – Giann

Respuesta

10

Supongamos que está utilizando TCP. Cuando llamas a send, los datos que estás enviando se colocan inmediatamente en la cola saliente y se envían y luego se completan con éxito. Sin embargo, si el envío no puede colocar los datos en la cola saliente, el envío regresará con un error.

Como Tcp es un protocolo de entrega garantizado, los datos en la cola saliente solo se pueden eliminar una vez que el extremo remoto ha recibido el acuse de recibo. Esto se debe a que los datos pueden ser reenviados si no se recibió ack a tiempo.

Si el extremo remoto es lento, la cola saliente se llenará de datos y el envío se bloqueará hasta que haya espacio para colocar los nuevos datos en la cola saliente.

Sin embargo, la conexión puede fallar de tal forma que no se pueden enviar más datos. Aunque una vez que se ha cerrado una conexión TCP, cualquier envío adicional dará como resultado un error, el usuario no tiene forma de saber cuántos datos realmente llegaron al otro lado. (No conozco ninguna forma de recuperar la contabilidad TCP desde un socket a la aplicación del usuario). Por lo tanto, si se requiere la confirmación de la recepción de datos, probablemente debería implementar esto en el nivel de la aplicación.

Para UDP, creo que no hace falta decir que una forma de informar lo que se ha recibido o no se debe.

7

send() bloques hasta que el sistema operativo (kernel) haya tomado los datos y los haya almacenado en un búfer de datos salientes. No espera hasta que el otro extremo haya recibido los datos.

0

Si está utilizando TCP, obtiene los reconocimientos de forma gratuita ya que es parte de lo que el protocolo hace bajo el capó. Pero parece que para este tipo de aplicaciones probablemente quieras usar UDP. En cualquier caso, aunque send() no bloqueará hasta que el cliente tenga éxito recv().

Si es crucial que el cliente reciba cada mensaje, entonces use TCP. Si está bien que el cliente pierda uno o más mensajes, entonces use UDP.

+1

Obtiene acks en la capa TCP, pero eso no lo ayuda si necesita ayuda en la capa de la aplicación, es decir, si necesita saber que se recibió un mensaje, debe implementar acks en cualquier aplicación protocolo que estás usando – nos

2

Si envía por TCP, obtiene la entrega garantizada y el otro extremo recibirá los datos en el orden enviado. Sin embargo, esto podría combinarse, de modo que lo que envió como 10 actualizaciones separadas podría recibirse como un único paquete grande (o viceversa, una sola actualización podría dividirse en un número arbitrario de paquetes). Esto significa, entre otras cosas, que cualquier ACK de cualquier dato reconoce implícitamente la recepción de todos los datos anteriores.

Si está utilizando UDP, nada de eso es cierto: los datos pueden llegar desordenados, o pueden perderse y nunca entregarse. Si te importan todos los datos que recibes, simplemente necesitas construir algún tipo de sistema de reconocimiento propio sobre UDP.

Por supuesto, hay un límite en la garantía: si se corta un cable de red (o lo que sea) no se entregarán los paquetes, pero al menos recibirá un mensaje de error indicándole que la conexión se perdió.

0

TCP garantiza la entrega en un nivel de pila TCP más bajo. Reintenta la entrega hasta que la parte receptora reconozca que se recibieron los datos, pero es posible que su aplicación nunca se entere de ello.

Digamos que está enviando fragmentos de datos y necesita colocar esos fragmentos de datos en algún lugar de acuerdo con alguna lógica. Si su aplicación no está preparada para saber dónde debe colocarse cada bloque individual, recibirlo en el nivel TCP puede ser inútil. La publicación original era sobre la lógica de nivel de aplicación.

Cuestiones relacionadas