12-19-2023 07:36 AM
I am transmitting three TCP messages from a RT application to a Windows application at 1 Hz. From time to time, the largest of the three messages takes 2 or even 3 messages to come in. That is not because it is larger than other messages like it. I don't know how the network adapters determine how much to package, but I would like it to go out at one message. Is this possible?
Sometimes the message is even conflated with one of the other messages because it is buffered and one of the other messages gets attached to it. I realize I can do a better job of parsing it on the Windows side, but I want to see if I can clean it up on the transmit side first.
Below I have bolded the start and end of the DATA message and the CONTROLS message. You can see the second chunk of the DATA message and the CONTROLS message are sent together as one.
08:17:10 Received partial DATA message
DATA 36 0 0 14.2792 -0.2902 1.83 0.00 14.0 0.001 4.5 0.0 2.0 0.1 5.0 10.0 0.4 4.5 0.3 5 -0 24.4 22.6 15.9 18.2 19.9 14.8 15.4 16.8 16.2 17.1 13.7 17.3 14.7 15.6 16.5 16.1 16.7 15.4 15.0 15.3 15.6 16.5 15.9 16.2 16.1 14.5 15.4 15.3 15.7 15.6 15.3 15.5 15.5 15.7 15.6 15.3 15.4 -0.3 -0.2 0.03 0.4 -37.6 -4.7 0.1 -0.032 -2.8 386.0 -0.3 0.02 -0.07 0.01 5.8 0.00 0 194.7 99.0 0 25.0 -1.0 481.5 170.9 0.0 0.0 0.0 0.0 100.0 0.0 0.0 15.0 9.1 1.0 1000.0 0 0 0.0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 0.0 0 1.0 0.0 0.0 0 32.0 125.0 0 0.0 1 1.0 0.0 0.0 25.0 0.000 6.52 65.0 170.5 0.0 0.0 585.0 96.6 0.0 0.0 0.000 0.0 0.000 0.000 0.000 0.000 0.0 0.0 0.0 1.000 1.000 0.232 0.000 0.0 3.39 3.39 0.00 0.00 200.00 0.00 0.0 1 0 0 257 32 1156.0 1.2 0.000 1 65.0 16.0 96.60 0.00 2.00 2.00 6.52 0.00 0.00 0.00 1.86 0.00 0.30 0.00 0.00 0.00 0.00 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 50.00 0.00 0.0 98.98 108.81 -1.00 0.00 17.59 18.04 0.0 0.000 6.52 0.00 0.0 0.0 0.803 26.0 1.157 99.0 25.00 0.00 -1.0 108.80 49.20 0.00 0.00 6.52 6.52 200.00 15.91 0.00 0.0 0.0 7841503.5 -6.7 0.0 -0.05 -0.02 0.0 0.00 0.00 0.000 0.42 -0.03 18.2 0.0 0.0 0.0 0.0 0.0 0 1 0 2 1.8 0.0 4672606.0 0.0 0.00 0.0 0.0 -1 0.0 0.0 92.4 0 0.0 0.00 0.0 67.6 97.2 98.7 -5 97.2 0 67.6 1 529 0 3.0 3.0 0.0 0.00 0.00 0.00 2.00 0.00 0 0.00 0.0 0.00 13.69 0.00 7841502.0 0.0 0.0 0.0 0.0 0.0 0.0 41.8 0.00 0.00 24.20 5.40 0.00 24.20 0.0 -8.1 -7.8 0.49 1.0 0.0 0.00 0.0 0.00 65.0 0 2.0 65.0 23.0 0.0 0.0 0.0 1.0 0.10 0.0 0.00 0.0 0.0 0.0 0.0 0.00 0.90 65.00 1.6 100.00 1.0 1.0 0.4 0.8 1.0 0.0 19.51 0.00 0 0.00 8.78 152.17 1 0.0 -100.00 0 0 0 1 0 -0.05 0 1 1 0 -0.02 0.38 0.0 0.0 419
08:17:10 Received partial DATA message
.03 0.00 87.4 0.0 9392.9 0.0 584.5 4.0 65.0 300.0 65.0 0.00 0.00 0.00 0.0 0.0 101.0 0.0 0.0 -1.0 0.0 0.00 0.00 0.0 0.0 0.0 0.0 0.00 0.0 0.0 67.6 0.00 0.00 0.00 0.00 0.00 0.00 0.0 1657.0 0.00 1.0 0.00 0.0 -0.34 19.6 0.0 0.0 17.1 16.3 15.6 16.4 15.6 301990400.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.00 1.0 0.0 1.0 1.0 0.0 0.00 0.001 0.00 1.0 0.0 0.0 0.0 -6.0 0.0 99.0 98.7 -0.34 25.0 17.1 16.3 15.6 17.1 16.4 15.9 0.00 0.00 0.0 0.00 0.0 700.0 1.0 16.5 0.1 0.0 0.000 0.000 0.000 0.00 0.0 0.0 15.9 0.1 0.0 0.6 0.8 5.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.00 0.00 0.00 0.00 0.00 60.00 0.00 60.00 0.00 60.00 60.00 0.00 0.0 0.2 0.0 15.9 0.2 0.000 0.1 0.0 0.64 0.000 0.0 0.0 0.0 3.1 0.0 -9.0 -3.0 0.0 0.0 0.0 0.0 1.0 4.970 0.0 0.0 0.0 0.8 0.00 0.00 0.04 0.04 45.45 0.0 0.4 450.0 0.00 0.0 1 0 0.00 0.00 58.0 0.0 569.9 0.0 0.0 0.0 0.000 0.000 0.000 0.0 0.0 0.0 0.00 65.0 1.0 5.4 0.0 65.0 0.0 1.0 0.10 4.9 0 0.0 16.2 23.1 0.000 0 0.000 0.000 0 0 0 100.0 0.000 1 0 3076 21.68 -438.2 -31.5 0.72 99.35 -0.11 0.00 0.0 0.0 9.0 -31.4 1304.5 0.000 0.0 1.904 1.012 0.986 0.018 21.70 73.4 1.83 0 0.01 11.37 0.0 0.0 0.1 4.6 1.4 -0.007 0.07 10316.9 20.4 892.0 0.00 661.5 29.7 876.0 0.00 0.0 0.0 0.0 0.0 -59.3 100703.0 483.4 491.1 0.8 0.7 1.6 -16.4 SREM SPAU 12429 24.00 15.70 59.83 99.35 0.00 21240.36 7920.78 4750 27700 800.00 0.00 800.00 413600.00 0.80 0.0000 0.00000 0.00 0.80 1 0.00 0.00 0.00 33165.00 1.50 0.0010 0.00001 0.00 1.83 1 38.00 14.66 23.35 0.00 6.00 -0.1500 -0.01000 0.00 5.00 1 85.00 16.78 68.22 0.00 6.00 -0.5000 -0.03000 0.00 2.00 1 20.00 13.72 6.28 0.00 4.00 -0.3000 -0.05000 0.00 2.00 1 32.00 18.22 13.78 0.00 6.00 -0.3000 -0.05000 0.00 10.00 1 35.00 15.41 19.60 0.00 6.00 -0.1000 -0.02000 0.00 4.00 1 38.00 16.50 21.50 0.00 6.00 0.0000 0.00000 0.00 6.00 1 0.00 15.40 0.00 0.00 0.00 0.0002 0.00005 0.00 0.00 0 0.00 14.97 0.00 0.00 4251.00 -40.0000 -30.00000 0.00 4251.00 0 0.00 14.97 0.00 0.00 28600.00 0.0000 0.00000 0.00 28600.00 0 17225 0 0 0 0 231218 081708
CONTROLS_800.0 0.0 800.0 0.799 0.000 0.000 0.000 0.799 419200.0 _0.0 0.0 0.0 1.500 0.000 0.332 0.000 1.832 33165.0 _38.0 14.6 23.3 6.000 -3.502 0.000 0.000 5.000 0.0 _85.0 16.8 68.2 6.000 -34.109 0.000 0.000 2.000 0.0 _20.0 13.7 6.3 4.000 -1.885 0.000 0.000 2.000 0.0 _32.0 18.2 13.8 6.000 -4.135 0.000 0.000 10.000 0.0 _35.0 15.4 19.6 6.000 -1.960 0.000 0.000 4.000 0.0 _38.0 16.5 21.5 6.000 0.000 0.000 0.000 6.000 0.0 _0.0 15.4 0.0 0.001 0.000 0.000 0.000 0.001 0.0 _0.0 15.0 0.0 4251.000 0.000 0.000 0.000 4251.000 0.0 _0.0 15.0 0.0 28600.000 0.000 0.000 0.000 28600.000 0.0 _END
12-20-2023 06:54 AM
Looks like you are transmitting floating point data...
What format are you transmitting - Float or Double or something that is converted using integers and a scaling factor?
What size are your control and data packets -- are they a fixed format of N elements or variable sized?
12-20-2023 07:26 AM
Everything is converted to ASCII. The number of parameters are fixed, as is their formatting, so the length of the string should be very similar if not the same every time. Sometimes I get the first message and it is only ~8 numbers. Other times it could be half of the message. It is random. Right now I am working on parsing it better by taking the substring that starts at 0 and ends at the index before CONTROLS or SAFETIES. I can stand to lose a CONTROLS message or SAFETIES message because they are just displayed on the screen. I don't want to lose the DATA message because the data goes to SQL at 1 Hz. Each time I drop a data message I lose a row of data.
12-21-2023 03:33 AM - edited 12-21-2023 03:45 AM
TCP is a streaming protocol, not a datagram protocol. It means that it guarantees that all bytes arrive in the same order than how they were sent, but it does not guarantee that the messages chunks are arriving in the same size than what they were send. The basic principle of TCP is that parts of the message could get routed over a relay in Singapore and other parts could go through a relay in the town next to you. In the end the TCP stack will make sure that the data arrives at your application in the same exact order as it was send or not at all, if some packages got lost and didn't arrive even after several retry requests.
Consider it similar to a binary file. It doesn't really matter if you wrote the file in 1000 little chunks of 100 byte each or in 10 chunks of 10000 bytes each. You can later read it in 50 chunks of 2000 bytes each, or in 1 chunk of 100000 bytes. The only thing that a stream guarantees is that the total size of the stream is known and that every byte in the stream stays in the same order as it was sent/written.
That is very different for UDP. Here messages are sent in datagrams. UDP only guarantees that a datagram arrives consistently at the receiving end if it is smaller than the smallest MTU in the communication chain. That is why UDP typically is limited to 512 or so bytes, anything bigger has a chance to be cut up in smaller pieces on intermediate gateways and not arrive or not arrive completely.
If your stream is not a consecutive stream of bytes and you want to have some framing structure in it, you need to provide that mechanism in the data stream yourself. There is simply no reliable way to get TCP/IP to deliver you messages in exactly the same size as what you send them off. Even if the devices are connected directly together without any gateways, routers or more complex devices in between, there is no guarantee that blocks of data arrive in exactly the same sized chunks as they were sent off. A TCP/IP stack has the freedom to process things in different sized chunks if it finds that more useful for memory or performance reason. The only thing it needs to guarantee is that the bytes in the stream are handed to the application in exact the same order as they were sent, or to produce an error indicating that data could not be transported consistently. Theoretically some of the bytes in your data stream could be routed over the moon and take several seconds before they arrive at the other end, while other parts of your stream my be routed directly. It's all within the specifications of TCP/IP, although this extreme example is unlikely, but if you consider that telecommunication channels can go through satellites you still have potentially significant delays for data, and some of your data may go over satellite and other may go through a sea cable. TCP/IP was designed to be a highly reliable transmission channel rather than a super fast one and data streams can be routed over very different channels if the network decides that a particular channel momentarily is unreliable or cut off.
You could make this sort of work, if you are using rather slow communication speeds. As long as your timeout on the reading side is significantly smaller than the interval in which you send messages, you can sort of do what you want at least if your data doesn't go over routers or similar smart devices that can do all kind of repackaging. However you can't make the timeout to small or you risk only receiving parts of a message.
Much more robust is to actually integrate the size of your messages into your protocol. Then you only have to make sure to initially synchronize somehow, read the message header with the integrated size and then read the indicated amount of data. As long as both sides adhere to this protocol your data is both guaranteed to be in proper sequence (thanks to TCP/IP) and in proper message chunks (thanks to your protocol provision).
12-21-2023 02:54 PM
That's what I figured. I'll just have to make sure my TCP receive callback does a good job of parsing the messages. My changes did great last night until the issue below happened in the event viewer, but that's not an issue for this forum.