Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.77/13: Рейтинг темы: голосов - 13, средняя оценка - 4.77
3 / 3 / 0
Регистрация: 22.09.2015
Сообщений: 124

Отправка структуры по TCP (protobuf)

08.02.2016, 06:46. Показов 2721. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте
Суть вопроса
Есть задание обмена сообщения между сервером и клиентом сообщения сериализуются/десереализуются при помощи protobuf
собственно сама вопрос как отправить по TCP сериализованное сообщение а на другой стороне его же и извлечь?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
08.02.2016, 06:46
Ответы с готовыми решениями:

Protobuf-Converter: Преобразует Domain Object в Google Protobuf Message
Вот разработали Protobuf-Converter который преобразует Domain Object в Google Protobuf Message. Пример: ...

Отправка каталога по tcp/ip
Здравствуйте..Реализована передача файлов по протоколу tcp/ip. У меня вопрос..Можно ли реализовать передачу всего каталога по сети? ...

tcp отправка файла
Здравствуйте, вообщем проблема в следующем. Отправляю файл с сервера на клиент, байты все доходят, файл создается все как надо, отправил...

5
3 / 3 / 0
Регистрация: 22.09.2015
Сообщений: 124
09.02.2016, 11:18  [ТС]
вот так вот сериализую и отправляю
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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");
вот так вот принимаю и распаковываю
C
1
2
3
4
5
6
7
8
9
10
11
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)
0
курлык-курлык
 Аватар для Max Patsy
87 / 96 / 8
Регистрация: 26.11.2009
Сообщений: 396
Записей в блоге: 1
09.02.2016, 11:26
Если можно, то исходник клиента и сервера в студию. Не видя функций, сложновато понять что-то
Скорей всего где-то утечка памяти, ибо сегфолт, но все равно надо смотреть
0
3 / 3 / 0
Регистрация: 22.09.2015
Сообщений: 124
09.02.2016, 12:00  [ТС]
Max Patsy, код выше

Добавлено через 4 минуты
клиент
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include <stdio.h>      /* for printf() and fprintf() */
#include <sys/socket.h> /* for socket(), connect(), send(), and recv() */
#include <arpa/inet.h>  /* for sockaddr_in and inet_addr() */
#include <stdlib.h>     /* for atoi() and exit() */
#include <string.h>     /* for memset() */
#include <unistd.h>     /* for close() */
#include <sys/shm.h>
#include "amessage.pb-c.h"
#define RCVBUFSIZE 32   /* Size of receive buffer */
#define N 10 
 
void DieWithError(char *errorMessage);  /* Error handling function */
 
int main(int argc, char *argv[])
{
    int sock;                        /* Socket descriptor */
    struct sockaddr_in ServAddr; /* Echo server address */
    unsigned short ServPort;     /* Echo server port */
    char *servIP;                    /* Server IP address (dotted quad) */
    char *String;                /* String to send to echo server */
    char Buffer[RCVBUFSIZE];     /* Buffer for echo string */
    unsigned int StringLen;      /* Length of string to echo */
    int bytesRcvd, totalBytesRcvd;
    //char message[]="random string from the client";   
 
    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); // See the length of message
     //fwrite(buf,len,1,stderr); // Write to stdout to allow direct command line piping
    if (argc < 3)   
    {
       fprintf(stderr, "Usage: %s <Server IP>  [<Echo Port>]\n",
               argv[0]);
       exit(1);
    }
    servIP = argv[1];             
         //String = message;
        ServPort = atoi(argv[2]); 
      if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
        DieWithError("socket() failed");
 
    memset(&ServAddr, 0, sizeof(ServAddr));     
    ServAddr.sin_family      = AF_INET;             
    ServAddr.sin_addr.s_addr = inet_addr(servIP);   
    ServAddr.sin_port        = htons(ServPort); 
 
   
    if (connect(sock, (struct sockaddr *) &ServAddr, sizeof(ServAddr)) < 0)
        DieWithError("connect() failed");
while (1)
    {
    //StringLen = strlen(String);      
 
    sleep (2);
    if (send(sock, buf,len, 0) != len)
        DieWithError("send() sent a different number of bytes than expected");
    totalBytesRcvd = 0;
    printf("\nReceived: ");             
   /*while (totalBytesRcvd < StringLen)
    {
        if ((bytesRcvd = recv(sock,Buffer, RCVBUFSIZE - 1, 0)) <= 0)
            DieWithError("recv() failed or connection closed prematurely");
        totalBytesRcvd += bytesRcvd;   
        Buffer[bytesRcvd] = '\0';  
        printf("%s", Buffer);    
    }*/
   }
    close(sock);
    exit(0);
}
сервер

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <stdio.h>      /* for printf() and fprintf() */
#include <sys/socket.h> /* for recv() and send() */
#include <unistd.h>     /* for close() */
#include <string.h> 
#include <sys/shm.h>
#include <sys/msg.h>
#define RCVBUFSIZE 255
#define MESSAGECOUNT 5
#include "amessage.pb-c.h"
#define MAX_MSG_SIZE 1024
void DieWithError(char *errorMessage); 
 
