Saltar al contenido

¿Qué tan grande debe ser mi búfer de recepción al llamar a recv en la biblioteca de sockets?

Te sugerimos que revises esta respuesta en un ambiente controlado antes de enviarlo a producción, saludos.

Las respuestas a estas preguntas varían dependiendo de si está utilizando un conector de flujo (SOCK_STREAM) o un socket de datagrama (SOCK_DGRAM) – dentro de TCP/IP, el primero corresponde a TCP y el segundo a UDP.

¿Cómo sabes qué tan grande hacer que el búfer pase a recv()?

  • SOCK_STREAM: Realmente no importa demasiado. Si su protocolo es transaccional / interactivo, simplemente elija un tamaño que pueda contener el mensaje / comando individual más grande que esperaría razonablemente (3000 probablemente esté bien). Si su protocolo está transfiriendo datos a granel, entonces los búferes más grandes pueden ser más eficientes; una buena regla general es aproximadamente el mismo que el tamaño del búfer de recepción del kernel del socket (a menudo alrededor de 256kB).

  • SOCK_DGRAM: use un búfer lo suficientemente grande como para contener el paquete más grande que su protocolo de nivel de aplicación envíe. Si está utilizando UDP, entonces, en general, su protocolo de nivel de aplicación no debería enviar paquetes de más de 1400 bytes, porque seguramente necesitarán ser fragmentados y reensamblados.

Qué pasa si recv obtiene un paquete más grande que el búfer?

  • SOCK_STREAM: La pregunta realmente no tiene sentido, porque los sockets de flujo no tienen un concepto de paquetes, son solo un flujo continuo de bytes. Si hay más bytes disponibles para leer de los que tiene espacio en el búfer, el sistema operativo los pondrá en cola y estarán disponibles para su próxima llamada a recv.

  • SOCK_DGRAM: Los bytes sobrantes se descartan.

¿Cómo puedo saber si he recibido el mensaje completo?

  • SOCK_STREAM: debe crear alguna forma de determinar el final del mensaje en su protocolo de nivel de aplicación. Comúnmente esto es una longitud prefix (comenzando cada mensaje con la longitud del mensaje) o un delimitador de fin de mensaje (que podría ser simplemente una nueva línea en un protocolo basado en texto, por ejemplo). Una tercera opción, menos utilizada, es exigir un tamaño fijo para cada mensaje. También son posibles combinaciones de estas opciones, por ejemplo, un encabezado de tamaño fijo que incluye un valor de longitud.

  • SOCK_DGRAM: un solo recv call siempre devuelve un único datagrama.

¿Hay alguna manera de hacer que un búfer no tenga una cantidad fija de espacio, de modo que pueda seguir agregando sin temor a quedarse sin espacio?

No. Sin embargo, puede intentar cambiar el tamaño del búfer usando realloc() (si se asignó originalmente con malloc() o calloc(), es decir).

Para protocolos de transmisión como TCP, puede configurar su búfer en cualquier tamaño. Dicho esto, se recomiendan valores comunes que sean potencias de 2, como 4096 o 8192.

Si hay más datos que su búfer, simplemente se guardarán en el kernel para su próxima llamada a recv.

Sí, puede seguir aumentando su búfer. Puede hacer una recepción en el medio del búfer comenzando en el desplazamiento idx, tu harías:

recv(socket, recv_buffer + idx, recv_buffer_size - idx, 0);

Si tienes un SOCK_STREAM enchufe, recv solo obtiene “hasta los primeros 3000 bytes” de la transmisión. No hay una guía clara sobre qué tan grande debe ser el búfer: la única vez que sabe qué tan grande es una secuencia es cuando está todo hecho ;-).

Si tienes un SOCK_DGRAM socket, y el datagrama es más grande que el búfer, recv llena el búfer con la primera parte del datagrama, devuelve -1 y establece errno en EMSGSIZE. Desafortunadamente, si el protocolo es UDP, esto significa que el resto del datagrama se pierde, parte de por qué UDP se llama protocolo. no fidedigno protocolo (Sé que existen protocolos de datagramas confiables pero no son muy populares; no podría nombrar uno en la familia TCP/IP, a pesar de conocer este último bastante bien;-).

Para hacer crecer un búfer dinámicamente, asígnelo inicialmente con malloc y use realloc según sea necesario. Pero eso no te ayudará con recv de una fuente UDP, por desgracia.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags :

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *