Russian Qt Forum

Qt => Вопросы новичков => Тема начата: Firefox от Марта 05, 2013, 18:01



Название: как обратиться к данным
Отправлено: 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) использовать.
А как к ним достучаться пока не понимаю. для передачи данных по сети передаю как ссылку в описании класса сервера и сокета, может есть попроще способ. буду рада если подскажите его. :)


Название: Re: как обратиться к данным
Отправлено: Firefox от Марта 05, 2013, 20:22
Мне не очень  хочется сохранять все указатели на созданные сокеты а потом в них рыться, нельзя ли по другому? dynamic_cast  - смотрела использование но не поняла немного. возможно ли его тут применить.


Название: Re: как обратиться к данным
Отправлено: Igors от Марта 05, 2013, 22:20
Сетью занимаюсь редко, но все же: пакет должен иметь длину и должен быть полностью считан. А так Вы хватанули кусок данных (напр 10 байт) - и потом с ним нечего делать


Название: Re: как обратиться к данным
Отправлено: alexis031182 от Марта 05, 2013, 22:44
А я уже раз десять перечитал, но так и не понял в чём суть проблемы. Вообще с этого описания проблему не смог уразуметь.


Название: Re: как обратиться к данным
Отправлено: Bepec от Марта 05, 2013, 23:07
Краткое описание проблемы на мой взгляд.

Цитировать
Стырили откуда то кусок кода, что с ним делать незнаю, пакеты полностью не приходят. Указатели вообще что-то непонятное, хранить не хочу и не буду. Подскажите как сделать хорошо.


Название: Re: как обратиться к данным
Отправлено: alexis031182 от Марта 05, 2013, 23:10
Верес, да Вы мастер дешифровки! ))


Название: Re: как обратиться к данным
Отправлено: Bepec от Марта 06, 2013, 06:52
Спасибо, стараюсь.

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

Если же не нужна, то можно переписать функцию приёмки, чтобы она преобразовывала полученные данные в нужные вам структуры/типы и ставила в очередь на обработку.


Название: Re: как обратиться к данным
Отправлено: Firefox от Марта 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 файл.


Название: Re: как обратиться к данным
Отправлено: Bepec от Марта 06, 2013, 13:16
Учите С++ и работайте с указателями. Указатель вас спасёт.


Название: Re: как обратиться к данным
Отправлено: Firefox от Марта 06, 2013, 13:30
что в данном случае вы имели ввиду про указаель?я возможно не сильно ими владею но в сути вопроса создать указатель или экземпляр на структуру не вижу разницы. главное чтоб одни данные в разных классах видны были. или я не так упрек ваш поняла?


Название: Re: как обратиться к данным
Отправлено: carrygun от Марта 06, 2013, 13:47
Решение данной проблемы зависит же в первую очередь от архитектуры приложения и тому подобных тонкостей. А вот вариантов реализации может быть много.

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

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

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

Выбирать только вам.


Название: Re: как обратиться к данным
Отправлено: Bepec от Марта 06, 2013, 14:36
Кхм это даже не упрёк.

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

В общем у вас пока непонимание принципа работы С++ :D


Название: Re: как обратиться к данным
Отправлено: Igors от Марта 06, 2013, 17:36
В общем у вас пока непонимание принципа работы С++ :D
Не вижу здесь никакой связи конкретно с плюсами  :)

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 >>  ...
}
 
Ну а как "не тупо" - тут по-всякому и можно долго рассказывать, но все равно принцип тот же - дождаться данных с которыми уже можно работать


Название: Re: как обратиться к данным
Отправлено: Firefox от Марта 09, 2013, 20:00
спасибо за помощь. я просто сделала структуру extern и подключила во все файлы мне необходимые. а по поводу того, что я читаю кусок только данных. я поправила. хотя пакет у меня не большой и все за один раз считывалось.