When I send a packet via tcp, it splits into two packets

I am developing a C # application using the server-client model, where the server sends a byte array with a bitmap on the client, the client loads it onto the screen, sends "OK" to the server and the server sends another image, etc.

The length of the image buffer depends on the level, usually from 60 to 90 kb, but I saw that it does not matter. If I put the client and server on the same computer using localhost, everything will be fine. The server starts SendSend, and the client does endReceive, and the entire buffer is sent.

However, now I am testing this on a wireless network, and the following happens:

  • The server sends the image.
  • The data_received callback function is called on the client, but only read 1460 bytes (MTU - why? Should it be not only in UDP?)
  • The data_received callback function on the client is called again, now with the rest of the buffer (either 1000 bytes or 100 kilobytes) ...

This is always the case, the first packet with 1460 bytes is received, and then the second packet contains the rest.

I can get around this by combining both byte arrays, but this seems wrong. I don’t even know why this is happening. Is this some kind of network restriction? Why does C # not wait until all the data has been transferred? I mean, this is TCP, I don't need to worry about that, right?

Anyway, any help would be great!
Greetings

+6
c # tcp mtu packets
source share
3 answers

This is TCP - you must treat the data as a stream. You don't care how the stream is packetized or make assumptions about it.

If you need to get one “block” of data, the easiest way to do this reliably is to prefix its length (for example, as a 32-bit value). You read the length (noting that even these bytes can be divided into several packets) and then read it again (whether synchronously or asynchronously), taking into account how much you read each time until you read all the data.

+14
source share

Read 9.2.4

When analyzing an application-level protocol, you cannot assume that each TCP packet contains exactly one application-level message. One application-level message can be divided into several TCP packets.

+5
source share

adding to John the answer:

int offset = 0; int imagesize = 512; byte[] buffer = new byte[512]; tcpChannel.Read(buffer, offset, imagesize); 
0
source share

All Articles