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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: как обратиться к данным  (Прочитано 6438 раз)
Firefox
Гость
« : Марта 05, 2013, 18:01 »

Здравствуйте. подскажите как мне обратиться к данным приходящим по сети при такой организации сервера:
В основном классе программы
Код:
//.h
TripServer *server;
//.cpp
 server_in=new TripServer(this,&gbo_data) ;
    if (!server_in->listen(QHostAddress::Any, 257)) {
        qDebug()<< "Failed to bind to port";
    }
Сервер
Код:
#include <QtCore>

#include "clientsocket.h"
#include "tripserver.h"

TripServer::TripServer(QObject *parent,_DATA_15GBO *dataGbo)
    : QTcpServer(parent)
{
        data=dataGbo;
}

void TripServer::incomingConnection(int socketId)
{
    ClientSocket *socket = new ClientSocket(this, this->serverPort(),data);
    socket->setSocketDescriptor(socketId);
}

Сокет
Код:
#include <QtNetwork>

#include "clientsocket.h"
unsigned char numb_packet=0;
ClientSocket::ClientSocket(QObject *parent, int port,_DATA_15GBO *GboStr)
    : QTcpSocket(parent)
{
    connect(this, SIGNAL(readyRead()), this, SLOT(readClient()));
    connect(this, SIGNAL(disconnected()), this, SLOT(deleteLater()));
    nextBlockSize = 0;
    dataGbo=GboStr;
    if(port==259)
    {
        tim=new QTimer(this);
        connect(tim,SIGNAL(timeout()),SLOT(slotSendDataGBO()));
        tim->start(500);
    }
}

void ClientSocket::readClient()
{
    QByteArray arr;
    QDataStream in(this);
    in.setVersion(QDataStream::Qt_4_2);
    quint64 tt=0;
    if (nextBlockSize == 0) {
        if (bytesAvailable() < sizeof(quint16))
            return;
        tt=bytesAvailable();
       arr=read(tt);
        tt=arr.size();
        command_arr=arr.mid(2,arr.size()-2);
        qDebug()<<"in data="<< command_arr;  //ВОТ ЭТИ ДАННЫЕ
         emit sendDataGbo();
    }
    close();
    processPaketFromGBO(command_arr);

}

то есть мне в основном классе программы для отображения нужно пришедшие по сети команды(command_arr) использовать.
А как к ним достучаться пока не понимаю. для передачи данных по сети передаю как ссылку в описании класса сервера и сокета, может есть попроще способ. буду рада если подскажите его. Улыбающийся
Записан
Firefox
Гость
« Ответ #1 : Марта 05, 2013, 20:22 »

Мне не очень  хочется сохранять все указатели на созданные сокеты а потом в них рыться, нельзя ли по другому? dynamic_cast  - смотрела использование но не поняла немного. возможно ли его тут применить.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Марта 05, 2013, 22:20 »

Сетью занимаюсь редко, но все же: пакет должен иметь длину и должен быть полностью считан. А так Вы хватанули кусок данных (напр 10 байт) - и потом с ним нечего делать
Записан
alexis031182
Гость
« Ответ #3 : Марта 05, 2013, 22:44 »

А я уже раз десять перечитал, но так и не понял в чём суть проблемы. Вообще с этого описания проблему не смог уразуметь.
Записан
Bepec
Гость
« Ответ #4 : Марта 05, 2013, 23:07 »

Краткое описание проблемы на мой взгляд.

Цитировать
Стырили откуда то кусок кода, что с ним делать незнаю, пакеты полностью не приходят. Указатели вообще что-то непонятное, хранить не хочу и не буду. Подскажите как сделать хорошо.
Записан
alexis031182
Гость
« Ответ #5 : Марта 05, 2013, 23:10 »

Верес, да Вы мастер дешифровки! ))
Записан
Bepec
Гость
« Ответ #6 : Марта 06, 2013, 06:52 »

Спасибо, стараюсь.

А по теме - никуда вы не денетесь от хранения списка подключений, если вам нужна двухсторонняя связь.

