Extra byte in TCP- vs RTMP-level packet - tcp

I am trying to debug a RTMP client that fails to connect to some servers. I'm using Wireshark to capture the packets and compare them with a client that connects successfully (in this case, ffmpeg).
Looking at the captured packets for a successfull connection, I noticed that, when viewing at TCP level, there is an extra byte in the payload (see pics below). The extra byte has value 0xc3 and is placed at byte 0xc3 in the payload.
I Googled the best I could to find information about extra bytes in the TCP payload, but I didn't find anything like this. I tried to look in the TCP spec but no luck either. Where can I find information about this ?
TCP-level view
RTMP-level view

This happens because the message length is larger than the maximum chunk size (as per the RTMP spec, the default maximum chunk size is 128). So if no Set Chunk Size control message was sent before connect (in your case), and the connect message is greater than 128 bytes, the client will split the message into multiple chunks.
0xC3 is the header of the next chunk, looking at the bits of 0xC3 we would have 11 000011. The highest 2 bits specify the format (fmt = 3 in this case, meaning that this next chunk is a type 3 chunk as per the spec). The remaining 6 bits specify the chunk stream ID (in this case 3). So that extra byte you're seeing is the header of a new chunk. The client/server would then have to assemble these chunks to form the complete message.

Related

Mavlink command what does the [180] means?

