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

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

Страниц: [1] 2 3 4   Вниз
  Печать  
Автор Тема: QTCPSocket в отдельном потоке.  (Прочитано 31999 раз)
GPPsoft
Гость
« : Декабрь 22, 2013, 08:51 »

Здравствуйте. Как правильно заставить QTCPSocket принимать и обрабатывать данные в отдельном потоке? Сейчас у меня сделано так:
Код:
connect(tcpSocket,SIGNAL(connected()),this,SLOT(on_connected()));
connect(tcpSocket,SIGNAL(disconnected()),this,SLOT(on_disconnected()));
connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(on_data()));

Три сигнала... первые два меня устраивают в плане того что ни выполняются в потоке UI, но вот получение и обработка данных необходима в отдельном потоке. Как реализовать? Как я понимаю сейчас данные обрабатываются в UI потоке.
Код:
void MainWindow::on_data()
{
    while(tcpSocket->bytesAvailable())
    {
        QByteArray data=tcpSocket->readAll();
        packetSplitter->setByteArray(&data,data.length());
    }
}

Спасибо!
Записан
Bepec
Гость
« Ответ #1 : Декабрь 22, 2013, 11:53 »

Читаем про QThread.

Есть два способа.
1) создать класс с нужным вам функционалом, создать новый поток(QThread) и перенести его (moveToThread) в отдельный поток.

2) создать наследника от QThread и в нём в конструкторе сделать moveToThread(this). И в этом наследнике творите что хотите.

Оба способа равнозначны, единственно что в первом можно будет разделять поток и класс(отдельные сущности),а во втором они будут единым целом.

PS мне больше нравится второй из-за экономии сущностей. Задач по перебросам из потока в поток, для которых необходим первый способ мне ещё не встречалось.
Записан
Nidxogg
Гость
« Ответ #2 : Январь 14, 2014, 21:46 »

Читаем про QThread.
Есть два способа.
1) создать класс с нужным вам функционалом, создать новый поток(QThread) и перенести его (moveToThread) в отдельный поток.

2) создать наследника от QThread и в нём в конструкторе сделать moveToThread(this). И в этом наследнике творите что хотите.

Оба способа равнозначны, единственно что в первом можно будет разделять поток и класс(отдельные сущности),а во втором они будут единым целом.

PS мне больше нравится второй из-за экономии сущностей. Задач по перебросам из потока в поток, для которых необходим первый способ мне ещё не встречалось.
Несколько вопросов:
1)А можете показать, где в документации на QThread это написано? (про moveToThread)
2)По второму способу. Если без moveToThread вывести в контруктуре gui-класса и конструкторе наследника QThread 
Код:
qDebug()<<this->thread() 
- адреса одинаковые. Это потому что поток создан в объекте gui-класса? Или не так надо смотреть в каком потоке живет объект?
Если смотреть через
Цитировать
qDebug()<<QThread::currentThread();
, то разные

Вообщем запутался Непонимающий



Записан
Bepec
Гость
« Ответ #3 : Январь 14, 2014, 22:14 »

QThread - myThread;
До запуска потока
Код:
myThread.start()
всё живёт в потоке родителя.
После
Код:
myThread.start()
инициализируется поток, и метод run() начинает выполнятся в новом потоке.
moveToThread(this) в конструкторе переносит весь myThread в него самого Веселый Это интересный момент.
И после
Код:
myThread.start()
все слоты/методы будут вызываться в новом потоке.

В каком же потоке вызываться будет слот, зависит от типа соединения. Это тоже отдельная песня Улыбающийся

PS Я сам доходил до этого неделю, если не больше. Интернета не было, потому исписывал бумажку Веселый
Записан
Nidxogg
Гость
« Ответ #4 : Январь 14, 2014, 22:18 »

Цитировать
инициализируется поток, и метод run() начинает выполнятся в новом потоке.
зачем тогда moveToThread(this), если добились "желаемого?"
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #5 : Январь 14, 2014, 22:25 »

зачем тогда moveToThread(this), если добились "желаемого?"
Тут цель не в этом.
Стоит сразу отметить, что все потоки выполняются в одном адресном пространстве и реально никаких контекстов нет.
Их искусственно вводи Qt, что бы у него была возможность решать какой тип соединения connect использовать в том или ином случае, при испускании сигнала.
Т.е. если два объекта порожденных от QObject, находятся в одном контексте, то будет использоваться DirectConnect (прямой вызов метода), если в разных - QueueConnect (вызов через очередь событий нити получателя).
Записан
Bepec
Гость
« Ответ #6 : Январь 14, 2014, 22:26 »

Если не сделать moveToThread, то все прочие методы наследника от QThread будут выполняться в потоке родителя.
run - всегда в новом. Прочие - после moveToThread.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #7 : Январь 14, 2014, 22:30 »

Да, и про moveToThread забыл написать... Улыбающийся

При конструировании Q-объекта он начинает принадлежать контексту той нити в которой создан, а moveToThread перемещает этот объект в контекст указанной нити.
Записан
Nidxogg
Гость
« Ответ #8 : Январь 15, 2014, 06:18 »

Спасибо
Записан
stix357
Гость
« Ответ #9 : Декабрь 20, 2016, 08:05 »

