2010-07-07 14 views
5

En la programación de socket TCP, si recv() devuelve 0, se toma como una indicación de que el otro lado cerró su conexión. Sin embargo, AFAIK, el TCP RFC no ordena que la carga de TCP sea> 0. Entonces, teóricamente, una pila TCP puede recibir un mensaje con la carga 0.¿Qué valor devolverá recv() si recibe un paquete TCP válido con tamaño de carga 0

Entonces, esencialmente mi pregunta es ¿qué devolverá recv() si recibe un paquete de tamaño de carga 0? Si devuelve 0, ¿cómo lo distinguimos de una indicación de conexión cerrada?

Respuesta

11

Los segmentos TCP con un tamaño de carga de 0 son omnipresentes, se producen en casi todas las corrientes TCP del mundo real. Se envían siempre que una de las partes desea acusar recibo de datos de la otra, pero no tiene datos para enviar por su cuenta. (Estos son comúnmente conocidos como "paquetes ACK", pero un "paquete ACK" es solo un segmento regular que no contiene datos).

Dado que tales paquetes no contienen ningún dato para entregar a la aplicación del usuario, no harán que recv() regrese - recv() continuará bloqueando hasta que lleguen algunos datos reales. Si recv() devuelve 0, entonces es una indicación definitiva de que el otro extremo ha cerrado su lado de la conexión y no enviará más datos.

Recuerde que TCP es orientado a flujo: hay no un mapeo 1-a-1 entre los datos devueltos por un solo recv() llamada y los datos en un segmento TCP solo. Una sola llamada a recv() podría devolver un bloque de datos que se superpone a varios segmentos TCP, y los datos en un único segmento TCP podrían devolverse en múltiples llamadas recv(). Los límites entre los segmentos TCP no son visibles para la aplicación que utiliza la API de sockets BSD. Si desea dichos límites, debe implementarse usando un protocolo de capa de aplicación dentro de la secuencia TCP, o usar un protocolo orientado a datagramas como UDP.

+0

+1 por mencionar ACK. –

+0

Los paquetes ACK tendrán un indicador de ACK establecido. – AlastairG

+1

@AlastairG: Correcto, pero cada paquete que no sea el 'SYN' inicial o un restablecimiento de conexión tiene el bit' ACK' establecido. – caf

3

Derecho, de acuerdo con POSIX si recv devuelve 0, entonces la conexión se cierra correctamente por el par.

Si alguien ha logrado enviar un paquete TCP con una carga útil de tamaño cero, entonces el sistema operativo no tiene que devolver ningún dato al proceso que está siendo bloqueado en recv llamada al sistema en ese socket.

Recuerde que las cargas útiles TCP forman una secuencia continua que puede ser segmentada aleatoriamente por el sistema operativo, no una secuencia de datagramas que deben devolverse durante una sola llamada al sistema.

Cuestiones relacionadas