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