I am trying to send a mavlink command for instance
GPS_RTCM_DATA ( #233 )
flags uint8_t
len uint8_t
data uint8_t[180] RTCM message (may be fragmented)
https://mavlink.io/en/messages/common.html#GPS_RTCM_DATA
I understand uint8_ would be in a single byte unsigned int.
What does the [180] means?
The uint8_t[180] in the MAVLink GPS_RTCM_DATA message means that the data field can contain up to 180 bytes.
Beware that RTCM messages can be bigger than 180 bytes and be fragmented in
more than one GPS_RTCM_DATA message.
You can check the flags field as stated in the mavlink documentation:
LSB: 1 means message is fragmented, next 2 bits are the fragment ID,
the remaining 5 bits are used for the sequence ID. Messages are only
to be flushed to the GPS when the entire message has been
reconstructed on the autopilot. The fragment ID specifies which order
the fragments should be assembled into a buffer, while the sequence ID
is used to detect a mismatch between different buffers. The buffer is
considered fully reconstructed when either all 4 fragments are
present, or all the fragments before the first fragment with a non
full payload is received. This management is used to ensure that
normal GPS operation doesn't corrupt RTCM data, and to recover from a
unreliable transport delivery order.
I tried every but it doesn't work. Except putting it as a 180 byte arrays. The data might be only 30 bytes for example. But input with the other 150 0x00 bytes in this way, the python program accepts my command. Strangely so. I can't explain why but in this case it works.

how to write one string at time using qtcpsocket?

How to send string using Qtcpsocket, when using
tcpsocket->write("hello");
tcpsocket->write("world");
etc..
tcpSocket->flush();
tcpSocket->waitForBytesWritten(3000);
it send it in one string "hello world", what i want make it write only one at time, i want make client recive "hello" then "world".
This is not how TCP works. TCP is a byte stream protocol, not a message protocol. You might programatically write N bytes on the sending side, but the remote end might not receive all N bytes at once. In fact, when it does a recv on its end, it might only get 1 byte, N-1 bytes, or some other number of bytes. Issues such as IP fragmentation, TCP segmentation, TCP window size, can influence this.
Further if you write "Hello" and "World" separately to the socket, the message could easily get coalesced (on the sender or receiver side), such that "HelloWorld" is received all at once. Again, because TCP is a byte stream, not a message based protocol.
When you write TCP code, you have to deal with these issues, because they really do happen.
When you want to do:
Each word is a "message". But each message needs it's only encapsulation. Perhaps you could send the messages like this:
tcpsocket->write("hello|");
tcpsocket->write("world|");
Where the trailing | pipe character of each word is the delimiter between each logical word. You could also use a space instead of a pipe char. Or have your own protocol header to indicate the number of bytes to follow. Regardless, it's up to the receiving side to parse the the messages from the byte stream back together to form the application messages.

GnuRadio tcp_sink data values are garbled

I'm developing a web front end for a GNU Radio application developed by a colleague.
I have a TCP client connecting to the output of two TCP Sink blocks, and the data encoding is not as I expect it to be.
One TCP Sink is sending complex data and the other is sending float data.
I'm decoding the data at the client by reading each 4-byte chunk as a float32 value. The server and the client are both little-endian systems, but I also tried byte swapping (with the GNU Radio Endian Swap block and also manually at the client), and the data is still not right. Actually it's much worse then, confirming there is no byte order mismatch.
When I execute the flow graph in GNU Radio Companion with appropriate GUI elements, the plots look correct. The data values are shown as expected to between 0 and 10.
However the values decoded at the client are generally around 0.00xxxxx, and the plot looks like noise rather than showing a simple tone as is seen in GNU Radio. If I manually scale the data by multiplying by 1000 it still looks like noise.
I'll describe the pre-D path in GNU Radio since it's shorter, but I see the same problem on the post-D path, where a WBFM Receive and a Rational Resampler are added, followed by a Throttle block and then a TCP Sink block sending float data.
File Source (Output Type: complex, vector length: 1) =>
Throttle (vector length: 1) =>
Low Pass Filter (FIR Type: Complex->Complex (Decimating)) =>
Throttle (vector length: 1) =>
TCP Sink (input type: complex, vector length: 1).
This seems to be the correct way to specify the stream parameters (and indeed Companion shows errors if I make changes which mismatch the stream items), but I can find no way to decode the data correctly on the other end of the stream.
"the historic RFC 1700 (also known as Internet standard STD 2) has defined the network order for protocols in the Internet protocol suite to be big-endian , hence the use of the term 'network byte order' for big-endian byte order."
see https://en.wikipedia.org/wiki/Endianness
having mentioned the network order for protocols being big-endian, this actually says nothing about the byte order of network payload itself.
also note: Sun Microsystems made big-endian native byte order computers (upon which much Internet protocol development was done).
i am surprised the previous answer has gone this long without a lesson on network byte order versus native byte order.
GNURadio appears to assume native byte order from a UDP Source block.
Examining the datatype color codes in Help->Types of GNURadio Companion, the orange colored 'float' connections are float32.
To verify a computer's native byte order, in Python, do:
from sys import byteorder
byteorder
the result will be 'little' or 'big'
It might be possible that no matter what type floats you are sending, when bytes get on network they get ordered in little endian. I had similar problem with udp connection, and I solved it by parsing floats as little endian on client side.

How do you read without specifying the length of a byte slice beforehand, with the net.TCPConn in golang?

I was trying to read some messages from a tcp connection with a redis client (a terminal just running redis-cli). However, the Read command for the net package requires me to give in a slice as an argument. Whenever I give a slice with no length, the connection crashes and the go program halts. I am not sure what length my byte messages need going to be before hand. So unless I specify some slice that is ridiculously large, this connection will always close, though this seems wasteful. I was wondering, is it possible to keep a connection without having to know the length of the message before hand? I would love a solution to my specific problem, but I feel that this question is more general. Why do I need to know the length before hand? Can't the library just give me a slice of the correct size?
Or what other solution do people suggest?
Not knowing the message size is precisely the reason you must specify the Read size (this goes for any networking library, not just Go). TCP is a stream protocol. As far as the TCP protocol is concerned, the message continues until the connection is closed.
If you know you're going to read until EOF, use ioutil.ReadAll
Calling Read isn't guaranteed to get you everything you're expecting. It may return less, it may return more, depending on how much data you've received. Libraries that do IO typically read and write though a "buffer"; you would have your "read buffer", which is a pre-allocated slice of bytes (up to 32k is common), and you re-use that slice each time you want to read from the network. This is why IO functions return number of bytes, so you know how much of the buffer was filled by the last operation. If the buffer was filled, or you're still expecting more data, you just call Read again.
A bit late but...
One of the questions was how to determine the message size. The answer given by JimB was that TCP is a streaming protocol, so there is no real end.
I believe this answer is incorrect. TCP divides up a bitstream into sequential packets. Each packet has an IP header and a TCP header See Wikipedia and here. The IP header of each packet contains a field for the length of that packet. You would have to do some math to subtract out the TCP header length to arrive at the actual data length.
In addition, the maximum length of a message can be specified in the TCP header.
Thus you can provide a buffer of sufficient length for your read operation. However, you have to read the packet header information first. You probably should not accept a TCP connection if the max message size is longer than you are willing to accept.
Normally the sender would terminate the connection with a fin packet (see 1) not an EOF character.
EOF in the read operation will most likely indicate that a package was not fully transmitted within the allotted time.

How to manage multi-packet sends with gsocket?

I got a question regarding tcp/ip socket networking. Basically it is there: are there any parts of tcp/ip that I can leverage to help manage multi-packet sends. For example, I want to send a 100 mb binary file which would take something like 70-80 tcp packets. Meanwhile I have a relatively fast polling receive on the other side. Would my receive have to receive each packet it individually and "stitch" together the data packet by packet, looking for some size to be reached(it can look at the opcode and determine size) or is there some way to tell tcp to say "hey I'm sending 100 mb here, let them know when it is finished."
I am using glib's low level socket library (gsocket).
When using a binary encoding like, say protocol buffers, you would wrap the actual payload by inserting a header that would include the information necessary to decode the payload on the other end.
Say appending 8 bytes where the first 4 signify the type of the encoded message and the second four indicate the length of the entire message.
On the receiving side you are then reading this header, that's part of the payload, to determine the message type and length of the message. This lets you combine multiple messages in one payload or split messages across packets and reliably recombine them.

Resources