<p>TCP is a stream protocol. Even though on the wire the stream is submitted as a series of IP messages, semantically it is just a stream of bytes.</p>

<p>This means that at the application level you shouldn't care about the message boundaries. Routers and other internet infrastructure can arbitrarily split up data into packets to fit in their underlying protocols (e.g. Ethernet has frames of at most 1500 bytes).</p>

CC BY-SA 3.0
2018-01-09T11:19:16.873Z
I am reading the data from socket and it comes incomplete (the first three cases, I have observed when connecting using TCP).
Jus12
CC BY-SA 3.0
2018-01-09T11:21:06.570Z
What do you mean by incomplete? It's just a stream of bytes. If a read from the socket returns and you don't have a full Bitcoin P2P message yet, it means the rest will come later.
Pieter Wuille
CC BY-SA 3.0
2018-01-09T11:21:53.120Z
The header checksum verifies, says payload should be `x` (non zero) bytes but the message is either only 24 bytes or less than `24+x`. So I need to wait for the rest of the message, with the guarantee that the peer has actually send the complete data and its on the way, and it won't send header of a different message. Right?
Jus12
CC BY-SA 3.0
2018-01-09T11:22:26.803Z
Then that means you haven't seen the entire message yet. You'll see the rest in a subsequent socket read.
Pieter Wuille
CC BY-SA 3.0
2018-01-09T11:27:04.300Z
Edited my question to explain the symptoms instead of extending the comments.
Jus12
CC BY-SA 3.0
2018-01-09T11:29:11.573Z
What do you mean by "another header arrives"? If the previous message isn't complete yet, then the first bytes that follow belong to that message.
Pieter Wuille
CC BY-SA 3.0
2018-01-09T11:31:06.670Z
The next message instead has the magic bytes, while the earlier payload was not fully received. Is it possible that the packet was lost?
Jus12
CC BY-SA 3.0
2018-01-09T11:32:32.677Z
That sounds wrong. Bitcoind should not do that (there can be a bug of course, but that seems unlikely as it would be very noticable).
Pieter Wuille
CC BY-SA 3.0
2018-01-09T11:55:12.533Z
Does bitcoind send messages as follows? `|header1|payload1|header2|payload2|` or is it always only one message at a time?
Jus12
CC BY-SA 3.0
2018-01-09T14:28:39.860Z
Why does it matter? TCP is a stream of bytes. You can't tell in which way those bytes were broken up in syscalls by the sender, and you shouldn't care.
Pieter Wuille
CC BY-SA 3.0
2018-01-09T11:18:34.120Z
2018-01-09T11:18:34.120Z
Pieter Wuille
<p>I am connecting to my local bitcoind using TCP and observed the following behavior: </p>

<p>I see many messages where only header is given or only part of the payload is attached. Of course, it could be a bug my code too. </p>

<p>Are the bytes sent in chunks? Which of the following are valid?</p>

<pre><code>|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|
</code></pre>

<p>Note: I am using version number 70002, relay = 1 and services = 0.</p>

<p>EDIT: Generally I wait for the remaining bytes, and most of the times they arrive, but in rare cases, around 2%, some other header arrives. This happens only with <code>tx</code> messages. </p>

<p>EDIT2: Based on the comments below, it seems likely that there is a bug in my code. I'll check and revert. </p>

<p>EDIT3: Was a bug in my code. I was assuming that partial data packets correspond to a single header. There can be multiple headers after the data is complete (in the same packet). This makes sense once I consider it as a stream. </p>

<bitcoind><protocol><message><inventory>
Does bitcoind send message headers and payload separately in P2P protocol?
Jus12
# Does bitcoind send message headers and payload separately in P2P protocol?

(Asked by: username_0 on 2018-01-09)

I am connecting to my local bitcoind using TCP and observed the following behavior:

I see many messages where only header is given or only part of the payload is attached. Of course, it could be a bug my code too.

Are the bytes sent in chunks? Which of the following are valid?

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

```

Note: I am using version number 70002, relay = 1 and services = 0.

EDIT: Generally I wait for the remaining bytes, and most of the times they arrive, but in rare cases, around 2%, some other header arrives. This happens only with `tx` messages.

EDIT2: Based on the comments below, it seems likely that there is a bug in my code. I'll check and revert.

EDIT3: Was a bug in my code. I was assuming that partial data packets correspond to a single header. There can be multiple headers after the data is complete (in the same packet). This makes sense once I consider it as a stream.

**Tags:** bitcoind, protocol, message, inventory


---

## 1 answers

### Answer by username_1 on 2018-01-09. Score: 1 | Accepted answer

TCP is a stream protocol. Even though on the wire the stream is submitted as a series of IP messages, semantically it is just a stream of bytes.

This means that at the application level you shouldn't care about the message boundaries. Routers and other internet infrastructure can arbitrarily split up data into packets to fit in their underlying protocols (e.g. Ethernet has frames of at most 1500 bytes).

> **Comments:**
> **username_0**: I am reading the data from socket and it comes incomplete (the first three cases, I have observed when connecting using TCP).  
> **username_1**: What do you mean by incomplete? It's just a stream of bytes. If a read from the socket returns and you don't have a full Bitcoin P2P message yet, it means the rest will come later.  
> **username_0**: The header checksum verifies, says payload should be `x` (non zero) bytes but the message is either only 24 bytes or less than `24+x`. So I need to wait for the rest of the message, with the guarantee that the peer has actually send the complete data and its on the way, and it won't send header of a different message. Right?  
> **username_1**: Then that means you haven't seen the entire message yet. You'll see the rest in a subsequent socket read.  
> **username_0**: Edited my question to explain the symptoms instead of extending the comments.  
> **username_1**: What do you mean by "another header arrives"? If the previous message isn't complete yet, then the first bytes that follow belong to that message.  
> **username_0**: The next message instead has the magic bytes, while the earlier payload was not fully received. Is it possible that the packet was lost?  
> **username_1**: That sounds wrong. Bitcoind should not do that (there can be a bug of course, but that seems unlikely as it would be very noticable).  
> **username_0**: Does bitcoind send messages as follows? `|header1|payload1|header2|payload2|` or is it always only one message at a time?  
> **username_1**: Why does it matter? TCP is a stream of bytes. You can't tell in which way those bytes were broken up in syscalls by the sender, and you shouldn't care.  

---

