Hello B&R community!,
I’m looking for some help regarding an issue which I have when using TcpRecv function block. I implemented TcpIp communication between AR and 3rd party tcp server, which is running on the same APC under windows (we use hypervisor). The connection is established via ETHInternal port and the PLC side is tcp client only.
I noticed that sometimes the TcpRecv buffer contains two tcp packets joined together.
This behavior is something I have not expected. My question is if TcpRecv should work this way or I encountered a bug?
I reproduced this behavior with two PLCs and I did wireshark trace to make sure that two separate tcp packes are sent:
One PLC acts as tcp server and sends two tcp packets and waits 100ms, then it repeats the sequence.
On the client PLC, TcpRecv is called cyclically in 2ms task class (enable=1 all the time). Most of the frames are received properly → TcpRecv returns 0 twice and two separate packets can be parsed:
Unfortunately, sometimes TcpRecv returns 0 only once and the buffer contains two tcp packets joined together.
vs
Does anyone have any suggestions or idea if this is intended TcpRecv behavior?
Thanks in advance for your help!
Hello Jacek Walkowski,
Welcome to B&R community, I’m quite sure that the TCP/IP protocol does not guarantee that length of each send() and each receive() be the same, it only guarantee that the byte stream will be transmitted in the right order without error (and total amount of the data sent will be the same as received). The TCP/IP is not and deterministic protocol.
Hi Wenbo,
thanks for response. I agree that TCP/IP is not a deterministic protocol. But, each Tcp packet can be clearly distinguished from the others in the tcp/ip network, so in my opinion, TcpRecv should be able to receive packet by packet from some kind of internal system buffer.
I can confirm that this is not a bug, but a normal behavior.
TCP is a connection-oriented streaming protocol, that ensures the reception of data in the right order.
Since a TCP stream does not have a “dedicated packet size”, depending on the senders and receivers timing it can happen that you get more then one “data packet” with one call which is a normal behavior.
If you want to influence that behavior, you can try:
run the receiver task much faster then the sender task
change the socket buffer size of the receiver TCP socket to the wanted value (but be aware, that this could have other negative influence to your communication) - this can be done by TcpIoctl function block.
while I agree with what has been said previously (not to distinguish between packets) I want to suggest not relying on the Transport Protocol, but to put an Application protocol on top. Simplest form would be to indicate the start and end of your data with unique characters / bytes that are distinct from the actual data. That way you don’t parse packets but append all received data to a buffer until you found start and end - and then parse that and use it.
E.g. *here is my data#
The length can then also vary - or if it shouldn’t, it can be checked after the fact.
Hi Jaroslav,
all answers were very helpful, especially Alexander’s post.
I had to rework my program to look for specific start/end characters. With this approach, my program either gets a single packet from the buffer or waits for the missing packet’s part.
Thanks everyone for your contribution!