QSocketNotifier: socket notifiers cannot be enabled from another thread
-
main.cpp
ds = new QThread();
mythread = new readthread(tcpsocket);
mythread->moveToThread(ds);
connect(this,&readData::readstart,mythread,&readthread::readWork);
ds->start();
emit readstart(stopped,readCapacity);readthread.cpp
readthread::readthread(QTcpSocket *s, QObject *parent)
: QObject{parent}
{
tcpsocket = s;
}
void readthread::readWork(bool stopped, int readCapacity)
{
while(stoopped)
{
tcpsocket->write(commandData);
if(tcpsocket->bytesAvailable() >= 1024)
{
time_wait = 0;
Buf += tcpsocket->read(1024);
}
}
}
Error message when sending command:QSocketNotifier: socket notifiers cannot be enabled from another thread.The program runs normally, but after looping for a period of time, there may be unread data in the buffer, but read() cannot be reached, causing the program to get stuck in the read() functionSo, pass the socket into a sub thread through movtothread:
main.cpp
ds = new QThread();
mythread = new readthread(tcpsocket);
tcpsocket->moveToThread(ds);
mythread->moveToThread(ds);
connect(this,&readData::readstart,mythread,&readthread::readWork);
ds->start();
emit readstart(stopped,readCapacity);readthread.cpp
readthread::readthread(QTcpSocket *s, QObject *parent)
: QObject{parent}
{
tcpsocket = s;
}
void readthread::readWork(bool stopped, int readCapacity)
{
while(stoopped)
{
tcpsocket->write(commandData);
if(tcpsocket->bytesAvailable() >= 1024)
{
time_wait = 0;
Buf += tcpsocket->read(1024);
}
}
}
no error message when sending instructions,However, when reading data, it was found that the buffer could not receive the data, and the readable data was 0 (confirming that there was data sent back)May I ask how to solve this -
main.cpp
ds = new QThread();
mythread = new readthread(tcpsocket);
mythread->moveToThread(ds);
connect(this,&readData::readstart,mythread,&readthread::readWork);
ds->start();
emit readstart(stopped,readCapacity);readthread.cpp
readthread::readthread(QTcpSocket *s, QObject *parent)
: QObject{parent}
{
tcpsocket = s;
}
void readthread::readWork(bool stopped, int readCapacity)
{
while(stoopped)
{
tcpsocket->write(commandData);
if(tcpsocket->bytesAvailable() >= 1024)
{
time_wait = 0;
Buf += tcpsocket->read(1024);
}
}
}
Error message when sending command:QSocketNotifier: socket notifiers cannot be enabled from another thread.The program runs normally, but after looping for a period of time, there may be unread data in the buffer, but read() cannot be reached, causing the program to get stuck in the read() functionSo, pass the socket into a sub thread through movtothread:
main.cpp
ds = new QThread();
mythread = new readthread(tcpsocket);
tcpsocket->moveToThread(ds);
mythread->moveToThread(ds);
connect(this,&readData::readstart,mythread,&readthread::readWork);
ds->start();
emit readstart(stopped,readCapacity);readthread.cpp
readthread::readthread(QTcpSocket *s, QObject *parent)
: QObject{parent}
{
tcpsocket = s;
}
void readthread::readWork(bool stopped, int readCapacity)
{
while(stoopped)
{
tcpsocket->write(commandData);
if(tcpsocket->bytesAvailable() >= 1024)
{
time_wait = 0;
Buf += tcpsocket->read(1024);
}
}
}
no error message when sending instructions,However, when reading data, it was found that the buffer could not receive the data, and the readable data was 0 (confirming that there was data sent back)May I ask how to solve this@bxrs
Please use the forum's Code tags (</>
toolbar button) when posting blocks of code.While you await a better answer. I can see this is not your actual code, which does not help. You write data to the socket and then immediately test for a response with >= 1024 bytes, without any delay. And if that is not there you keep resending the data, which does not sound helpful.
-
@bxrs
Please use the forum's Code tags (</>
toolbar button) when posting blocks of code.While you await a better answer. I can see this is not your actual code, which does not help. You write data to the socket and then immediately test for a response with >= 1024 bytes, without any delay. And if that is not there you keep resending the data, which does not sound helpful.
@JonB while(0 < thr_readCapacity)
{
QApplication::processEvents();
if(!thr_stopped)
{
tcpsocket->write(commandData);if(send_command(commandData)) { qDebug() << "EthernetRequest"; while(!thr_stopped) { while(thr_tcpsocket->bytesAvailable() < 1024) { QThread::msleep(10); time_wait++; if(time_wait >= 500) { qDebug() << "time_over"; thr_stopped = true; break; } } readlen = thr_tcpsocket->read(receivebytes.data(), 1024); time_wait = 0; if(readlen == 1024)//data.size() - count >= readlen { data.replace(count,readlen,receivebytes); count += readlen; readlen = 0; qDebug() << "readcount" << count; } else { qDebug() << "read_less"; thr_stopped = true; break; } if(count >= 65536)//count >= data.size() { if(thr_file->isOpen()) { thr_file->write(data); } thr_readCapacity -= 64; js++; qDebug() << "bc" << js; // readvalue += 64; // progressDialog.setValue(readvalue); count = 0; break; } } } else { thr_stopped = true; break; } } else { break; } } qDebug() << "while_stop"; thr_tcpsocket->moveToThread(QApplication::instance()->thread()); emit compelet();
}
In fact, each time 64k data is received in a loop, when TCP leaves the main thread message QSocket Notify: socket notifiers cannot be enabled from another thread, There may be a situation where instructions can be sent, but data cannot be read from the buffer when receiving data. When TCP enters a sub thread, there are no errors when issuing instructions, but the read buffer cannot receive data -
@JonB while(0 < thr_readCapacity)
{
QApplication::processEvents();
if(!thr_stopped)
{
tcpsocket->write(commandData);if(send_command(commandData)) { qDebug() << "EthernetRequest"; while(!thr_stopped) { while(thr_tcpsocket->bytesAvailable() < 1024) { QThread::msleep(10); time_wait++; if(time_wait >= 500) { qDebug() << "time_over"; thr_stopped = true; break; } } readlen = thr_tcpsocket->read(receivebytes.data(), 1024); time_wait = 0; if(readlen == 1024)//data.size() - count >= readlen { data.replace(count,readlen,receivebytes); count += readlen; readlen = 0; qDebug() << "readcount" << count; } else { qDebug() << "read_less"; thr_stopped = true; break; } if(count >= 65536)//count >= data.size() { if(thr_file->isOpen()) { thr_file->write(data); } thr_readCapacity -= 64; js++; qDebug() << "bc" << js; // readvalue += 64; // progressDialog.setValue(readvalue); count = 0; break; } } } else { thr_stopped = true; break; } } else { break; } } qDebug() << "while_stop"; thr_tcpsocket->moveToThread(QApplication::instance()->thread()); emit compelet();
}
In fact, each time 64k data is received in a loop, when TCP leaves the main thread message QSocket Notify: socket notifiers cannot be enabled from another thread, There may be a situation where instructions can be sent, but data cannot be read from the buffer when receiving data. When TCP enters a sub thread, there are no errors when issuing instructions, but the read buffer cannot receive data -
@bxrs Why this dirty hacks with processEvents and sleep and what not if you could simply rely on assynchronous nature of Qt?! You also would not have to mess around with threads.
@jsulm QApplication::processEvents(); Will it cause the program to crash? If you want to modify the flag thr_stopped in another slot function while reading while while, but while still occupying the thread, how can you exit the loop? Thank you for your answer
-
@jsulm QApplication::processEvents(); Will it cause the program to crash? If you want to modify the flag thr_stopped in another slot function while reading while while, but while still occupying the thread, how can you exit the loop? Thank you for your answer
-
-
@JonB Thank you for your response.
But without using threads, won't the while loop cause the program to block?@bxrs
What "while" loop? You won't have one. No blocking, no waiting! The asynchronous way of doing things is: send your data to device, put a slot onreadyRead()
, accumulate whatever is received into a (member variable, so it persists) buffer (you must not assume one call will receive 1024 bytes or whatever, Qt only guarantees you will get 1 or more bytes whenreadyRead()
is called), check to see if 1024 bytes or whatever for a "complete message". If so, remove the 1024/message bytes from the "pending" buffer, emit your own signal (likemessageReceived(bytes)
) with that data, attach a slot to do whatever on completed signal. That is how we do asynchronous stuff without blocking or using a thread.