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

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

08.02.2016, 06:46. Показов 2660. Ответов 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
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru