Название: Передача структур по сети
Отправлено: 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); // ???неверно } } }
Название: Re: Передача структур по сети
Отправлено: Bepec от Февраль 06, 2013, 13:54
Кхм. Можно глупый вопрос ? А как вы отправляете дейтаграмму и вопрос, откуда клиент узнает, что добавилась новая структура на сервере или другом клиенте?
Название: Re: Передача структур по сети
Отправлено: Firefox от Февраль 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); // пФРТБЧЙФШ ДБООЩЕ Ч уптд
}
потом планирую доделать
Название: Re: Передача структур по сети
Отправлено: Bepec от Февраль 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 // пФРТБЧЙФШ ДБООЩЕ Ч уптд !
Название: Re: Передача структур по сети
Отправлено: Firefox от Февраль 06, 2013, 14:37
соглашусь, но при чтении данные у меня другие выходят вот и сделала так. но даже если так запихивать, вопрос с заполнением нужной структуры данными остается.вроде есть указатель на структуру, но не понятно как по нему обращаться к данным самим.
Название: Re: Передача структур по сети
Отправлено: alexis031182 от Февраль 06, 2013, 14:40
Не запихивайте всю структуру, да ещё по указателю в сеть. Ничего хорошего не выйдет. Делайте сериализацию для каждого поля в отдельности. И восстанавливайте на приёмной стороне точно также, по позициям. Наличие контрольной суммы данных в заголовке - это лишь первый бастион защиты, но не 100% гарантия.
Название: Re: Передача структур по сети
Отправлено: Bepec от Февраль 06, 2013, 14:44
Полностью согласен с alexis031182. Это именно то, что я описал в коде.
PS и почитайте про правила оформления кода. Это не для меня, не для кого-либо, а для вас же :)
Название: Re: Передача структур по сети
Отправлено: fuCtor от Февраль 17, 2013, 12:32
Может уже и поздно и мое решение будет "гвозди микроскопом":
- перевести структуры в классы, унаследованные от интерфейса с двумя методами serialize/deserialize, т.е. пускай сами структуры себя разбирают в поток и собирают (им же видней); - т.к. подразумевается расширение количества структур, то можно сделать некий менеджер, который будет принимать сырые данные (поток), определять необходимый класс и создавать нужный экземпляр с вызовом его заполнения.
Таким образом понизиться связность, увеличиться расширяемость, можно будет используя любую SVC поддерживать актуальность набора структур с обоих сторон.
Название: Re: Передача структур по сети
Отправлено: Firefox от Февраль 18, 2013, 22:02
Спасибо. это более похоже на решение моей задачи)про классы подумаю. но идея это уже хорошо)
|