Por lo tanto, la respuesta a su pregunta depende un poco justo de si se está utilizando UDP o TCP como su transporte.
Para UDP, la vida se vuelve mucho más simple, ya que puede llamar a recv/recvfrom/recvmsg con el tamaño de paquete que necesita (probablemente envíe paquetes de longitud fija desde la fuente) y asume que si los datos están disponibles, están allí en múltiplos de tamaños de paquetes de longitud. (Por ejemplo, usted llama a recv * con el tamaño de su paquete de envío y está configurado).
Para TCP, la vida se pone un poco más interesante. Para el propósito de esta explicación, asumiré que ya sabe cómo usar socket(), bind(), listen() y accept() - siendo esta última la forma de obtener el descriptor de archivo (FD) de su conexión recién creada.
Hay dos maneras de hacer las E/S para un socket - blocking, en el que llama a read (fd, buf, N) y la lectura se queda ahí y espera hasta que haya leído N bytes en buf - o sin bloqueo, en el que debe verificar (usando select() o poll()) si el FD es legible, y LUEGO haga su lectura().
Cuando se trata de conexiones basadas en TCP, el sistema operativo no presta atención a los tamaños de paquete, ya que se considera una secuencia continua de datos, no fragmentos separados del tamaño de un paquete.
Si su aplicación usa "paquetes" (estructuras de datos empaquetadas o no empaquetadas que está pasando), debe poder llamar a read() con el argumento de tamaño adecuado y leer toda una estructura de datos fuera del socket a la vez La única advertencia con la que tiene que lidiar es recordar ordenar por byte correctamente todos los datos que está enviando, en caso de que el sistema de origen y el de destino sean de diferente entidad de bytes. Esto se aplica tanto a UDP como a TCP.
Por lo que se refiere a * NIX socket programming, recomiendo W. Richard Stevens 'Unix Network Programming, Vol. 1 "(UNPv1) y" Advanced Programming in Unix Environment "(APUE). El primero es un tomo sobre programación basada en red, independientemente del transporte, y el último es un buen libro de programación versátil, ya que se aplica a la programación * basada en NIX. Además, busque "TCP/IP Illustrated", Volúmenes 1 y 2.
¿No debería el retorno anticipado después de la conexión cerrada ser "return bytesRead;" en lugar de "return ret;"? Supongo que la función readBytes está destinada a devolver el número real de bytes leídos. Supongo que podría definirlo para devolver un entero no positivo si hay un error, pero también podría detectar que ocurrió un error al verificar si readBytes devuelve un número de bytes diferente del solicitado. –
un valor negativo para marcar un estado de error es una práctica común en la programación C y se debe cumplir tanto como sea posible para evitar confusiones por parte del usuario de la API. – Guss
Modifiqué mi función de ejemplo para devolver el número de bytes leídos incluso si se produjo un error durante la lectura. Un punto a tener en cuenta con los sockets es que una lectura que devuelve cero indica que la conexión se cerró, y puede no ser necesariamente un error. – dfjacobs