Russian Qt Forum
Ноябрь 23, 2024, 18:18 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Передача структур по сети  (Прочитано 5071 раз)
Firefox
Гость
« : Февраль 06, 2013, 13:48 »

Здравствуйте. хочу вас спросить как мне реализовать следующее:
по сети могут передаваться разные структуры с разным набором данных. при том в любой момент можно добавить новую структуру.
Я хочу сделать следующее: структуры будут идентифицироваться номером формуляра(то есть он уникален для каждой новой структуры).добавляя новую структуру для обмена пользователь в своем коде должен вызвать функцию которая до будет добавлять пару(номер формуляра, указатель на структуру) в некую структуру которая хранит список имеющихся структур для обмена, то есть:
Код:
typedef struct
{
    short Nom_form;
    void *Name_struct;
}Form_count;
// функция добавляющая очередную структуру для обмена
bool client:: addNewStruct(short Nom_Form ,void* _struct)
{
    int sz=ST_FORM.size();
      for(int i=0; i<sz;i++)
      {
          if(Nom_Form==ST_FORM.at(i).Nom_form)// такой формуляр уже есть
          {
              emit Err_addStruct(Nom_Form);
              return false;

          }
      }
      Form_count fct;
      fct.Name_struct= _struct;
      fct.Nom_form=Nom_Form;
      ST_FORM.append(fct);
      if(sz+1==ST_FORM.size())
             return true;
      else return false;
}

//использование
struct INn //IN
{
  short field2;  // controlling flag. 0 - no connection, 1 - training, 2 - training stops, 3 training ends.
  short reg;       //
  short v;       
  short tip;       
  short gl_m;       

  short tip1;
  float kr;
  float x_nl;       
  float y_nl;       
  float h_nl;       
  float k_nl;   

  float C_z[20];     
  float H_z[20];       

  short num_hc;         

  float K_otr[11]; 
  float  v_vet;     
  int num_cel;         

  dan_cel cel[5];       

  int day;             
  int hour;           
  int minute;         
  int sec;             
};
 extern struct  INn IN_ST1; //IN
addNewStruct(101,&IN_ST1);
далее при чтении дейтаграммы есть заголовок пакета в котором присутствует номер формуляра и размер самых данных без учета заголовка
Код:
struct Config_client
{
    unsigned int pulseCount;// номер посылки
    unsigned char crc; // контрольная сумма
    short id_Form; // номер формуляра
    unsigned int ST_size; // размер данных
};
Config_client conf_in;
при чтении данных я сравниваю формуляры, но вот как мне переписать полученные данные правильно в структуру соответствующую данному формуляру мне немного не понятно. в структуре Form_count есть указатель но нужную структуру но как им правильно воспользоваться?
Код:

void client::readDatagrams()
{
    while( udp_in->hasPendingDatagrams() )
    {
        QByteArray datagram;
        datagram.resize( udp_in->pendingDatagramSize() );
        QHostAddress sender;
        quint16 senderPort;
        udp_in->readDatagram( datagram.data(), datagram.size(), &sender, &senderPort );
        processTheDatagramFromStm(datagram);
    }
}
void client::processTheDatagramFromStm(QByteArray dtgr)
{
   
    memmove((char *)&conf_in, (char *)dtgr.data(), sizeof(conf_in));
    char crc;
    int sz;
    sz=sizeof(conf_in);
    crc=calc_control_summ( (unsigned char*)&conf_in, sz-1 );
    if( conf_in.crc !=crc)
        emit errorCrc_in();
   sz=ST_FORM.size();
   for(int i=0; i<sz;i++)
   {
       if(conf_in.id_Form==ST_FORM.at(i).Nom_form)
       {
           QByteArray arr;
           arr=dtgr.mid(sizeof(Config_client)+1,conf_in.ST_size);
           memmove((char *)&ST_FORM.at(i).Name_struct, (char *)arr.data(), conf_in.ST_size); // ???неверно
       }
   }
}
Записан
Bepec
Гость
« Ответ #1 : Февраль 06, 2013, 13:54 »

Кхм. Можно глупый вопрос ? А как вы отправляете дейтаграмму и вопрос, откуда клиент узнает, что добавилась новая структура на сервере или другом клиенте?
Записан
Firefox
Гость
« Ответ #2 : Февраль 06, 2013, 14:01 »

