Отправляет ли биткойн заголовки сообщений и полезную нагрузку отдельно в протоколе P2P?

Я подключаюсь к своему локальному биткойну с помощью TCP и наблюдаю следующее поведение:

Я вижу много сообщений, в которых указан только заголовок или прикреплена только часть полезной нагрузки. Конечно, это может быть ошибка и в моем коде.

Байты отправляются кусками? Какие из следующих действительны?

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

Примечание. Я использую номер версии 70002, реле = 1 и службы = 0.

РЕДАКТИРОВАТЬ: Обычно я жду оставшиеся байты, и в большинстве случаев они приходят, но в редких случаях, около 2%, приходит какой-то другой заголовок. Это происходит только с txсообщениями.

EDIT2: судя по приведенным ниже комментариям, кажется вероятным, что в моем коде есть ошибка. Я проверю и вернусь.

EDIT3: в моем коде была ошибка. Я предполагал, что частичные пакеты данных соответствуют одному заголовку. После завершения данных (в одном пакете) может быть несколько заголовков. Это имеет смысл, если я рассматриваю это как поток.

Ответы (1)

TCP — это потоковый протокол. Несмотря на то, что по сети поток передается в виде серии IP-сообщений, семантически это просто поток байтов.

Это означает, что на уровне приложения вы не должны заботиться о границах сообщения. Маршрутизаторы и другая интернет-инфраструктура могут произвольно разбивать данные на пакеты, чтобы они соответствовали их базовым протоколам (например, Ethernet имеет кадры размером не более 1500 байт).

Я читаю данные из сокета, и они приходят неполными (первые три случая я наблюдал при подключении по TCP).
Что вы подразумеваете под неполным? Это просто поток байтов. Если чтение из сокета возвращается, а у вас еще нет полного биткойн-сообщения P2P, это означает, что остальное придет позже.
Контрольная сумма заголовка проверяет, говорит, что полезная нагрузка должна быть x(не нулевой) байтами, но сообщение имеет размер всего 24 байта или меньше 24+x. Поэтому мне нужно дождаться остальной части сообщения с гарантией того, что одноранговый узел действительно отправил полные данные и находится в пути, и он не отправит заголовок другого сообщения. Верно?
Тогда это означает, что вы еще не видели все сообщение. Остальное вы увидите в последующем чтении сокета.
Отредактировал мой вопрос, чтобы объяснить симптомы, а не расширять комментарии.
Что вы подразумеваете под «приходит другой заголовок»? Если предыдущее сообщение еще не завершено, то первые последующие байты принадлежат этому сообщению.
Вместо этого следующее сообщение содержит магические байты, в то время как предыдущая полезная нагрузка не была получена полностью. Возможно ли, что пакет был потерян?
Это звучит неправильно. Биткойн не должен этого делать (конечно, может быть ошибка, но это маловероятно, так как будет очень заметно).
Отправляет ли биткойн сообщения следующим образом? |header1|payload1|header2|payload2|или это всегда только одно сообщение за раз?
Почему это имеет значение? TCP — это поток байтов. Вы не можете сказать, каким образом эти байты были разбиты отправителем в системных вызовах, и вас это не должно волновать.