send(sock, std::to_string(length).c_str(), 10, 0);
Это UB. Вы говорите, что данные имеют 10 байтов, но это не правильно. Кроме того, нет необходимости преобразовывать ваш int в строку, а затем отправлять строку. Просто отправил int, и во избежание несовместимости платформ я рекомендую использовать тип фиксированного размера:
std::int32_t length = package.length();
send(sock, &length, sizeof(length), 0);
На принимающей стороне вы должны убедиться, что вы действительно ждете, пока все байты будут там. Вы не можете просто позвонить recv
и предположить, что он дает вам все необходимые байты. Вам нужно вызвать его в цикле и проверить его возвращаемое значение, которое говорит вам, сколько байтов вы получили. Чтобы получить length
, вам нужно прочитать соответствующее количество байтов в буфер, а затем заново интерпретировать этот буфер как тип, который вы выбрали (например, std::int32_t
.
Кроме того, вы должны убедиться, что порядковый номер вашего int правильный. Это де-факто стандарт для использования данных с прямым порядком байтов для сетевых данных, но в конце концов это ваше дело. Не являются частью стандарта (afaik), но доступны на общих платформах вспомогательные функции htonl
и ntohl
, которые обозначают «хост-сеть, длинный» и «сеть-хост, длинный». Они берут и возвращают std::int32_t
, и вы можете просто использовать их, чтобы убедиться, что порядок байтов работает для обеих сторон.
Отправитель:
std::int32_t length = htonl(package.length());
send(sock, &length, sizeof(length), 0);
Получатель:
// after successfully reading all bytes for the length value into an adequately sized buffer:
std::int32_t length = ntohl(*reinterpret_cast<std::int32_t*>(buffer));