static size_t read_buffer (unsigned max_length, uint8_t *out)
{
  size_t cur_len = 0;
  size_t nread;
  while ((nread=fread(out + cur_len, 1, max_length - cur_len, stdin)) != 0)
  {
    cur_len += nread;
    if (cur_len == max_length)
    {
      fprintf(stderr, "max message length exceeded\n");
      exit(1);
    }
  }
  return cur_len;
}
 
void HandleTCPClient(int clntSocket, key_t ipckey,int mq_id)
{
    char Buffer[RCVBUFSIZE];      
    int recvMsgSize;                    
    int length, count=1; 
    struct {
        long type;
        char text[255]; 
    }mymsg;
    length=sizeof(mymsg)-sizeof(long);
    memset (Buffer,0,RCVBUFSIZE);
 
    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);   
  /*if (msg == NULL)
  {
    fprintf(stderr, "error unpacking incoming message\n");
    exit(1);
  }
  printf("Received: t=%d",msg->t);  // required field
  if (msg->has_dlinastroki)                   // handle optional field
    printf("  dlinastroki=%d",msg->dlinastroki);
  printf(" stroka=%s\n",msg->stroka);
 
    amessage__free_unpacked(msg, NULL);*/
 
    while (recvMsgSize > 0)    
    {
        memset (mymsg.text,0,255);
        strcpy(mymsg.text,Buffer);
        mymsg.type=1;
        //msgsnd(mq_id, &mymsg,length,0);
 
               
       // if (send(clntSocket, Buffer, recvMsgSize, 0) != recvMsgSize)
         //  DieWithError("send() failed");
 
 
        if ((recvMsgSize = recv(clntSocket, Buffer, RCVBUFSIZE, 0)) < 0)
            DieWithError("recv() failed");
       
         msgrcv(mq_id, &mymsg,length,1,0);
         printf("Message from the message queuing: %s\n", mymsg.text);
        strcpy (Buffer,"Answer from the server");
 
    }
    close(clntSocket);    /* Close client socket */
}
прощу прощения за грязь в коде

Добавлено через 2 минуты
по идее на 51 строке кода серевера я дожен был увидеть
stroka=message from the client
но вывода нет а есть ошибка что написана в первом сообщении темы

Добавлено через 8 минут
ну на сервер это не весь код он из нескольких файлов сервер у меня но основной экшн происходит в коде который я привел
0
курлык-курлык
 Аватар для Max Patsy
87 / 96 / 8
Регистрация: 26.11.2009
Сообщений: 396
Записей в блоге: 1
09.02.2016, 12:19
Вечерком гляну
Но меня на первый взгляд смутил малок без фри. И вот эта штука sizeof(MAX_MSG_SIZE), sizeof от дефайна.
0
3 / 3 / 0
Регистрация: 22.09.2015
Сообщений: 124
09.02.2016, 15:13  [ТС]
Max Patsy, ну маллок не ошибка т к я перед тем как протобуфер прикручивать сюда сидел отдельно с прото игрался и там распаковка и запаковка идет без проблем да и я ставил free толку не добавлялось если честно
и у меня попутный вопрос в коде клиента есть вот такая строка 38
fwrite(buf,len,1,stderr); закомментированная так вот если раскментировать ее то она должна выводить на экран содержание структуры но выводит как попало с непонятными значками и иероглифами

Добавлено через 2 минуты
Max Patsy, ну сайзоф ошибки не выдает

Добавлено через 24 минуты
хотя и не выдает но выдает значение 4 как обычный int но я сделал иначе просто призвольную длину буфера в байтах задал 255
но проблемы это не решило

Добавлено через 2 часа 5 минут
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include "server.h"  /* TCP echo server includes */
#include <pthread.h>  
#include <sys/types.h>
#include <sys/ipc.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <wait.h>
#include <sys/stat.h>
#include <time.h>
#include <errno.h>   
//#include <sys/shm.h>   /* for POSIX threads */
#include <sys/msg.h>
#include "amessage.pb-c.h"
#define SIZE 5
 
void *ThreadMain(void *arg);            /* Main program of a thread */
 