структуру новую конечно надо добавлять одинаково и на сервере и на клиенте, иначе по заданному номеру формуляра не будет найдена структура на одном из концов при чтении.
пока что отправляю так
Код:
void client::send_data_slot()
{
    int sz=0;
    conf_out.id_Form=101;
    conf_out.pulseCount+=1;
    conf_out.ST_size=sizeof(IN_ST1);
    sz=sizeof(conf_out);
    conf_out.crc=calc_control_summ( (unsigned char*)&conf_out, sz-1 );
    QByteArray datagram,arr,ARR_REZ,arr1;
    QDataStream out( &datagram, QIODevice::WriteOnly );;
    out.setVersion( QDataStream::Qt_4_2 );
    arr.append((char*)&conf_out.pulseCount,sizeof(unsigned int));
    arr.append((char*)&conf_out.crc,sizeof(unsigned char));
    arr.append((char*)&conf_out.id_Form,sizeof(short));
    arr.append((char*)&conf_out.ST_size,sizeof(unsigned int));
    ARR_REZ.append(arr);
    bool yy=memmove((char *)&arr1 ,(char *)&IN_ST1, sizeof(IN_ST1));
   sz=arr1.size();
   ARR_REZ.append(arr1);
   out.writeRawData(ARR_REZ,ARR_REZ.size());
    sz=udp_out->writeDatagram( datagram, QHostAddress::Broadcast, port_out); // пФРТБЧЙФШ ДБООЩЕ  Ч уптд

}
потом планирую доделать
Записан
Bepec
Гость
« Ответ #3 : Февраль 06, 2013, 14:32 »

Кхм, а просто сделать наподобие вот так?

осторожно, псевдокод;
Код:

    // заполняем данные
    int sz=0;
    conf_out.id_Form=101;
    conf_out.pulseCount+=1;
    conf_out.ST_size=sizeof(IN_ST1);
    sz=sizeof(conf_out);
    conf_out.crc=calc_control_summ( (unsigned char*)&conf_out, sz-1 );

    // создаём отправной массив и поток
    QByteArray datagram;
    QDataStream out( &datagram, QIODevice::WriteOnly );;
    out.setVersion( QDataStream::Qt_4_2 );
  
    // запихивает все данные в поток
    out <<  conf_out.id_Form  <<  conf_out.pulseCount << conf_out.ST_size << conf_out.crc;

    // отправляем
    sz=udp_out->writeDatagram( datagram, QHostAddress::Broadcast, port_out);

Согласитесь, читабельнее?

PS
Цитировать
// пФРТБЧЙФШ ДБООЩЕ  Ч уптд
!
Записан
Firefox
Гость
« Ответ #4 : Февраль 06, 2013, 14:37 »

соглашусь, но при чтении данные у меня другие выходят вот и сделала так. но даже если так запихивать, вопрос с заполнением нужной структуры данными остается.вроде есть указатель на структуру, но не понятно как по нему обращаться к данным самим.
Записан
alexis031182
Гость
« Ответ #5 : Февраль 06, 2013, 14:40 »

Не запихивайте всю структуру, да ещё по указателю в сеть. Ничего хорошего не выйдет. Делайте сериализацию для каждого поля в отдельности. И восстанавливайте на приёмной стороне точно также, по позициям. Наличие контрольной суммы данных в заголовке - это лишь первый бастион защиты, но не 100% гарантия.
Записан
Bepec
Гость
« Ответ #6 : Февраль 06, 2013, 14:44 »

Полностью согласен с alexis031182. Это именно то, что я описал в коде.

PS и почитайте про правила оформления кода. Это не для меня, не для кого-либо, а для вас же Улыбающийся
Записан
fuCtor
Гость
« Ответ #7 : Февраль 17, 2013, 12:32 »

Может уже и поздно и мое решение будет "гвозди микроскопом":

- перевести структуры в классы, унаследованные от интерфейса с двумя методами serialize/deserialize, т.е. пускай сами структуры себя разбирают в поток и собирают (им же видней);
- т.к. подразумевается расширение количества структур, то можно сделать некий менеджер, который будет принимать сырые данные (поток), определять необходимый класс и создавать нужный экземпляр с вызовом его заполнения.

Таким образом понизиться связность, увеличиться расширяемость, можно будет используя любую SVC поддерживать актуальность набора структур с обоих сторон.
Записан
Firefox
Гость
« Ответ #8 : Февраль 18, 2013, 22:02 »

Спасибо. это более похоже на решение моей задачи)про классы подумаю. но идея это уже хорошо)
« Последнее редактирование: Февраль 18, 2013, 22:04 от Firefox » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.064 секунд. Запросов: 21.