¿Bitcoind envía encabezados de mensajes y carga útil por separado en el protocolo P2P?

Me estoy conectando a mi bitcoind local usando TCP y observé el siguiente comportamiento:

Veo muchos mensajes en los que solo se proporciona el encabezado o solo se adjunta una parte de la carga útil. Por supuesto, también podría ser un error en mi código.

¿Los bytes se envían en fragmentos? ¿Cuáles de los siguientes son válidos?

|header1|payload1|     (as per documentation, this is valid)
|header1|              (no payload, even though required. Have seen this)
|payload1|             (no header, have seen this)
|header1|partPayload1| (incomplete payload, not sure if seen these)
|partPayload1|         (part earlier header's payload, not sure if seen these)
|header1|payload1|header2|payload2| 
|header1|payload1|header2|partPayload2|  
|header1|partPayload1|header2|
|partPayload1|header2|payload2|

Nota: estoy usando el número de versión 70002, relé = 1 y servicios = 0.

EDITAR: generalmente espero los bytes restantes, y la mayoría de las veces llegan, pero en casos raros, alrededor del 2%, llega algún otro encabezado. Esto sucede solo con txlos mensajes.

EDIT2: según los comentarios a continuación, parece probable que haya un error en mi código. Voy a comprobar y revertir.

EDIT3: Fue un error en mi código. Supuse que los paquetes de datos parciales corresponden a un solo encabezado. Puede haber múltiples encabezados después de que los datos estén completos (en el mismo paquete). Esto tiene sentido una vez que lo considero como una corriente.

Respuestas (1)

TCP es un protocolo de flujo. Aunque en el cable la transmisión se envía como una serie de mensajes IP, semánticamente es solo una transmisión de bytes.

Esto significa que, a nivel de la aplicación, no debería preocuparse por los límites del mensaje. Los enrutadores y otras infraestructuras de Internet pueden dividir arbitrariamente los datos en paquetes para que encajen en sus protocolos subyacentes (por ejemplo, Ethernet tiene marcos de 1500 bytes como máximo).

Estoy leyendo los datos del socket y vienen incompletos (los primeros tres casos, los he observado al conectarme usando TCP).
¿A qué te refieres con incompleto? Es solo un flujo de bytes. Si regresa una lectura del socket y aún no tiene un mensaje completo de Bitcoin P2P, significa que el resto llegará más tarde.
La suma de verificación del encabezado verifica, dice que la carga útil debe ser x(no cero) bytes, pero el mensaje tiene solo 24 bytes o menos de 24+x. Así que debo esperar el resto del mensaje, con la garantía de que el par realmente envió los datos completos y está en camino, y no enviará el encabezado de un mensaje diferente. ¿Bien?
Entonces eso significa que aún no has visto el mensaje completo. Verá el resto en una lectura de socket posterior.
Edité mi pregunta para explicar los síntomas en lugar de extender los comentarios.
¿A qué te refieres con "llega otra cabecera"? Si el mensaje anterior aún no está completo, los primeros bytes que siguen pertenecen a ese mensaje.
En cambio, el siguiente mensaje tiene los bytes mágicos, mientras que la carga útil anterior no se recibió por completo. ¿Es posible que el paquete se haya perdido?
Eso suena mal. Bitcoind no debería hacer eso (puede haber un error, por supuesto, pero eso parece poco probable ya que sería muy notable).
¿Bitcoind envía mensajes de la siguiente manera? |header1|payload1|header2|payload2|¿O es siempre un solo mensaje a la vez?
¿Por qué eso importa? TCP es un flujo de bytes. No puede saber de qué manera el remitente dividió esos bytes en llamadas al sistema, y ​​no debería importarle.