Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Сокеты в Qt / 10 сообщений из 10, страница 1 из 1
24.01.2014, 04:57
    #38536250
GorloPavel
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сокеты в Qt
Здравствуйте. Мне нужно чтобы прием и обработка данных выполнялись в отдельном потоке. А оправку данных я мог выполнять из любого потока имеющего указатель или ссылку на socket. Сделал так:

.h
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
#ifndef TCPSOCKET_H
#define TCPSOCKET_H

#include <QThread>
#include <QtNetwork>

typedef unsigned char BYTE;

class TCPSocket : public QThread
{
    Q_OBJECT
public:
    TCPSocket(QObject *parent = 0);
    void run();
    void connectTo(QString hostName, int port);
    void sendData(const QByteArray &packet);
private:
    QTcpSocket *socket;
    QString hostName;
    int port;
signals:
  void connected();
  void disconnected();
  void notConnected();
};

#endif // TCPSOCKET_H



.cpp
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
#include "tcpsocket.h"

TCPSocket::TCPSocket(QObject *parent) :QThread(parent)
{
}

void TCPSocket::connectTo(QString hostName, int port)
{
    this->hostName=hostName;
    this->port=port;

    if(!isRunning())
        start();
}

void TCPSocket::sendData(const QByteArray &packet)
{
    socket->write(packet,packet.length());
    socket->flush();
}

void TCPSocket::run()
{
    QString serverName = hostName;
    int serverPort = port;

    socket = new QTcpSocket();
    socket->connectToHost(serverName, serverPort);

    if (!socket->waitForConnected(5000)) {
        emit notConnected();
        return;
    }

    emit connected();

    while(socket->waitForReadyRead(60000*2)){
        while(socket->bytesAvailable())
        {
            QByteArray data=socket->readAll();
            qDebug()<<"Данные";
        }
    }

    emit disconnected();
}



Но при вызове TCPSocket::sendData я ловлю в логах:
Код: sql
1.
2.
QSocketNotifier: socket notifiers cannot be enabled from another thread
QSocketNotifier: socket notifiers cannot be disabled from another thread



Как правильно сделать? Спасибо!
...
Рейтинг: 0 / 0
24.01.2014, 07:00
    #38536263
GorloPavel
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сокеты в Qt
Попробовал так. Не знаю насколько это правильно. Какие проблемы могут быть при таком раскладе?

.h
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
#ifndef TCPSOCKET_H
#define TCPSOCKET_H

#include <QThread>
#include <QtNetwork>

typedef unsigned char BYTE;

class TCPSocket : public QThread
{
    Q_OBJECT
public:
    TCPSocket(QObject *parent = 0);
    void run();
    bool connectTo(QString hostName, int port);
    void sendData(const QByteArray &packet);
private:
    QTcpSocket *socket;
signals:
  void disconnected();
};

#endif // TCPSOCKET_H



.cpp
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
#include "tcpsocket.h"

TCPSocket::TCPSocket(QObject *parent) :QThread(parent)
{
}

bool TCPSocket::connectTo(QString hostName, int port)
{
    socket = new QTcpSocket();
    socket->connectToHost(hostName, port);

    if (!socket->waitForConnected(5000)) {
        return false;
    }else{
        if(!isRunning())
            start();
        return true;
    }
}

void TCPSocket::sendData(const QByteArray &packet)
{
    socket->write(packet,packet.length());
    socket->flush();
}

void TCPSocket::run()
{
    QTcpSocket socketReceiver;
    socketReceiver.setSocketDescriptor(socket->socketDescriptor());

    while(socketReceiver.waitForReadyRead(60000*2)){
        while(socketReceiver.bytesAvailable())
        {
            QByteArray data=socketReceiver.readAll();
            qDebug()<<"Данные";
        }
    }

    emit disconnected();
}
...
Рейтинг: 0 / 0
24.01.2014, 07:28
    #38536271
GorloPavel
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сокеты в Qt
Вообщем вот что получилось. Чтение и обработка данных в отдельном потоке. Может кому-то пригодиться. Исправления-добавления приветствуются. Вроде работает :)

.h
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
#ifndef TCPSOCKET_H
#define TCPSOCKET_H

#include <QThread>
#include <QtNetwork>

typedef unsigned char BYTE;