QThread - myThread;
До запуска потока
Код:
myThread.start()
всё живёт в потоке родителя.
После
Код:
myThread.start()
инициализируется поток, и метод run() начинает выполнятся в новом потоке.
moveToThread(this) в конструкторе переносит весь myThread в него самого Веселый Это интересный момент.
И после
Код:
myThread.start()
все слоты/методы будут вызываться в новом потоке.

В каком же потоке вызываться будет слот, зависит от типа соединения. Это тоже отдельная песня Улыбающийся

PS Я сам доходил до этого неделю, если не больше. Интернета не было, потому исписывал бумажку Веселый
Мммм, попробую поднять тему.
Предложенные варианты:
Цитировать
Есть два способа.
1) создать класс с нужным вам функционалом, создать новый поток(QThread) и перенести его (moveToThread) в отдельный поток.

2) создать наследника от QThread и в нём в конструкторе сделать moveToThread(this). И в этом наследнике творите что хотите.

Оба способа равнозначны, единственно что в первом можно будет разделять поток и класс(отдельные сущности),а во втором они будут единым целом.

PS мне больше нравится второй из-за экономии сущностей. Задач по перебросам из потока в поток, для которых необходим первый способ мне ещё не встречалось.
Вариант 1- работает, но странно:
Код:
TCPClientQt::TCPClientQt(): QTcpSocket()
.....
m_pTcpSocket = new QTcpSocket(this);

отрабатываются сигналы
Код:
 connect(m_pTcpSocket, SIGNAL(connected()), SLOT(slotConnected()));
 connect(m_pTcpSocket, SIGNAL(disconnected()), SLOT(slotDisconnected()));
 connect(m_pTcpSocket, SIGNAL(readyRead()), SLOT(slotReadyRead()));

не отрабатывают
Код:
 connect(m_pTcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(slotError(QAbstractSocket::SocketError)));
 connect(m_pTcpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState socketState )),this, SLOT(slotStateChanged(QAbstractSocket::SocketState)));

Вариант 2 - не работает на Win7-32, Qt-4.8.1
Сокет запускается в основном потоке. Гуй виснет. При получении сокетом пакета.

Вариант 3 - создание наследника QTcpSocket в наследнике QThread в методе run() согласно рекомендациям Шлее
Код:
ReadData::ReadData(QObject *parent) :
    QThread(parent)
.....
void ReadData::run()
{
    try
    {

      m_Client=new TCPClientQt(this);
      exec();
    }catch(const std::exception& ex)
    {
        m_Result=-2;
    }
 }
работает аналогично варианту 1.

В чем мой косяк?
« Последнее редактирование: Декабрь 20, 2016, 08:16 от stix357 » Записан
Bepec
Гость
« Ответ #10 : Декабрь 20, 2016, 11:55 »

1) вы создали TCPSocket и указали ему родителя. И будет он жить теперь в потоке родителя (this). Перенос в поток вы не осуществили.
1*) отработка сигналов должна работать в любом случае, видимо вы где то ошиблись, что без полного кода проекта сказать невозможно.
2) Хз что вы там наделали, но явно всё неправильно. Приводите код, а не "я сделал, оно не работает, способ плохо, код не покажу, я идеален" Веселый
3) Опять таки нет полного кода Веселый Ничего сказать не могу.
Записан
stix357
Гость
« Ответ #11 : Декабрь 20, 2016, 12:14 »

1) вы создали TCPSocket и указали ему родителя. И будет он жить теперь в потоке родителя (this). Перенос в поток вы не осуществили.
1*) отработка сигналов должна работать в любом случае, видимо вы где то ошиблись, что без полного кода проекта сказать невозможно.
2) Хз что вы там наделали, но явно всё неправильно. Приводите код, а не "я сделал, оно не работает, способ плохо, код не покажу, я идеален" Веселый
3) Опять таки нет полного кода Веселый Ничего сказать не могу.
1 - нет, не так
Это в приложении
Код
C++ (Qt)
   ReadData *thread;
   TCPClientQt s_Client;
.....
   thread=new ReadData(this);
   QObject::connect(&s_Client,SIGNAL(sig_Connected()),this, SLOT(slotIsConnected()),Qt::AutoConnection);
   QObject::connect(&s_Client,SIGNAL(sig_newInfo()),this, SLOT(getNewInfo()),Qt::AutoConnection);
   QObject::connect(&s_Client,SIGNAL(sig_Disconnected()),this, SLOT(slotIsDisonnected()),Qt::AutoConnection);
   s_Client.moveToThread(thread);
 
В конструкторе наследника сокета :
Код
C++ (Qt)
//work
connect(m_pTcpSocket, SIGNAL(connected()), SLOT(slotConnected()));
connect(m_pTcpSocket, SIGNAL(disconnected()), SLOT(slotDisconnected()));
connect(m_pTcpSocket, SIGNAL(readyRead()), SLOT(slotReadyRead()));
//not work
connect(m_pTcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(slotError(QAbstractSocket::SocketError)));
connect(m_pTcpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState socketState )),this, SLOT(slotStateChanged(QAbstractSocket::SocketState)));
 
