Sendet Bitcoin Nachrichtenheader und Payload separat im P2P-Protokoll?

Ich verbinde mich über TCP mit meinem lokalen Bitcoin und habe folgendes Verhalten beobachtet:

Ich sehe viele Nachrichten, bei denen nur der Header angegeben ist oder nur ein Teil der Nutzlast angehängt ist. Natürlich könnte es auch ein Fehler in meinem Code sein.

Werden die Bytes in Blöcken gesendet? Welche der folgenden sind gültig?

|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|

Hinweis: Ich verwende Versionsnummer 70002, Relais = 1 und Dienste = 0.

BEARBEITEN: Im Allgemeinen warte ich auf die verbleibenden Bytes, und meistens kommen sie an, aber in seltenen Fällen, etwa 2%, kommt ein anderer Header an. Dies geschieht nur mit txNachrichten.

EDIT2: Basierend auf den Kommentaren unten scheint es wahrscheinlich, dass es einen Fehler in meinem Code gibt. Ich überprüfe und kehre zurück.

EDIT3: War ein Fehler in meinem Code. Ich ging davon aus, dass Teildatenpakete einem einzelnen Header entsprechen. Es können mehrere Header vorhanden sein, nachdem die Daten vollständig sind (in demselben Paket). Das macht Sinn, wenn ich es als Stream betrachte.

Antworten (1)

TCP ist ein Stream-Protokoll. Obwohl der Stream drahtlos als eine Reihe von IP-Nachrichten gesendet wird, ist er semantisch nur ein Byte-Stream.

Das bedeutet, dass Sie sich auf Anwendungsebene nicht um die Nachrichtengrenzen kümmern sollten. Router und andere Internet-Infrastrukturen können Daten willkürlich in Pakete aufteilen, damit sie in ihre zugrunde liegenden Protokolle passen (zB Ethernet hat Frames von höchstens 1500 Bytes).

Ich lese die Daten vom Socket und sie kommen unvollständig (die ersten drei Fälle habe ich beim Verbinden über TCP beobachtet).
Was meinst du mit unvollständig? Es ist nur ein Strom von Bytes. Wenn ein Lesevorgang vom Socket zurückkehrt und Sie noch keine vollständige Bitcoin P2P-Nachricht haben, bedeutet dies, dass der Rest später kommt.
xDie Header-Prüfsumme überprüft, sagt, dass die Nutzlast (nicht Null) Bytes sein sollte , aber die Nachricht ist entweder nur 24 Bytes oder weniger als 24+x. Ich muss also auf den Rest der Nachricht warten, mit der Garantie, dass der Peer tatsächlich die vollständigen Daten gesendet hat und auf dem Weg ist, und er sendet keinen Header einer anderen Nachricht. Rechts?
Dann bedeutet das, dass Sie noch nicht die gesamte Nachricht gesehen haben. Den Rest sehen Sie in einem nachfolgenden Socket-Read.
Meine Frage wurde bearbeitet, um die Symptome zu erklären, anstatt die Kommentare zu erweitern.
Was meinst du mit "ein weiterer Header kommt an"? Wenn die vorherige Nachricht noch nicht vollständig ist, dann gehören die ersten nachfolgenden Bytes zu dieser Nachricht.
Die nächste Nachricht enthält stattdessen die magischen Bytes, während die frühere Nutzlast nicht vollständig empfangen wurde. Kann es sein, dass das Paket verloren gegangen ist?
Das klingt falsch. Bitcoind sollte das nicht tun (es kann natürlich einen Fehler geben, aber das scheint unwahrscheinlich, da es sehr auffällig wäre).
Sendet Bitcoin Nachrichten wie folgt? |header1|payload1|header2|payload2|oder ist es immer nur eine Nachricht auf einmal?
Warum spielt es eine Rolle? TCP ist ein Strom von Bytes. Sie können nicht sagen, auf welche Weise diese Bytes in Syscalls vom Absender aufgebrochen wurden, und es sollte Ihnen auch egal sein.