class TCPSocket : public QThread
{
    Q_OBJECT
public:
    TCPSocket(QObject *parent = 0);
    void run();
    bool connectTo(QString hostName, int port);
    void sendData(const QByteArray &packet);
private:
    QTcpSocket *socket;
signals:
  void disconnected();
  void error(QString error);
};

#endif // TCPSOCKET_H



.cpp
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
#include "tcpsocket.h"

TCPSocket::TCPSocket(QObject *parent) :QThread(parent)
{
}

bool TCPSocket::connectTo(QString hostName, int port)
{
    socket = new QTcpSocket();
    connect(socket,SIGNAL(disconnected()),this,SIGNAL(disconnected()));
    socket->connectToHost(hostName, port);

    if (!socket->waitForConnected(5000)) {
        emit error(socket->errorString());
        return false;
    }else{
        if(!isRunning())
            start();
        return true;
    }
}

void TCPSocket::sendData(const QByteArray &packet)
{
    socket->write(packet,packet.length());
    socket->flush();
}

void TCPSocket::run()
{
    QTcpSocket socketReceiver;
    connect(&socketReceiver,SIGNAL(disconnected()),this,SIGNAL(disconnected()));
    socketReceiver.setSocketDescriptor(socket->socketDescriptor());

    while(socketReceiver.waitForReadyRead(5000)){
        while(socketReceiver.bytesAvailable())
        {
            QByteArray data=socketReceiver.readAll();
            qDebug()<<"Данные";
        }
    }

    emit error(socketReceiver.errorString());
}
...
Рейтинг: 0 / 0
24.01.2014, 08:33
    #38536281
GorloPavel
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сокеты в Qt
Нашел проблему... Если вызвать socket->disconnectFromHost(), то поток продолжает работать. Как быть?
...
Рейтинг: 0 / 0
24.01.2014, 11:08
    #38536460
GorloPavel
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сокеты в Qt
Никто не знает?
...
Рейтинг: 0 / 0
24.01.2014, 18:45
    #38537325
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сокеты в Qt
Сокет и поток это две разные вещи.
...
Рейтинг: 0 / 0
25.01.2014, 03:54
    #38537543
GorloPavel
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сокеты в Qt
White OwlСокет и поток это две разные вещи.
Да, но сокет закрыт, а поток висит на waitForReadyRead
...
Рейтинг: 0 / 0
25.01.2014, 05:41
    #38537545
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сокеты в Qt
Ты закрываешь сокет в одном потоке и надеешься что в другом потоке waitForReadyRead сработает?
Не сработает.
...
Рейтинг: 0 / 0
25.01.2014, 10:08
    #38537574
GorloPavel
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сокеты в Qt
White OwlТы закрываешь сокет в одном потоке и надеешься что в другом потоке waitForReadyRead сработает?
Не сработает.
Уже понял. Так правильнее?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
#include "tcpsocket.h"


TCPSocket::TCPSocket(QObject *parent) :QThread(parent)
{
}

bool TCPSocket::connectTo(QString hostName, int port){
    socket = new QTcpSocket();
    connect(socket,SIGNAL(disconnected()),this,SLOT(onDisconnect()));
    socket->connectToHost(hostName, port);

    if (!socket->waitForConnected(5000)) {
        emit error(socket->errorString());
        return false;
    }else{
        if(!isRunning())
            start();
        return true;
    }
}

void TCPSocket::killConnection(){
    socket->disconnectFromHost();
}

void TCPSocket::sendData(const QByteArray &packet){
    socket->write(packet,packet.length());
    socket->flush();
}

void TCPSocket::onDataReceive()
{
    while(socket->bytesAvailable()){
        QByteArray data=socket->readAll();
        qDebug()<<"Данные";
    }
}

void TCPSocket::onDisconnect(){
    emit disconnected();
    exit(0);
}

void TCPSocket::run(){
    QTcpSocket tcpSocket;
    connect(&tcpSocket,SIGNAL(readyRead()), this, SLOT(onDataReceive()));
    if (!tcpSocket.setSocketDescriptor(socket->socketDescriptor())) {
        emit error(tcpSocket.errorString());
        return;
    }
    exec();
}
...
Рейтинг: 0 / 0
25.01.2014, 10:48
    #38537583
GorloPavel
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сокеты в Qt
Теперь нифига не работает прием данных.
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Сокеты в Qt / 10 сообщений из 10, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]