2) Хм, классы вывалить?
Портянка получится, но попробую %)
Код
C++ (Qt)
class ReadData : public QThread
{
   Q_OBJECT
 
private:
   int m_Result;
 
public:
   explicit ReadData(QObject *parent = 0);
   ~ReadData();
 
   void run();
 
signals:
 
public slots:
 
};
 
Код
C++ (Qt)
ReadData::ReadData(QObject *parent) :
   QThread(parent)
{
//moveToThread(this);
//&#1087;&#1088;&#1086;&#1073;&#1086;&#1074;&#1072;&#1083; &#1090;&#1091;&#1090;, &#1085;&#1086; &#1087;&#1086;&#1090;&#1086;&#1082; &#1089;&#1072;&#1084; &#1074; &#1089;&#1077;&#1073;&#1103; &#1083;&#1077;&#1079;&#1090;&#1100; &#1085;&#1077; &#1093;&#1086;&#1095;&#1077;&#1090; :)
m_Result=-1;
}
 
void ReadData::run()
{
   try
   {
     exec();
   }catch(const std::exception& ex)
   {
       m_Result=-2;
   }
}
 
ReadData::~ReadData()
{
 
}
 

 //Цикл нужен потому, что с сервера не все данные могут прийти одновременно.
 //Поэтому клиент должен быть в состоянии получать как весь блок целиком,
 //так и только часть блока или даже все блоки сразу.
//размер блока заранее не известен может и 2 к быть, а может и 20 к.
//промышленный контроллер после получения команды старт гонит цепочку байт (8 бит на датчик)
//предваряя посылку признаком начала, а при корректном завершении признак завершения передачи

Код
C++ (Qt)
class TCPClientQt : public QTcpSocket{
Q_OBJECT
 
public:
explicit TCPClientQt();
   ~TCPClientQt();
bool slotStartData(QString _cmdStart);
bool m_IsConnected;
int m_IsThread;//&#1077;&#1089;&#1083;&#1080; &#1074; &#1086;&#1090;&#1076;&#1077;&#1083;&#1100;&#1085;&#1086;&#1084; &#1087;&#1086;&#1090;&#1086;&#1082;&#1077;, &#1090;&#1086; &#1074;&#1099;&#1089;&#1090;&#1072;&#1074;&#1083;&#1103;&#1077;&#1084; 1
int m_RecivedBytes;//&#1089;&#1082;&#1086;&#1083;&#1100;&#1082;&#1086; &#1073;&#1072;&#1081;&#1090; &#1079;&#1072;&#1073;&#1088;&#1072;&#1083;&#1080; &#1080;&#1079; &#1073;&#1091;&#1092;&#1077;&#1088;&#1072;
QString m_StrInfo;
QString m_CmdCfg;
QString m_AnswerCfg;
QString m_CmdStart;
QString m_AnswerStart;
QString m_CmdStop;
QString m_AnswerStop;
QString m_CmdGetTimer;
QString m_CmdResetTimer;
QString m_CmdResetADC;
QTcpSocket *m_pTcpSocket;
QFile m_LogFile;
QString m_ApplPath;
QByteArray arrReadBlock;
//function
QByteArray getCurrentData();
private:
 
//&#1072;&#1076;&#1088;&#1077;&#1089; &#1080; &#1087;&#1086;&#1088;&#1090;
QString m_strHost;
int m_nPort;
//&#1101;&#1090;&#1086; &#1082;&#1086;&#1084;&#1072;&#1085;&#1076;&#1072;
bool isCmd;
//&#1079;&#1072;&#1074;&#1077;&#1088;&#1096;&#1077;&#1085;&#1080;&#1077; &#1076;&#1072;&#1085;&#1085;&#1099;&#1093;
bool isEnd;
//&#1089;&#1082;&#1086;&#1083;&#1100;&#1082;&#1086; &#1086;&#1078;&#1080;&#1076;&#1072;&#1077;&#1084;
uint ExpectedBytes;
//&#1089;&#1082;&#1086;&#1083;&#1100;&#1082;&#1086; &#1087;&#1086;&#1083;&#1091;&#1095;&#1080;&#1083;&#1080;
uint totalBytesRecived;
//&#1089;&#1082;&#1086;&#1083;&#1100;&#1082;&#1086; &#1079;&#1072;&#1073;&#1088;&#1072;&#1083;&#1080; &#1080;&#1079; &#1084;&#1072;&#1089;&#1089;&#1080;&#1074;&#1072;
uint currentPos;
 //QByteArray m_bufferRead;
 
signals:
 void sig_newInfo();
 void sig_Connected();
 void sig_Disconnected();
 
//private slots:
public slots:
void slotReadyRead();
void slotError (QAbstractSocket::SocketError);
void slotSendToServer(QString _cmdSend);
void slotConnected();
void slotDisconnected();
void slotStateChanged ( QAbstractSocket::SocketState socketState );
void slotConnectToServer(QString _ipHost);
void slotClearLog();
void slotCloseConnect();
 
};
 
Код
C++ (Qt)
TCPClientQt::TCPClientQt(): QTcpSocket()
//
{
m_strHost="192.168.1.7";//strHost;
m_nPort=32000;//nPort;
m_CmdCfg="+WIND:80:";//&#1082;&#1086;&#1085;&#1092;&#1080;&#1075;&#1091;&#1088;&#1072;&#1094;&#1080;&#1103; &#1087;&#1088;&#1077;&#1092;&#1080;&#1082;&#1089; &#1082;&#1086;&#1084;&#1072;&#1085;&#1076;&#1099;
m_AnswerCfg="+WIND:81:";//&#1082;&#1086;&#1085;&#1092;&#1080;&#1075;&#1091;&#1088;&#1072;&#1094;&#1080;&#1103; &#1087;&#1088;&#1077;&#1092;&#1080;&#1082;&#1089; &#1086;&#1090;&#1074;&#1077;&#1090;
m_CmdStart="+WIND:82:";//&#1089;&#1090;&#1072;&#1088;&#1090; &#1082;&#1086;&#1084;&#1072;&#1085;&#1076;&#1072;
m_AnswerStart="+WIND:83:";//&#1089;&#1090;&#1072;&#1088;&#1090; &#1087;&#1088;&#1077;&#1092;&#1080;&#1082;&#1089; &#1086;&#1090;&#1074;&#1077;&#1090;
m_CmdStop="+WIND:84:";//&#1089;&#1090;&#1086;&#1087; &#1082;&#1086;&#1084;&#1072;&#1085;&#1076;&#1072;
m_AnswerStop="+WIND:85:";//&#1089;&#1090;&#1086;&#1087; &#1087;&#1088;&#1077;&#1092;&#1080;&#1082;&#1089; &#1086;&#1090;&#1074;&#1077;&#1090;
m_CmdGetTimer="+WIND:89:";//&#1079;&#1072;&#1087;&#1088;&#1086;&#1089; &#1090;&#1072;&#1081;&#1084;&#1077;&#1088;&#1072;
m_CmdResetTimer="+WIND:88:";//&#1089;&#1073;&#1088;&#1086;&#1089; &#1090;&#1072;&#1081;&#1084;&#1077;&#1088;&#1072;
m_CmdResetADC="+WIND:99:";//&#1089;&#1073;&#1088;&#1086;&#1089; &#1040;&#1062;&#1055;
m_pTcpSocket = new QTcpSocket(this);
m_ApplPath=QCoreApplication::applicationDirPath();
m_LogFile.setFileName(m_ApplPath+"/TCPClientQt.log");
m_StrInfo="Empty";
m_IsThread=0;
m_RecivedBytes=0;
m_IsConnected=false;
//&#1087;&#1088;&#1080;&#1079;&#1085;&#1072;&#1082; &#1085;&#1072;&#1083;&#1080;&#1095;&#1080;&#1103; &#1082;&#1086;&#1084;&#1072;&#1085;&#1076;&#1099;
isCmd=false;
isEnd=false;
ExpectedBytes=0;
totalBytesRecived=0;
currentPos=0;
arrReadBlock.clear();
connect(m_pTcpSocket, SIGNAL(connected()), SLOT(slotConnected()));
connect(m_pTcpSocket, SIGNAL(disconnected()), SLOT(slotDisconnected()));
connect(m_pTcpSocket, SIGNAL(readyRead()), SLOT(slotReadyRead()));
connect(m_pTcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(slotError(QAbstractSocket::SocketError)));
connect(m_pTcpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState socketState )),this, SLOT(slotStateChanged(QAbstractSocket::SocketState)));
}
 
void TCPClientQt::slotClearLog()
{
   //m_ptxtInfo->clear();
}
 
void TCPClientQt::slotCloseConnect()
{
 
   if(m_pTcpSocket->state() == QAbstractSocket::UnconnectedState)
   {
       m_StrInfo="&#1053;&#1077;&#1090; &#1086;&#1090;&#1082;&#1088;&#1099;&#1090;&#1086;&#1075;&#1086; &#1089;&#1086;&#1082;&#1077;&#1090;&#1072;";
   }else{
       m_pTcpSocket->close();
       m_IsConnected=false;
       m_StrInfo="&#1057;&#1086;&#1082;&#1077;&#1090; &#1079;&#1072;&#1082;&#1088;&#1099;&#1090;";
   }
   if(m_LogFile.isOpen())
   {
    QByteArray arr=m_StrInfo.toAscii()+"\n";
     m_LogFile.write(arr);
     m_LogFile.close();
   }
   emit sig_Disconnected();
   emit sig_newInfo();
}
 
void TCPClientQt::slotSendToServer(QString _cmdSend)
{
   if(m_pTcpSocket->state() == QAbstractSocket::ConnectedState)
   {
      m_StrInfo=QTime::currentTime().toString("hh:mm:ss.zzz")+" &#1054;&#1090;&#1087;&#1088;&#1072;&#1074;&#1082;&#1072; &#1082;&#1086;&#1084;&#1072;&#1085;&#1076;&#1099; "+_cmdSend;
      emit sig_newInfo();
      if(m_LogFile.isOpen())
      {
       QByteArray arr=m_StrInfo.toAscii()+"\n";
        m_LogFile.write(arr);
      }
      currentPos=0;
   }else
   {
     m_StrInfo=QTime::currentTime().toString("hh:mm:ss.zzz")+" &#1053;&#1077;&#1090; &#1086;&#1090;&#1082;&#1088;&#1099;&#1090;&#1086;&#1075;&#1086; &#1089;&#1086;&#1077;&#1076;&#1080;&#1085;&#1077;&#1085;&#1080;&#1103;!";
     emit sig_newInfo();
     return;
   }
QByteArray arrSend;
QString cmdSend=_cmdSend;
arrSend=cmdSend.toAscii();
m_pTcpSocket->write(arrSend);
 if(m_LogFile.isOpen())
 {
  QByteArray arr=m_StrInfo.toAscii()+"\n";
   m_LogFile.write(arr);
 }
}
 
 
void TCPClientQt::slotReadyRead()
{
//&#1076;&#1086;&#1089;&#1090;&#1091;&#1087;&#1085;&#1086; &#1073;&#1072;&#1081;&#1090; &#1074; &#1090;&#1077;&#1082;&#1091;&#1097;&#1080;&#1081; &#1084;&#1086;&#1084;&#1077;&#1085;&#1090;
uint bytesAvailable=0;
//&#1087;&#1086;&#1083;&#1091;&#1095;&#1077;&#1085;&#1085;&#1099;&#1077; &#1090;&#1077;&#1082;&#1091;&#1097;&#1080;&#1077; &#1073;&#1072;&#1081;&#1090;&#1099;
QByteArray currArr;
//&#1076;&#1083;&#1103; &#1087;&#1077;&#1088;&#1077;&#1075;&#1086;&#1085;&#1072; &#1074; &#1089;&#1090;&#1088;&#1086;&#1082;&#1091;, &#1077;&#1089;&#1083;&#1080; &#1082;&#1086;&#1084;&#1072;&#1085;&#1076;&#1072; &#1080;&#1083;&#1080; &#1086;&#1090;&#1074;&#1077;&#1090;
QByteArray strArr;
//&#1087;&#1086;&#1083;&#1091;&#1095;&#1077;&#1085;&#1085;&#1072;&#1103; &#1089;&#1090;&#1088;&#1086;&#1082;&#1072; &#1086;&#1090;&#1074;&#1077;&#1090;&#1072; &#1087;&#1086; &#1082;&#1086;&#1084;&#1072;&#1085;&#1076;&#1077; &#1089;&#1090;&#1072;&#1088;&#1090;
QByteArray strAnswerStart;
//&#1088;&#1072;&#1079;&#1084;&#1077;&#1088; &#1086;&#1090;&#1074;&#1077;&#1090;&#1072; &#1074; &#1073;&#1072;&#1081;&#1090;&#1072;&#1093;
//&#1103;&#1103;
int pos=-1;
//&#1088;&#1072;&#1079;&#1084;&#1077;&#1088; &#1082;&#1086;&#1084;&#1072;&#1085;&#1076;&#1099; &#1089; &#1086;&#1090;&#1074;&#1077;&#1090;&#1086;&#1084;
uint sizeCmd=20;
//int bytesArray=0;
//&#1062;&#1080;&#1082;&#1083; &#1085;&#1091;&#1078;&#1077;&#1085; &#1087;&#1086;&#1090;&#1086;&#1084;&#1091;, &#1095;&#1090;&#1086; &#1089; &#1089;&#1077;&#1088;&#1074;&#1077;&#1088;&#1072; &#1085;&#1077; &#1074;&#1089;&#1077; &#1076;&#1072;&#1085;&#1085;&#1099;&#1077; &#1084;&#1086;&#1075;&#1091;&#1090; &#1087;&#1088;&#1080;&#1081;&#1090;&#1080; &#1086;&#1076;&#1085;&#1086;&#1074;&#1088;&#1077;&#1084;&#1077;&#1085;&#1085;&#1086;.
//&#1055;&#1086;&#1101;&#1090;&#1086;&#1084;&#1091; &#1082;&#1083;&#1080;&#1077;&#1085;&#1090; &#1076;&#1086;&#1083;&#1078;&#1077;&#1085; &#1073;&#1099;&#1090;&#1100; &#1074; &#1089;&#1086;&#1089;&#1090;&#1086;&#1103;&#1085;&#1080;&#1080; &#1087;&#1086;&#1083;&#1091;&#1095;&#1072;&#1090;&#1100; &#1082;&#1072;&#1082; &#1074;&#1077;&#1089;&#1100; &#1073;&#1083;&#1086;&#1082; &#1094;&#1077;&#1083;&#1080;&#1082;&#1086;&#1084;,
//&#1090;&#1072;&#1082; &#1080; &#1090;&#1086;&#1083;&#1100;&#1082;&#1086; &#1095;&#1072;&#1089;&#1090;&#1100; &#1073;&#1083;&#1086;&#1082;&#1072; &#1080;&#1083;&#1080; &#1076;&#1072;&#1078;&#1077; &#1074;&#1089;&#1077; &#1073;&#1083;&#1086;&#1082;&#1080; &#1089;&#1088;&#1072;&#1079;&#1091;.
m_RecivedBytes=0;
isEnd=false;
isCmd=false;
if(m_pTcpSocket->state() == QAbstractSocket::UnconnectedState)
{
 
    m_StrInfo=QTime::currentTime().toString("hh:mm:ss.zzz")+" UnconnectedState";
    if(m_LogFile.isOpen())
    {
     QByteArray arr=m_StrInfo.toAscii()+"\n";
      m_LogFile.write(arr);
    }
    emit sig_newInfo();
   return;
}
 while(true){
 
   strArr.clear();
   currArr.clear();
       bytesAvailable=m_pTcpSocket->bytesAvailable();
       if(bytesAvailable < sizeof(quint16)){
           //&#1085;&#1077;&#1090; &#1076;&#1072;&#1085;&#1085;&#1099;&#1093;
           m_StrInfo=QTime::currentTime().toString("hh:mm:ss.zzz")+" bytesAvailable 0 &#1055;&#1091;&#1089;&#1090;&#1086;";
           if(m_LogFile.isOpen())
           {
            QByteArray arr=m_StrInfo.toAscii()+"\n";
             m_LogFile.write(arr);
           }
           emit sig_newInfo();
           break;
       }else
       {
        //
       }
       //&#1077;&#1089;&#1090;&#1100; &#1076;&#1072;&#1085;&#1085;&#1099;&#1077;
       totalBytesRecived=totalBytesRecived+bytesAvailable;
           currArr=m_pTcpSocket->read(bytesAvailable);
           arrReadBlock.append(currArr);
           //&#1077;&#1089;&#1083;&#1080; &#1082;&#1091;&#1089;&#1086;&#1095;&#1077;&#1082; &#1084;&#1077;&#1085;&#1077;&#1077; 20 &#1073;&#1072;&#1081;&#1090;
           if(bytesAvailable<sizeCmd && !currArr.contains(m_AnswerStop.toAscii())){
               strArr=currArr.left(sizeCmd);
               //&#1086;&#1090;&#1074;&#1077;&#1090; &#1082;&#1086;&#1085;&#1092;&#1080;&#1075;&#1091;&#1088;&#1072;&#1094;&#1080;&#1080;
               if(currArr.contains(m_AnswerCfg.toAscii()))
               {
                 strArr=currArr.left(17);
                 m_StrInfo=QTime::currentTime().toString("hh:mm:ss.zzz")+" Answer CFG "
                                    +QString::fromAscii(strArr);
                 if(m_LogFile.isOpen())
                 {
                  QByteArray arr=m_StrInfo.toAscii()+"\n";
                   m_LogFile.write(arr);
                 }
                 emit sig_newInfo();
               }else
               {
                 //
               }
               if(currArr.contains(m_CmdGetTimer.toAscii()))
               {
                   strArr=currArr.left(20);
                   m_StrInfo=QTime::currentTime().toString("hh:mm:ss.zzz")+" Answer GetTimer "
                                      +QString::fromAscii(strArr);
                   if(m_LogFile.isOpen())
                   {
                    QByteArray arr=m_StrInfo.toAscii()+"\n";
                     m_LogFile.write(arr);
                   }
                   emit sig_newInfo();                  
               }else
               {
                 //
               }
               if(currArr.contains(m_CmdResetTimer.toAscii()))
               {
                   strArr=currArr.left(20);
                   m_StrInfo=QTime::currentTime().toString("hh:mm:ss.zzz")+" Answer ResetTimer "
                                      +QString::fromAscii(strArr);
                   if(m_LogFile.isOpen())
                   {
                    QByteArray arr=m_StrInfo.toAscii()+"\n";
                     m_LogFile.write(arr);
                   }
                   emit sig_newInfo();
               }else
               {
                 //
               }
               isCmd=true;
               break;
           }else{
               m_StrInfo=QTime::currentTime().toString("hh:mm:ss.zzz")
                               +" bytesAvailable "+QString::number(bytesAvailable);
               if(m_LogFile.isOpen())
               {
                QByteArray arr=m_StrInfo.toAscii()+"\n";
                 m_LogFile.write(arr);
               }
               emit sig_newInfo();
           }
           //&#1077;&#1089;&#1090;&#1100; &#1085;&#1072;&#1095;&#1072;&#1083;&#1086; +WIND:83:
           if(currArr.contains(m_AnswerStart.toAscii()))
           {
               isCmd=false;
               pos=17;
               strArr=currArr.left(pos);
               m_StrInfo=QTime::currentTime().toString("hh:mm:ss.zzz")
                                  +" Begin "+QString::fromAscii(strArr);
               if(m_LogFile.isOpen())
               {
                QByteArray arr=m_StrInfo.toAscii()+"\n";
                 m_LogFile.write(arr);
               }
               //&#1074;&#1099;&#1103;&#1089;&#1085;&#1103;&#1077;&#1084;, &#1089;&#1082;&#1086;&#1083;&#1100;&#1082;&#1086; &#1073;&#1072;&#1081;&#1090; &#1076;&#1086;&#1083;&#1078;&#1085;&#1086; &#1087;&#1088;&#1080;&#1083;&#1077;&#1090;&#1077;&#1090;&#1100; &#1080;&#1089;&#1093;&#1086;&#1076;&#1103; &#1080;&#1079; &#1079;&#1072;&#1075;&#1086;&#1083;&#1086;&#1074;&#1082;&#1072; &#1086;&#1090;&#1074;&#1077;&#1090;&#1072; &#1089;&#1077;&#1088;&#1074;&#1077;&#1088;&#1072; +WIND:83:XX:XX:XX
               //&#1088;&#1072;&#1079;&#1073;&#1086;&#1088; &#1079;&#1072;&#1075;&#1086;&#1083;&#1086;&#1074;&#1082;&#1072;
               strAnswerStart.clear();
               strAnswerStart.append(strArr.data()[9]);
               strAnswerStart.append(strArr.data()[10]);
               int F=strAnswerStart.toInt();
               strAnswerStart.clear();
               strAnswerStart.append(strArr.data()[12]);
               strAnswerStart.append(strArr.data()[13]);
               int C=strAnswerStart.toInt();
               strAnswerStart.clear();
               strAnswerStart.append(strArr.data()[15]);
               strAnswerStart.append(strArr.data()[16]);
               int T=strAnswerStart.toInt();
               strAnswerStart.clear();
               //&#1089;&#1082;&#1086;&#1083;&#1100;&#1082;&#1086; &#1073;&#1072;&#1081;&#1090;
               ExpectedBytes=F*1000*C*T+34;
               emit sig_newInfo();
           }else{
               //
           }
           //&#1077;&#1089;&#1090;&#1100; &#1082;&#1086;&#1085;&#1077;&#1094;
           if(currArr.contains(m_AnswerStop.toAscii()))
           {
               isEnd=true;
               pos=arrReadBlock.indexOf(m_AnswerStop);
               strArr=currArr.right(17);
               m_StrInfo=QTime::currentTime().toString("hh:mm:ss.zzz")
                                  +" End "+QString::fromAscii(strArr);
               if(m_LogFile.isOpen())
               {
                QByteArray arr=m_StrInfo.toAscii()+"\n";
                 m_LogFile.write(arr);
               }
               emit sig_newInfo();
               break;
 
           }else{
             //
           }
 
       //&#1080; &#1085;&#1072; &#1085;&#1086;&#1074;&#1099;&#1081; &#1094;&#1080;&#1082;&#1083; &#1087;&#1086;&#1089;&#1083;&#1077; &#1086;&#1078;&#1080;&#1076;&#1072;&#1085;&#1080;&#1103;
       m_pTcpSocket->waitForReadyRead(550);//&#1074;&#1088;&#1077;&#1084;&#1103; &#1086;&#1078;&#1080;&#1076;&#1072;&#1085;&#1080;&#1103; &#1086;&#1095;&#1077;&#1088;&#1077;&#1076;&#1085;&#1086;&#1075;&#1086; &#1087;&#1072;&#1082;&#1077;&#1090;&#1072; &#1074;  &#1084;&#1089;
}
 //&#1079;&#1072;&#1074;&#1077;&#1088;&#1096;&#1077;&#1085;&#1080;&#1077; &#1087;&#1088;&#1080;&#1077;&#1084;&#1072; &#1076;&#1072;&#1085;&#1085;&#1099;&#1093;
 if(isEnd)
 {
   m_StrInfo=QTime::currentTime().toString("hh:mm:ss.zzz")
                     +" Total Expected: "
                     +QString::number(ExpectedBytes);
   if(m_LogFile.isOpen())
   {
    QByteArray arr=m_StrInfo.toAscii()+"\n";
     m_LogFile.write(arr);
   }
   emit sig_newInfo();
    m_StrInfo=QTime::currentTime().toString("hh:mm:ss.zzz")
                    +" Total Recive: "
                    +QString::number(totalBytesRecived);
    if(m_LogFile.isOpen())
    {
     QByteArray arr=m_StrInfo.toAscii()+"\n";
      m_LogFile.write(arr);
    }
   emit sig_newInfo();
   m_StrInfo=QTime::currentTime().toString("hh:mm:ss.zzz")
                    +" Lost: "
                    +QString::number(ExpectedBytes-totalBytesRecived);
   if(m_LogFile.isOpen())
   {
    QByteArray arr=m_StrInfo.toAscii()+"\n";
     m_LogFile.write(arr);
   }
   emit sig_newInfo();
   isEnd=false;
 }
totalBytesRecived=0;
ExpectedBytes=0;
arrReadBlock.clear();
return;
}
 
 
 
