Как передать длину данных по tcp (python)

Есть сервер на C#, который читает сообщение от клиента вот так:

private string ReadMessageWithPrefixLength()
{
    var length = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(ReadBytes(sizeof(int)), 0));
    return Encoding.UTF8.GetString(ReadBytes(length));
}

private byte[] ReadBytes(int size)
{
    var buffer = new byte[size];
    int alreadyReadCount = 0;

    while (size - alreadyReadCount > 0)
    {
        var read = stream.Read(buffer, alreadyReadCount,   size - alreadyReadCount);
        if (read == 0)
            throw new EndOfStreamException();
        
        alreadyReadCount += read;
    }

    return buffer;
}

И есть клиент на питоне, который должен отправить сначала длину сообщения, а потом и само сообщение:

sendMessage = "message"
socket.send(len(sendMessage).to_bytes(2, "big"))
socket.send(sendMessage.encode())

Каждый раз, когда я пытаюсь прочитать длину сообщения на сервере, я получаю отрицательное (или наоборот слишком большое) значение. Что я делаю не так?


Ответы (1 шт):

Автор решения: CrazyElf

Скорее всего проблема в том, что sizeof(int) - это 4 байта (на что вам также намекает название функции ToInt32 - это 32 бита в стандартном int). А передаёте вы длину, используя 2 байта в .to_bytes(2, "big").

В общем, вы лишних 2 байта из потока читаете и потом 2 байта от настоящей длины и ещё 2 байта уже от самого сообщения вместе слепляете и пытаетесь в int преобразовать. Если уж вы на передающей стороне явно указываете число генерируемых байт в передаваемой длине сообщения, то и на принимающей стороне делайте это также явно: ReadBytes(2). Также можно использовать ReadBytes(sizeof(short)), но на мой взгляд лучше делать единообразно.

→ Ссылка