Soy consciente de que ::send dentro de un servidor TCP de Linux puede limitar el envío de la carga útil de tal manera que se debe llamar a ::send varias veces hasta que se envíe toda la carga útil.
es decir, la carga útil es de 1024 bytes
sent_bytes = ::send(fd, ...) donde sent_bytes tiene solo 256 bytes, por lo que debe llamarse nuevamente.
¿Hay alguna forma de saber exactamente cuántos bytes se pueden enviar antes de enviar? ¿Si el socket permitirá el mensaje completo, o si el mensaje estará fragmentado y por cuánto?
Caso de ejemplo
2 mensajes son enviados al mismo socket por diferentes subprocesos al mismo tiempo en el mismo cliente tcp a través de ::send() . En algunos casos en los que los mensajes son grandes, se requieren múltiples llamadas a ::send() ya que no todos los bytes se envían en la llamada inicial. Por lo tanto, vaya con la solución de bucle hasta que se envíen todos los bytes. El bucle está silenciado, por lo que puede verse como seguro para subprocesos, por lo que cada subproceso debe realizar el envío después del otro. Pero mi preocupación es que debido a que Tcp es una transmisión, el cliente recibirá fragmentos de cada mensaje y estaba pensando que agregando marcos a cada mensaje podría reconstruir el mensaje en el lado del cliente, si supiera cuántos bytes se envían a la vez. .
Aunque la llamada a ::send() se realiza secuencialmente, ¿hay alguna posibilidad de que el flujo de bytes aún esté mezclado?
Efectivamente, podría suceder esto:
Aunque la llamada a ::send() se realiza secuencialmente, ¿hay alguna posibilidad de que el flujo de bytes aún esté mezclado?
Por supuesto. No solo existe la posibilidad de eso, sino que será una certeza, en un momento u otro. Va a suceder en un momento. Garantizado.
enviado al mismo socket por diferentes subprocesos
Será necesario manejar la sincronización a este nivel, empleando un mutex que cada subproceso bloquea antes de enviar su mensaje y lo desbloquea solo después de que se envía el mensaje completo.
No hace falta enviar que esto deja abierta la posibilidad de que un socket bloqueado/colgado resulte en un solo subproceso que bloquee este mutex durante una cantidad de tiempo excesiva, hasta que el socket se agote y su subproceso de ejecución termine lidiando con un send() o write() , de cualquier manera que ya esté haciendo ahora (por supuesto, está verificando el valor de retorno de send/write y manejando las condiciones de excepción de manera apropiada).
No existe una solución única, simple, pintada por números, que funcione en cada situación, en cada programa, que necesite hacer algo como esto. Cada solución eventual debe adaptarse en función de los requisitos y el propósito únicos de cada programa. Solo una posibilidad sería un subproceso de ejecución dedicado que maneje todas las entradas/salidas del socket, y todos los demás subprocesos de ejecución que envíen sus mensajes al subproceso del socket, en lugar de escribir directamente en el socket. Esto evitaría tener todo el subproceso de ejecución acuñado por un socket colgado, a expensas de la memoria creciente, que contiene todos los datos no enviados.
Pero ese es solo un enfoque posible. El número de posibles soluciones alternativas no tiene límite. Deberá averiguar qué solución basada en lógica/algoritmo funcionará mejor para su programa específico. No hay ninguna indicación de nivel de sistema operativo/núcleo que le dé algún tipo de garantía en cuanto a la cantidad de una llamada send() o write() que aceptará un socket.