void TCPClientQt::slotError(QAbstractSocket::SocketError err)
{
QString strError =
   (err == QAbstractSocket::HostNotFoundError ?
   "The host was not found. "+QString::number(-1) :
   err == QAbstractSocket::RemoteHostClosedError ?
   "The remote host is closed. "+QString::number(-2) :
   err == QAbstractSocket::ConnectionRefusedError ?
   "The connection was refused. "+QString::number(-3) :
   QString(m_pTcpSocket->errorString())
);
 
   m_StrInfo=QTime::currentTime().toString("hh:mm:ss.zzz")+" Error: "+strError;
   if(m_LogFile.isOpen())
   {
   QByteArray arr=m_StrInfo.toAscii()+"\n";
   m_LogFile.write(arr);
   }
emit sig_newInfo();
}
 
void TCPClientQt::slotStateChanged(QAbstractSocket::SocketState socketState)
{
    m_StrInfo=QTime::currentTime().toString("hh:mm:ss.zzz")+" StateChanged";
   if(m_LogFile.isOpen())
   {
     QByteArray arr=m_StrInfo.toAscii()+"\n";
     m_LogFile.write(arr);
   }
}
 
void TCPClientQt::slotConnected()
{
 
   m_StrInfo=QTime::currentTime().toString("hh:mm:ss.zzz")+" Connected";
   m_IsConnected=true;
   emit sig_Connected();
   emit sig_newInfo();
   if(!m_LogFile.isOpen())
   {
       m_LogFile.open(QIODevice::ReadWrite);
       m_LogFile.seek(m_LogFile.size());
       QByteArray arr=m_StrInfo.toAscii()+"\n";
       m_LogFile.write(arr);
   }
}
 
