Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > C/C++: Сетевое программирование > Отправка структуры по TCP (protobuf) - C Linux


Автор: maxim1988 09.02.16, 08:18
Здравствуйте
Суть вопроса
Есть задание обмена сообщения между сервером и клиентом сообщения сериализуются/десереализуются при помощи protobuf
собственно сама вопрос как отправить по TCP сериализованное сообщение а на другой стороне его же и извлечь?
вот так вот сериализую и отправляю
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    AMessage msg = AMESSAGE__INIT;
        void *buf;                    
        unsigned len;
     
        msg.stroka="message from the client";
        msg.t = 3;
        msg.dlinastroki = strlen(msg.stroka);
        fprintf(stderr,"PARAMETRS %d %s %d\n",msg.t,msg.stroka,msg.dlinastroki);
        len = amessage__get_packed_size(&msg);
        buf = malloc(len);
        amessage__pack(&msg,buf);
        fprintf(stderr,"Writing %d serialized bytes\n",len);
    if (send(sock, buf,len, 0) != len)
            DieWithError("send() sent a different number of bytes than expected");


вот так вот принимаю и распаковываю

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    AMessage *msg;
       uint8_t buf[MAX_MSG_SIZE];
    size_t msg_len =sizeof(MAX_MSG_SIZE);
        if ((recvMsgSize = recv(clntSocket, buf,msg_len, 0)) <msg_len)
            DieWithError("recv() failed");
      
       // size_t msg_len =sizeof(MAX_MSG_SIZE);
        printf("recover 1\n" );
        msg = amessage__unpack(NULL, msg_len, buf);
     
        printf(" stroka=%s\n",msg->stroka);

но код не работает
есть ощущение что сообщение отправляется все таки но не извлекается при извлечении появляется вот такая ошибка
data too short after length-prefix of 23
make: *** [serv] Segmentation fault (core dumped)

Автор: ter_nk_ 09.02.16, 18:34
Так сразу

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    size_t msg_len =sizeof(MAX_MSG_SIZE);


это переменная или define

Сначала вытащи это в стандартный вывод или файл.

Добавлено
Это к то что размер принимаемых данных 4 максимальный

Автор: maxim1988 10.02.16, 03:26
ter_nk_да вы правы с define разобрался это я затупил
но проблемы это не решило

Автор: Oleg2004 10.02.16, 10:13
Цитата maxim1988 @
есть ощущение что сообщение отправляется все таки

Странная для программиста новая категория - "ощущение" :)
Практически любой сниффер позволит вам точно определить, что пришло, когда и сколько.
Кстати, вот здесь есть очень хороший пример использования protobuf для клиент/серверного приложения.

Автор: maxim1988 11.02.16, 04:02
Oleg2004есть ощущение просто к слову пришлось
wireshark показывает что все отправляется но извлечь не выходит

Добавлено
Oleg2004ну и да пример плюсовый мне нужен на чистом си
понимаю что можно сделать по аналогии но в плюсах я не силен вообще

Автор: Oleg2004 11.02.16, 09:55
Цитата maxim1988 @
мне нужен на чистом си
понимаю что можно сделать по аналогии но в плюсах я не силен вообще

Не надо сразу сдаваться. :no:
Сейчас примеры на чистом Си найти можно разве только что в книжках.
В том примере нет ни классов, ни наследования и всего прочего. Пара тройка может быть пока непонятных моментов - почитайте и все станет на свои места. Основная логика ведь не языком определяется. А сокетные операции - так они вообще чисто сишные.
Потратьте пару часов - и все будет ОК! :)
Цитата maxim1988 @
wireshark показывает что все отправляется но извлечь не выходит

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

Автор: ter_nk_ 11.02.16, 09:59
Цитата Oleg2004 @
Надо попробовать сделать и то и другое просто на одной машине без пересылки по сети.


Так и я же говорю - файл и сравни два файла.

Автор: Oleg2004 11.02.16, 10:02
Цитата ter_nk_ @
Так и я же говорю - файл и сравни два файла.

Я позволил себе вашу мысль изложить более системно... :)

Автор: maxim1988 12.02.16, 08:06
в общем во всем разобрался все сделал всем спасибо за помощь если кому интересно могу скинуть код

а вообще все задание выглядело вот так

Нужно написать сервер и 2 типа клиента.
На сервере работает синхронизированная очередь из N сообщений. Идет прием сообщений и отправка клиентам одновременно по TCP протоколу.

Если очередь не заполнена, то сервер каждые K секунд посылает UDP пакет "Жду сообщений" в локальную сеть. Если клиент 1-го типа получает этот пакет, то отправляет по TCP сообщение (время T обработки сообщения, длина случайной строки, случайная строка) . После отправки сообщения клиент засыпает на время T. Строка случайной длины и время T - генерируется случайно, максимальная длина строки и интервал времени задается через константы. Как только очередь заполняется, то сервер перестает слать UDP оповещение.

Если в очереди есть сообщения, то сервер посылает каждые L секунд UDP пакет "есть сообщения" в локальную сеть.
Клиент 2-го типа получив такой UDP пакет устанавливает соединение с сервером и получает по TCP от сервера сообщение со строкой. Обрабатывает T секунд(просто спит) и только после сможет опять получать сообщения. Как только очередь опусташается, то сервер перестает слать UDP оповещение.

Кол-во клиентов 1-го и 2-го типа может быть неограниченно.
Реализовать сервер и клиенты на языке С. Использовать компилятор gcc. Стандарт языка С99. Результаты выкладывать на git сервер http://bitbucket.org.
Допускается написание сервера на Java, а клиенты на С.
Для упаковки и распаковки сообщения между клиентами и сервером использовать библиотеку protobuf-c.
https://github.com/protobuf-c/protobuf-c

Автор: vanass 16.06.17, 07:22
Да хотелось бы исходники плсмотреть,интересно

Добавлено
maxim1988поделишься?

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)