Sending integer with Python TCP socket and receiving with C# - Error receiving correct data

39 Views Asked by At

I am new to TCP sockets and am trying to use Python (server) to send the size of an encoded image (an integer) with TCP sockets. A C# Winforms application (client) is used to receive this integer but the received int looks to be very random. For example, if the encoded image is 6570, the C# app receives 808924470

The Python code (sender):

## Connection code...

# Send image size
imageSize = len(encodedImage)
socket.send(str(imageSize).encode("utf-8"))

The C# code (receiver):

// Connection code...

// Receive int
byte[] buffer = new byte[1024];
int bytesReceived = stream.Read(buffer);
int imageSize = BitConverter.ToInt32(buffer, 0);
1

There are 1 best solutions below

2
Marc Gravell On BEST ANSWER

The python code is sending the value as UTF string data, i.e. 6570 will be the bytes (as hex) 36-35-37-30. You need to decode this as such.

The most efficient approach would be, for example:

var bytes = new byte[] { 0x36, 0x35, 0x37, 0x30 };
if (System.Buffers.Text.Utf8Parser.TryParse(bytes, out int value, out int bytesUsed))
{
    Console.WriteLine($"Read {value} from {bytesUsed} bytes");
}

(you could also use Encoding.UTF8 to parse the bytes to a string, then int.Parse to process that string to an int; Utf8Parser is designed to skip the intermediate string)

However, you'd also want to consider "framing"; TCP is a stream protocol, not a message protocol. It is not sufficient to just call Read - that could be half a message (just the 65), an entire message, or 57 entire messages and half of the 58th. For a text protocol, something involving line breaks is common.


For completeness (to understand what the existing code is doing), BitConverter.ToInt32 is performing a CPU-endian "pun" (reinterpret-cast) of the bytes to raw integers; since your CPU is most likely little-endian, this is the integer 0x30373536 (remember the UTF8 bytes were hex 36-35-37-30, and little-endianness reverses the perceived byte order), aka the decimal 808924470.