void TCPClientQt::slotDisconnected()
{
   m_StrInfo=m_StrInfo=QTime::currentTime().toString("hh:mm:ss.zzz")+" Disconnected";
   if(m_LogFile.isOpen())
   {
    QByteArray arr=m_StrInfo.toAscii()+"\n";
     m_LogFile.write(arr);
     m_LogFile.close();
   }
   m_IsConnected=false;
   emit sig_Disconnected();
}
 
QByteArray TCPClientQt::getCurrentData()
{
   QByteArray result;
   .....
   return result;
}
 
void TCPClientQt::slotConnectToServer(QString _ipHost)
{
   if(m_pTcpSocket!=0)
   {
   if(m_pTcpSocket->state() == QAbstractSocket::UnconnectedState)
   {
       m_strHost=_ipHost;
       m_pTcpSocket->connectToHost(m_strHost, m_nPort);
   }else{
       m_StrInfo=QTime::currentTime().toString("hh:mm:ss.zzz")+" &#1045;&#1089;&#1090;&#1100; &#1086;&#1090;&#1082;&#1088;&#1099;&#1090;&#1086;&#1077; &#1089;&#1086;&#1077;&#1076;&#1080;&#1085;&#1077;&#1085;&#1080;&#1077;";
       emit sig_newInfo();
   }
   }else
   {
       //
   }
   if(m_LogFile.isOpen())
   {
       QByteArray arr=m_StrInfo.toAscii()+"\n";
       m_LogFile.write(arr);
   }
}
 