/* Structure of arguments to pass to client thread */
struct ThreadArgs
{
    int clntSock;
    key_t ipckey;
    int mq_id;
};
 
int main(int argc, char *argv[])
{
 
    int servSock;                    
    int clntSock;                    
    unsigned short servPort;     
    pthread_t threadID;              
    struct ThreadArgs *threadArgs;  
    struct msqid_ds qstatus;
    if (argc < 2)    
    {
        printf("Usage:  %s <SERVER PORT>\n", argv[0]);
        exit(1);
    }
    int mq_id;
    key_t ipckey;
    ipckey=ftok("/tmp/foo", 42);
    printf("key = %d\n",ipckey );
    mq_id = msgget(ipckey, IPC_CREAT | 0666);
 
    if(msgctl(mq_id,IPC_STAT,&qstatus)<0){
    perror("msgctl failed");
    exit(1);
    }
    printf("mq_id = %d\n",mq_id );
 
    servPort = atoi(argv[1]);
    servSock = CreateTCPSocket(servPort);
    printf("%d message(s) on queue\n",qstatus.msg_qnum);
 
    for (;;) /* run forever */
    {       
    clntSock = AcceptTCPConnection(servSock);
 
        if ((threadArgs = (struct ThreadArgs *) malloc(sizeof(struct ThreadArgs))) 
               == NULL)
            DieWithError("malloc() failed");
       threadArgs -> clntSock = clntSock;
       threadArgs -> ipckey = ipckey;
       threadArgs -> mq_id = mq_id;
       if (pthread_create(&threadID, NULL, ThreadMain, (void *) threadArgs) != 0)
           DieWithError("pthread_create() failed");
 
    }
    /* NOT REACHED */
    msgctl (mq_id, IPC_RMID,0);
}
 
void *ThreadMain(void *threadArgs)
{
    int clntSock;    
    key_t ipckey;
    int mq_id;
    /* Guarantees that thread resources are deallocated upon return */
    pthread_detach(pthread_self()); 
    clntSock = ((struct ThreadArgs *) threadArgs) -> clntSock;
    ipckey = ((struct ThreadArgs *) threadArgs) -> ipckey;
    mq_id = ((struct ThreadArgs *) threadArgs) -> mq_id;
    free(threadArgs); /* Deallocate memory for argument */
 
    HandleTCPClient(clntSock,ipckey,mq_id);
 
    return (NULL);
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
09.02.2016, 15:13
Помогаю со студенческими работами здесь

Отправка TCP пакета
Всем привет! Появился ЕЩЁ один вопрос. Пишу программу без использования VCL, мне требуется отправить TCP пакет средствами (по...

Отправка сообщения по TCP/IP
Здравствуйте, на одном компьютере есть программа, доступ к которой осуществляется через определенный TCP порт. Необходимо с другого...

Отправка сообщения по TCP/IP
Здравствуйте, на одном компьютере есть программа, доступ к которой осуществляется через определенный TCP порт. Необходимо с другого...

Отправка tcp пакета JAVA
Доброго времени суток. Работаю над написанием клиента для Mail.ru агента, в документации сказано: MMP бинарный протокол. Все...

Отправка данных по TCP подключению
Добрый день. Имеется сервер на C# и клиентское приложение на Android (запускается с эмулятора) В новом потоке создается подключение. ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
Контроль уникальности заводского номера - вариант №2
Maks 24.03.2026
В отличие от предыдущего варианта добавлено прерывание циклов, также добавлены новые переменные для сохранения контекста ошибки перед прерыванием цикла: Процедура ПередЗаписью(Отказ, РежимЗаписи,. . .
SDL3 для Desktop (MinGW): Вывод текста со шрифтом TTF с помощью библиотеки SDL3_ttf на Си и C++
8Observer8 24.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-text-sdl3-c. zip finish-text-sdl3-cpp. zip
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло. Но на выплатах по больничным это. . .
Контроль уникальности заводского номера - вариант №1
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере документа выдачи шин для спецтехники с табличной частью в КА2. Данные берутся из регистра сведений, по которому настроено. . .
Хочу заставить корпорации вкладываться в здоровье сотрудников: делаю мат модель здравосохранения
anaschu 22.03.2026
e7EYtONaj8Y Z4Tv2zpXVVo https:/ / github. com/ shumilovas/ med2. git
Программный отбор элементов справочника по группе
Maks 22.03.2026
Установка программного отбора элементов справочника "Номенклатура" из модуля формы документа в КА2. В качестве фильтра для отбора справочника служит группа номенклатуры. Отбор по наименованию. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru