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

Войти
 
  Начало Форум WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  
  Просмотр сообщений
Страниц: 1 ... 67 68 [69]
1021  Qt / Работа с сетью / Re: Чтение с сокета без QDataStream : Апрель 28, 2011, 15:22
а без QByteArray?

вот текущий пример моей реализации
Код:
if(fblockSize==0)
    {
        if(fsocket->bytesAvailable()<sizeof(scb_msg_t)) return;
        fblockSize = fsocket->read(frawBuffer,sizeof(scb_msg_t));
        if(fframeHeader.size==0)
        {
            fblockSize = 0;
            return;
        }
//        qDebug("block %d\n, header.size %d",fblockSize,fframeBuffer.msg_head->size);
    }

    fblockSize=fsocket->bytesAvailable();
    fleftBytes = fframeBuffer.msg_head->size-sizeof(scb_msg_t);

    if(fblockSize>=(fleftBytes))
    {
        fblockSize = fsocket->read(&frawBuffer[sizeof(scb_msg_t)],fleftBytes);
//        qDebug("fblockSize %d\n",fblockSize);
        fblockSize = 0;
    }
1022  Qt / Работа с сетью / Чтение с сокета без QDataStream : Апрель 28, 2011, 14:48
Как читать с сокета данные без QDataStream (который используется во всех примерах).
Есть сервер (написан на нативных сокетах под QNX), пишу клиент под Win/Lin под Qt.
Нужно получать с сервера пакеты (пакеты могут иметь разную длину).
Пакет представляет из себя несколько массивов собранных в кучу друг за другом (типы quin32, структуры и т.п.).
при сигнале readyRead() получаю только часть данных (меньше чем нужно в bytesAvailable()).
при socket->read() я так понимаю внутренний буфер очищается на колчиество считанных байт.
Как грамотно реализовать чтение?

я пока делаю так:
Код:
void     QClient::readyRead()
{
    int readBytes = fsocket->bytesAvailable();
    if(readBytes<sizeof(scb_msg_t)) return; //если меньше данных чем заголовок игнорируем

    fsocket->read((char*)frawBuffer,sizeof(scb_msg_t));
    if(fframeBuffer.msg_head->size)
    {
        freadBytes = 0;
        while((readBytes = fsocket->bytesAvailable())!=0)
        {
            fsocket->read((char*)frawBuffer[freadBytes],readBytes);
            freadBytes+=readBytes;
        }
    }
...
}
1023  Qt / Многопоточное программирование, процессы / Re: Несколько TCP клиентов в одной программе : Апрель 28, 2011, 10:26
Необходимо создать отдельный объект, в котором будет работать сокет, в этом объекте связать все сигналы и слоты с сокетом, а уже в потоке в run() создать экземпляр этого объекта.
Проблема в следующем, что каждый поток:
-должен читать сокет
-данные с этого сокета должны быть потом обработаны в другом потоке (поток синхронизации данных)
-также по этому сокету нужно отправлять асинхронные команды на сервер (команды задаются как с главного потока гуи, так и с других потоков).
В главном потоке (или в другом) по таймеру на все сокеты отправлять пакет запроса.

Раньше все писалось под QNX/POSIX threads и с этим проблем у меня не возникало, так как сокеты там потокобезопасные по умолчанию.

1024  Qt / Многопоточное программирование, процессы / Re: Несколько TCP клиентов в одной программе : Апрель 28, 2011, 10:22
Может я что-то недоглядел, но где у тебя сокет создается?
опечатался, сокет созлаю в конструкторе (забыл вставить когда копировал из исходника).

1025  Qt / Многопоточное программирование, процессы / Несколько TCP клиентов в одной программе : Апрель 27, 2011, 17:41
Привет. В Qt я новичек. С многопоточностью (в Qt) только столкнулся.
Как лучше реализовать такую задачу:
Есть TCP 4 сервера. Нужно к каждому из них подключаться (независимо), делать запросы и получать данные.
Резонно что на каждое TCP соединение имеет смысл выделить по потоку.

Код:
class QMMNClientThread : public QThread
{
    Q_OBJECT

    QTcpSocket   * fmmnClient; //сетевой клиент
    QTimer        * freqTimer; //таймер, в котором надо переодически слать запрос на сервер (каждые 250мс)
    void            run();

public:

    explicit QMMNClientThread(QObject *parent = 0);
    ~QMMNClientThread();

    QString         remoteHost;
    quint16         remotePort;

signals:

public slots:

private slots:

    void            readyRead();
    void            onConnected();
    void            onDisconnected();
    void            onError();
    void            doRequest();

};

вот моя реализация класса
Код:
#include <memory.h>
#include <QObject>
#include "mmn_client.h"
#include "qmmnclientthread.h"

QMMNClientThread::QMMNClientThread(QObject *parent) :
    QThread(parent)
{
    remoteHost = "127.0.0.1";
    remotePort = 10000;
    freqTimer = new QTimer;
    freqTimer->setInterval(250);
    fmmnClient->moveToThread(this);
    freqTimer->moveToThread(this);
    connect(fmmnClient,SIGNAL(connected()),this,SLOT(onConnected()));
    connect(fmmnClient,SIGNAL(disconnected()),this,SLOT(onDisconnected()));
    connect(fmmnClient,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(onError()));
    connect(fmmnClient,SIGNAL(readyRead()),this,SLOT(readyRead()));
    connect(freqTimer,SIGNAL(timeout()),this,SLOT(doRequest()));
}

QMMNClientThread::~QMMNClientThread()
{
    freqTimer->stop(); //надо остановить таймер
    fmmnClient->close(); //закрыть соединение
    delete  fmmnClient; //удалить объекты
    delete  freqTimer;
    if(frawBuffer) free(frawBuffer); //освободить память буфера приема
}

void    QMMNClientThread::run()
{
    fmmnClient->connectToHost(remoteHost,remotePort); //первая попытка соединения
    exec(); //запускаю петлю событий потока
}

void     QMMNClientThread::readyRead()
{
 //здесь буду обрабатывать принятые данные (порядка 4Кб)
}

void     QMMNClientThread::onConnected()
{
//при подключении к серверу начинаю делать запросы данных
    freqTimer->start(250);
}


void     QMMNClientThread::onDisconnected()
{
//если сервер отключил, то
    freqTimer->stop(); //остановить запросы
    fmmnClient->close(); //закрыть сокет
    sleep(freconnTimeot); //ждем 2 секунды
    fmmnClient->connectToHost(remoteHost,remotePort); //пытаемся подключиться
}

//пока тоже самое как и при отключении
void     QMMNClientThread::onError()
{
    freqTimer->stop();
    fmmnClient->close();
    sleep(freconnTimeot);
    fmmnClient->connectToHost(remoteHost,remotePort);
}

void     QMMNClientThread::doRequest()
{
 //здесь надо отправить небольшой пакет данных по этому же сокету
}


Проблема возникает при вызове деструктора
Код:
QMMNClientThread::~QMMNClientThread()
{
    freqTimer->stop(); //надо остановить таймер
    fmmnClient->close(); //закрыть соединение <<--------здесь вылетает окно с аварийным закрытием программы
    delete  fmmnClient; //удалить объекты
    delete  freqTimer;
    if(frawBuffer) free(frawBuffer); //освободить память буфера приема
}

Я понимаю что моя тема уже избита и стара как г-но мамонта, но как мне создать сокет, что бы можно было к нему обращаться не только в run()?
Страниц: 1 ... 67 68 [69]

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