Вам следует изменить способ получения данных:
void Helper::getPartFromSocket(SOCKET sc, char* buffer, size_t bytesNum, int flags);
вместо внутреннего создания массива.Тогда вы можете сделать:
uint8_t Helper::getCode(SOCKET sc)
{
uint8_t code;
getPartFromSocket(sc, reinterpret_cast<char*>(&code), sizeof(code), 0);
return code;
}
uint32_t Helper::getLength(SOCKET sc)
{
uint32_t length;
getPartFromSocket(sc, reinterpret_cast<char*>(&length), sizeof(length), 0);
return length;
}
std::string Helper::getString(SOCKET sc, size_t length)
{
std::string s(length, 0);
getPartFromSocket(sc, s.data(), length, 0);
// possible since C++17 ^
return s;
}
т.е. вы записываете данные непосредственно туда, где они должны быть размещены.В то же время вы решаете проблему утечки памяти ...
Проблема остается с порядком байтов ... Вы, очевидно, пишете байты с прямым порядком байтов на стороне Python, но, как показано выше, вы (скорее всего - этозависит от машины, но машины с прямым порядком байтов в наши дни становятся очень редкими ...)Чтобы получить независимость от порядка байтов машины на стороне C ++, вы также можете изменить код следующим образом:
uint32_t length = 0
for(unsigned int i = 0; i < sizeof(length); ++i)
{
uint8_t byte;
getPartFromSocket(sc, reinterpret_cast<char*>(&byte), sizeof(byte), 0);
// little endian tranmitted:
// length |= static_cast<uint32_t>(byte) << 8*i;
// big endian transmitted:
length |= static_cast<uint32_t>(byte) << 8*(sizeof(length) - (i + 1));
// simpler: just adjust loop variable; = 1, <= sizeof ^
}
return length;
Редактировать: некоторые замечания из комментариев, так как они были удалены:
Ну, на самом деле, уже есть функция, выполняющая такие вещи: ntohl
(спасибо, WhozCraig , за подсказку), так что вы можете получить ее намногопроще:
uint32_t length;
getPartFromSocket(sc, reinterpret_cast<char*>(&length), sizeof(length), 0);
return ntohl(length);
Еще одна проблема, обнаруженная во время обсуждения, на этот раз на стороне Python:
sock.send((msg.encode()))
encode
по умолчанию доставляет строку, кодированную utf-8
, что, конечно, нечто мы хотим в этом случае (200 будет преобразовано в два байта).Вместо этого нам нужно использовать кодировку локальной машины (на хосте Windows, вполне вероятно, cp1252 для западной Европы или cp1250 для центральной и восточной Европы).