powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Сокеты в Qt
10 сообщений из 10, страница 1 из 1
Сокеты в Qt
    #38536250
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте. Мне нужно чтобы прием и обработка данных выполнялись в отдельном потоке. А оправку данных я мог выполнять из любого потока имеющего указатель или ссылку на 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
Сокеты в Qt
    #38536263
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробовал так. Не знаю насколько это правильно. Какие проблемы могут быть при таком раскладе?

.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
Сокеты в Qt
    #38536271
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообщем вот что получилось. Чтение и обработка данных в отдельном потоке. Может кому-то пригодиться. Исправления-добавления приветствуются. Вроде работает :)

.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
Сокеты в Qt
    #38536281
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нашел проблему... Если вызвать socket->disconnectFromHost(), то поток продолжает работать. Как быть?
...
Рейтинг: 0 / 0
Сокеты в Qt
    #38536460
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Никто не знает?
...
Рейтинг: 0 / 0
Сокеты в Qt
    #38537325
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сокет и поток это две разные вещи.
...
Рейтинг: 0 / 0
Сокеты в Qt
    #38537543
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White OwlСокет и поток это две разные вещи.
Да, но сокет закрыт, а поток висит на waitForReadyRead
...
Рейтинг: 0 / 0
Сокеты в Qt
    #38537545
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ты закрываешь сокет в одном потоке и надеешься что в другом потоке waitForReadyRead сработает?
Не сработает.
...
Рейтинг: 0 / 0
Сокеты в Qt
    #38537574
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Сокеты в Qt
    #38537583
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Теперь нифига не работает прием данных.
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Сокеты в Qt
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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