Search code examples
pythonc#tcpbitconverter

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


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);

Solution

  • 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.