TCPClientQt::~ TCPClientQt ()
{
   if(m_LogFile.isOpen())
   {
     m_LogFile.close();
   }
   if(m_pTcpSocket!=0)
   { if(m_pTcpSocket->state() != QAbstractSocket::UnconnectedState)
       {
        m_pTcpSocket->close();
       }else
       {
           //
       }
       m_pTcpSocket=0;
   }
}
 

Блин, все комменты на русском злобно перегнало в другую кодировку
Как побороть не знаю. Грустный

А если в конструкторе потока создать сокет, и попытаться поток сам в себя перенести, он продолжает жить в основном потоке

Код
C++ (Qt)
ReadData::ReadData(QObject *parent) :
   QThread(parent)
{
 
m_Client=new TCPClientQt(this);
QObject::connect(m_Client,SIGNAL(sig_Connected()),this->parent(), SLOT(slotIsConnected()),Qt::AutoConnection);
QObject::connect(m_Client,SIGNAL(sig_newInfo()),this->parent(), SLOT(getNewInfo()),Qt::AutoConnection);
QObject::connect(m_Client,SIGNAL(sig_Disconnected()),this->parent(), SLOT(slotIsDisonnected()),Qt::AutoConnection);
moveToThread(this);
}
//&#1090;&#1077;&#1089;&#1090; &#1082;&#1086;&#1076;&#1080;&#1088;&#1086;&#1074;&#1082;&#1080;
 
« Последнее редактирование: Декабрь 20, 2016, 18:49 от stix357 » Записан
stix357
Гость
« Ответ #12 : Декабрь 21, 2016, 11:18 »

Далее:
то что
не отрабатывает
Код
C++ (Qt)
void TCPClientQt::slotError(QAbstractSocket::SocketError err)
 
наврал
отрабатывает при попытке получения пакета в
Код
C++ (Qt)
void
connect(m_pTcpSocket, SIGNAL(readyRead()), SLOT(slotReadyRead()));
 
только по Network operation timed out
На остальные ошибки  ... типо плевать
Хоть IP задавай несуществующий, хоть порт левый ....
тупо отправляется SYNC и полный завис (смотрю в Tcpview)
ClientADC_QT.exe   1844   TCP   pc-win7060.dlink   50120   192.168.1.200   32000   SYN_SENT                              
и в Wireshark чисто, чисто, чисто
А при запуске из основного потока с ГУИ все робит ...... парадокс
« Последнее редактирование: Декабрь 21, 2016, 14:18 от stix357 » Записан
stix357
Гость
« Ответ #13 : Декабрь 29, 2016, 09:05 »

Цитата: Bepec
2) создать наследника от QThread и в нём в конструкторе сделать moveToThread(this). И в этом наследнике творите что хотите.
Вообще довольно спорный способ переносить объект QThread в самого себя в конструкторе.
До отработки конструктора объект еще не существует.
Записан
Bepec
Гость
« Ответ #14 : Декабрь 29, 2016, 13:18 »

Неверно.
Сначала создаётся объект.
Потом вызывается конструктор.
Всё есть.
Записан
Страниц: [1] 2 3 4   Вверх
  Печать  
 
Перейти в:  


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