Попытка отправить вектор через TCP - PullRequest
0 голосов
/ 14 марта 2019

Я пытаюсь отправить получающий и многомерный вектор с tcp в c ++, но я продолжаю получать ошибку сегментации.Я пытаюсь отправить один вектор за раз вместо отдельных целых чисел, чтобы уменьшить задержку.Мне было интересно, как я должен сериализовать и десериализовать вектор (без каких-либо библиотек, таких как Boost)

Сервер:

vector< vector<int> > contours = { {3,6,8}, {7,24,64}, {87,399} };
int len = 3;
int size =0;

while(waitKey(10) != 'q')
{      

    send(new_socket, &len, sizeof(int),0); //send size of vector 

    for(int i =0; i< len; i++){

        size = (contours[i].size() * sizeof(int)) + 24; //byte amount to send and receive

        send(new_socket, &size, sizeof(int), 0);
        send(new_socket, &contours[i], size, 0);
    } 
}

Клиент:

vector< vector<int> >contours;
vector<int> lines;
int contoursize =0;
int size =0;

while(waitKey(100) != 'q'){

    read(sock,&contoursize, sizeof(int));
    contours.resize(contoursize);

    for(int i =0; i< contoursize; i++){
        read(sock, &size, sizeof(int));


         cout<<" size: "<<size<<endl;

        read(sock, &lines, size);
        contours[i]= lines;
    }
}

1 Ответ

1 голос
/ 14 марта 2019

С send(new_socket, &contours[i], size, 0) вы отправляете фактический std::vector объект в contours[i], вы не отправляете его данные. И std::vector объект - фактически просто обертка вокруг указателя и размера. И вы не можете отправлять указатели по сети.

Вам необходимо отправить фактические данные каждого вектора:

for (auto const& sub_vector : contours)
{
    // First send the number of elements
    uint32_t number_elements = sub_vector.size();
    send(new_socket, &number_elements, sizeof number_elements, 0);

    // Then send the actual data
    send(new_socket, sub_vector.data(), sub_vector.size() * sizeof sub_vector[0], 0);
}

[Проверка ошибок опущена, но она действительно должна быть.]

Я также рекомендую не использовать тип, подобный int, так как его размер на самом деле не фиксирован. Если вы хотите 32-разрядные целые числа без знака, используйте uint32_t. Конечно, вы можете использовать int внутри вашей программы и конвертировать данные в переносимый тип фиксированного размера для передачи, если принимающая сторона может выполнить обратное преобразование.


Кроме того, я рекомендую вам также отправить количество субвекторов, которые вы хотите отправить, чтобы получающая сторона знала это заранее:

uint32_t number_vectors = contours.size();
send(new_socket, &number_vectors, sizeof number_vectors, 0);

for (...) { ... }

На принимающей стороне вы можете сделать что-то вроде

// Receive the number of sub-vectors
uint32_t number_vectors;
recv(sock, &number_vectors, sizeof number_vectors, 0);

// Create the vectors
std::vector<std::vector<int>> contours(num_vectors);

// Read all sub-vectors
for (auto& sub_vector : contours)
{
    // Receive the amount of values
    uint32_t number_elements;
    recv(sock, &number_elements, sizeof number_elements, 0);

    // Create the sub-vector
    sub_vector = std::vector<int>(number_elements);

    // Receive the sub-vector data
    recv(sock, sub_vector.data(), sub_vector.size() * sizeof sub_vector[0], 0);
}

[Примечание: Опять проверка ошибок опущена, но она действительно должна быть там.]

...