Winsock отправка массива типа vector

216
16 апреля 2019, 12:20

Имею такую матрицу vector<vector<float>> matrix n-го размера. каким образом ее передать через сокеты на сервер. Вектор используется, потому что создать обычный массив float n-го размера нельзя. Есть реализация сделанная мною, она передает каждый элемент по отдельности через send(), но данный процесс слишком долог. В интернете не нашел ничего толкового. Заранее благодарен всем кто откликнется

Answer 1

Есть много способов. самый простой - передавать вектора - вектор это непрерывная структура, поэтому, можно передать размер вектора и потом весь вектор.

схематически.

// отправим размер вектора
vector<vector<float>> v;
send(v.size(), sizeof(v.size()));
// в цикле отправляем каждый кусочек, с размером и данными
for (auto& x : v) {
  send(x.size(), sizeof(x.size()));
  send(x.data(), x.size()*sizeof(float));
}

send - это функция отправки. Да, там типы нужно будет аккуратно привести, но это справитесь.

На приемной стороне читается размер, потом вычитываются вложенные данные.

где то так:

vector<vector<float>> data;
size_t t;
read(&t, sizeof(t));
data.resize(t);
for (size_t i = 0; i < t; i++) {
  size_t ti;
  read(&ti, sizeof(ti));
  data[i].resize(ti);
  read(data[i].data(), sizeof(float)*ti);
}

предупреждение:

  • нет никакой проверки валидности.
  • если плаформа/компилятор отличается, то могут быть проблемы.
  • желательно добавить пару байт заголовка/концовки, что бы проверять, что данные прочитаны правильно.

Второй способ - сделать это все строкой, например, через запятую или что то вида json. А дальше все просто.

Третий способ - использовать protobuf или подобное.

Answer 2

Я пошел почти по этому пути. Так как программа считает исключительно квадратную матрицу. И мы знаем изначально количество строк = количеству столбцов. То я решил в каждой отсылке не пересылать размер строки, а пересылать непосредственно строку.

Код отправки с клиента:

bool sendMatrix(SOCKET socket, int masLength, vector<vector<float>> matrix)
{
bool result = true;
for (auto& x : matrix)
{
    send(socket, (char*)x.data(), x.size() * sizeof(float), 0);
}
return result;
}

Код на стороне сервера:

vector<vector<float>> recvMatrix(SOCKET socket)
{
vector<vector<float>> matrix;
matrix.resize(masLength);
for (int i = 0; i < masLength; i++)
{
    matrix[i].resize(masLength);
    recv(socket, (char*)matrix[i].data(), sizeof(float)*masLength, 0);
}
return matrix;
}

Параметр masLength принимается на сервере первым. Это как раз и есть количество строк. На сервере при помощи этого параметра и создаем необходимые размеры для вектора.

READ ALSO
Пять Чисел Задача C++

Пять Чисел Задача C++

Написал такой код, проходит половину тестов, из тех что не проходят - половина ограничение по времени, половина неверный ответГде в коде ошибка...

231
UB в невыполняемом коде

UB в невыполняемом коде

Содержит ли эта программа UB? Функция foo не вызывается

213
Разобрать одну строку кода

Разобрать одну строку кода

Нужно разобрать строку sum += (i / 2) ? i : 0; как работает это условие и как его заменить через оператор if

210
Исключение std::bad_alloc для 2 элементов

Исключение std::bad_alloc для 2 элементов

Почему следующая программа выбрасывает исключение std::bad_alloc?

201