Если же не нужна, то можно переписать функцию приёмки, чтобы она преобразовывала полученные данные в нужные вам структуры/типы и ставила в очередь на обработку.
Записан
Firefox
Гость
« Ответ #7 : Марта 06, 2013, 13:00 »

В функции processPaketFromGBO(QByteArray data) я преобразовываю полученные данные в структру которая описана в подключаемом файле common.h.

Код:
typedef struct
{
    unsigned char head[2];       
    unsigned char bort;           
    unsigned char number_packet;
    unsigned char fatal;           
    unsigned char param_byte1;   
    unsigned char param_byte2;   
    unsigned char param_byte3;     
    unsigned short press;         
    unsigned short count_body;     
    unsigned char summa;         
} _HEAD_15GBO;
в классе сокета я делаю
_HEAD_15GBO  head;

Дак если я напишу в основном классе в хидере
_HEAD_15GBO  head; то это будет другой экземпляр структуры и он не будет заполнен данными из сети.
Хотя конечно можно там где структура описана написать _HEAD_15GBO  head; тогда будет видно этот экземпляр всем классам куда подключен common.h файл.
Записан
Bepec
Гость
« Ответ #8 : Марта 06, 2013, 13:16 »

Учите С++ и работайте с указателями. Указатель вас спасёт.
Записан
Firefox
Гость
« Ответ #9 : Марта 06, 2013, 13:30 »

что в данном случае вы имели ввиду про указаель?я возможно не сильно ими владею но в сути вопроса создать указатель или экземпляр на структуру не вижу разницы. главное чтоб одни данные в разных классах видны были. или я не так упрек ваш поняла?
Записан
carrygun
Гость
« Ответ #10 : Марта 06, 2013, 13:47 »

Решение данной проблемы зависит же в первую очередь от архитектуры приложения и тому подобных тонкостей. А вот вариантов реализации может быть много.

Например можно держать объекты, допустим, в массиве, в том классе где прилетают данные и сделать публичный метод для получения данных.

Можно завести хэш или ассоциативный массив.

Можно даже просто взять и выбросить сигнал в методе чтения данных и ловить его родительским классом.

Выбирать только вам.
« Последнее редактирование: Марта 06, 2013, 13:49 от carrygun » Записан
Bepec
Гость
« Ответ #11 : Марта 06, 2013, 14:36 »

Кхм это даже не упрёк.

Указатель - это (надо же!) указатель на адрес памяти. А откуда вы обратитесь к памяти значения не имеет.

В общем у вас пока непонимание принципа работы С++ Веселый
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Марта 06, 2013, 17:36 »

В общем у вас пока непонимание принципа работы С++ Веселый
Не вижу здесь никакой связи конкретно с плюсами  Улыбающийся

Firefox, Вам нужно "получить пакет" (весь, а не огрызок) и уже из него получать данные Ваших структур. Например (тупейшее лобовое решение)

Код
C++ (Qt)
struct CHeader {
int command;
int dataSize;
};
...
 
// ждем пока придут данные заголовка
if (bytesAvailable() < sizeof(CHeader))
 msleep(100);
 
// читаем заголовок
CHeader head;
QByteArray arr = read(sizeof(CHeader));
 
// десериализуем заголовок
if (1) {
QDataStream strm(arr);
strm >> head.command;
strm >> head.dataSize;
}
 
// проверяем что за команда
switch (head.command) {
...
}
 
// тупо ждем данных (в заголовке есть их длина)
if (bytesAvailable() < head.dataSize)
 msleep(100);
 
// все данные пришли, читаем
arr = read(head.dataSize);
 
// десериализуем данные
if (1) {
QDataStream strm(arr);
strm >>  ...
}
 
Ну а как "не тупо" - тут по-всякому и можно долго рассказывать, но все равно принцип тот же - дождаться данных с которыми уже можно работать
Записан
Firefox
Гость
« Ответ #13 : Марта 09, 2013, 20:00 »

спасибо за помощь. я просто сделала структуру extern и подключила во все файлы мне необходимые. а по поводу того, что я читаю кусок только данных. я поправила. хотя пакет у меня не большой и все за один раз считывалось.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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