Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Сети > Упаковка полей структуры в буфер


Автор: sergu 13.4.2008, 20:52
Понимаю что подобная тема поднималась много раз, но все же.
Ситуация следующая:
Есть структура

Код

struct ST
{
char a;
int length_buff;
char buff[2048];
};


Неоходимо отправить данные из этой структуры в сеть. Естественно, что не разумно слать в сеть структуру размером 2053 байта, если в buff[] содержит, например, 5 нужных символов.
Думаю, что рациональным режением этой проблемы, является созданием буфера типа char, в который будет упаковываться эта структура.
Допустим, что в массиве buff[] у нас хранится 10 символов. Соответственно в переменной length_buff хранится число 10, ну а в  char a любое значение.
Плучается, для того чтобы отправить инфу из этой структуры, нам нужно создать буфер send_buff[] размером 15 байт. В первом байте у нас хранится значение из  char a, в со второго байта по пятый int length_buff, а в следующих десяти байтах buff.
Ну и после того как мы упаковли поля делаем отправку send(socket, send_buff, send_buff_length);
Хотелось бы узнать:
1 - как лучше объявить send_buff (статически или динамически). 
2 - как, собственно, производить упаковку.
3 - как заполнить структуру значениями из массива

Кстати. Насчет 32 и 64 разрядов. В моем учебном протоколе строго оговорен, тип и размер данных т.е., например, целое беззнаковое число размером 4 байта.
простите непутевого  smile 

Автор: sergu 13.4.2008, 22:57
Вот примерное решение проблемы. Прошу товарищей постарше прокоментировать программку и, если можно, дать советы по рациональности и безопасности кода кода.
Код

#include <stdlib.h>
#include <iostream>
using namespace std;

struct ST
{
    char a;
    unsigned int l;
    char buff[2048];
};
void main(void)
{

    ST s;

    int size;

    cin >> s.buff;

    //Случайные данные
    s.a = 'a';
    s.l = 16843009;
    size = sizeof(s.a) + sizeof(s.l)+(strlen(s.buff)+1); //+1 äëÿ 0
    
    char *buff = new char[size];

    char *pa = (char *) &s.a;
    char *pl = (char *) &s.l;
    char *pb = (char *) &s.buff;


    //Упаковка на отправителе
    buff[0] = *pa;
    strncpy(&buff[1], pl, 4);
    strncpy(&buff[5], pb, strlen(s.buff)+1); 


//Распаковка на получателе
    ST st;
    unsigned int *il2;

    st.a = buff[0];    
    il2 = (unsigned int *) &buff[1];
    st.l = *il2;
    strncpy(st.buff,&buff[5], strlen(&buff[5])+1);
}

Спасибо

Автор: jonie 14.4.2008, 00:52
чет какая-то фигня)
Код

 buff[0] = *pa;
 char *pl = (char *) &s.l;  //зачем ?
 strncpy(&buff[1], pl, 4);  //зачем так ?


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

pragma pack(push)
pragma pack(1)
typedef struct{
  int stringlen;
} PACKET_HEADER;
pragma pack(pop)

char string[1024];
std::cin.getline(string);
PACKET_HEADER header;
header.stringlen = strlen(string);

char sentBuf[1024];
memcpy(sentBuf,header);
memcpy(&sentBuf+sizeof(header), string);

.....


а ошибок-то у меня огого....)) ну в общем суть, думаю понятно : заголовок, потом данные.

Автор: korian 14.4.2008, 05:12
sergu, 
strncpy копирует до первого попавшегося нуля.
если в ST::buff - могут быть не только строки, то распаковать не получится.

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