can't sending data outside qtcpsocket thread
-
Hi,
anyone can help me about qtcpsocket with qthread after this .i want to send message over qtcpsocket, but i don't know why i got error in Application logs
error : QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread
here is the readyRead() function :
void UpdataServerThread::readyRead() { qDebug()<<updata_socket; qDebug()<<"connected_client_socket => "<<connected_client_socket; qDebug()<<"connected_client_ip => "<<connected_client_ip; QByteArray Data = updata_socket->readLine(); QJsonDocument document = QJsonDocument::fromJson(Data.data()); QJsonObject object = document.object(); //qDebug()<<"current thread :"<<QThread::currentThread()<<" DEVICE::"<<updata_socket->peerAddress()<<"in : "<<Data.data(); //authorize device if(Data.contains("devNumber")){ connected_client_ip.insert(updata_socket->peerAddress(),object.value("devNumber").toString()); QString str = "{\"msg\":\"Device registered successfully.\",\"timestamp\":"+QString::number(QDateTime::currentSecsSinceEpoch())+"}"; QByteArray registered_device = str.toUtf8(); ((QTcpSocket*)connected_client_socket.value(updata_socket->peerAddress()))->write(registered_device); } qDebug()<<"connected_client_ip::"<<connected_client_ip; }
I've read topic similar topic like this, I haven't got solution.
in this example of threadedfortuneserver , i saw write() in run() function is work as well as my code in run() function to ,
how do I use write() outside run() function ?
here is my code
-
@rifky said in QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread:
solve with
connect(updata_socket,SIGNAL(readyRead()),this,SLOT(readyRead()),Qt::DirectConnection);
error : QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread
here is the readyRead() function :
void UpdataServerThread::readyRead() { qDebug()<<updata_socket; qDebug()<<"connected_client_socket => "<<connected_client_socket; qDebug()<<"connected_client_ip => "<<connected_client_ip; QByteArray Data = updata_socket->readLine(); QJsonDocument document = QJsonDocument::fromJson(Data.data()); QJsonObject object = document.object(); //qDebug()<<"current thread :"<<QThread::currentThread()<<" DEVICE::"<<updata_socket->peerAddress()<<"in : "<<Data.data(); //authorize device if(Data.contains("devNumber")){ connected_client_ip.insert(updata_socket->peerAddress(),object.value("devNumber").toString()); QString str = "{\"msg\":\"Device registered successfully.\",\"timestamp\":"+QString::number(QDateTime::currentSecsSinceEpoch())+"}"; QByteArray registered_device = str.toUtf8(); ((QTcpSocket*)connected_client_socket.value(updata_socket->peerAddress()))->write(registered_device); } qDebug()<<"connected_client_ip::"<<connected_client_ip; }
but i want to write outside ,
void UpdataServerThread::sendCommand(QByteArray cmd) { qDebug()<<"current thread :@sendCommand"<<QThread::currentThread(); // qDebug()<<"connected_client_ip::"<<connected_client_ip; qDebug()<<"UpdataServerThread::sendCommand::"<<cmd; updata_socket->write("hi22"); }
how can i fix this code?
-
@rifky said in can't sending data outside qtcpsocket thread:
how can i fix this code?
Perhaps you could use
QTimer::singleShot()
:void UpdataServerThread::sendCommand(QByteArray cmd) { qDebug()<<"current thread :@sendCommand"<<QThread::currentThread(); // qDebug()<<"connected_client_ip::"<<connected_client_ip; qDebug()<<"UpdataServerThread::sendCommand::"<<cmd; if(QThread::currentThread() != updata_socket->thread()) QTimer::singleShot(0, updata_socket, [updata_socket](){ updata_socket->write("hi22"); }); else updata_socket->write("hi22"); }
-
@KroMignon said in can't sending data outside qtcpsocket thread:
Perhaps you could use
QTimer::singleShot()
:void UpdataServerThread::sendCommand(QByteArray cmd) { qDebug()<<"current thread :@sendCommand"<<QThread::currentThread(); // qDebug()<<"connected_client_ip::"<<connected_client_ip; qDebug()<<"UpdataServerThread::sendCommand::"<<cmd; if(QThread::currentThread() != updata_socket->thread()) QTimer::singleShot(0, updata_socket, [updata_socket](){ updata_socket->write("hi22"); }); else updata_socket->write("hi22"); }
thx for response but i got error :
updataserverthread.cpp:79:50: error: 'updata_socket' in capture list does not name a variable
updataserverthread.cpp:79:66: error: expected body of lambda expression../qtcpsocket_w_qthread/updataserverthread.cpp:79:50: error: 'updata_socket' in capture list does not name a variable QTimer::singleShot(0, updata_socket,[updata_socket]()){ ^ ../qtcpsocket_w_qthread/updataserverthread.cpp:79:66: error: expected body of lambda expression QTimer::singleShot(0, updata_socket,[updata_socket]()){ ^ 2 errors generated.
-
-
@KroMignon said in can't sending data outside qtcpsocket thread:
QTimer::singleShot(0, updata_socket,updata_socket {
qDebug()<<"UpdataServerThread::sendCommand::"<<cmd; if(QThread::currentThread() != updata_socket->thread()){ QTimer::singleShot(0, updata_socket,[updata_socket]() { updata_socket->write("hi22"); }); }else{ updata_socket->write("hi22"); }
is it correct ?
i still got error
updataserverthread.cpp:79:46: error: 'updata_socket' in capture list does not name a variable
-
@rifky said in can't sending data outside qtcpsocket thread:
is it correct ?
Why this question? Does it work or not?
If you are not confident with lambda functions take a look at this ==> https://medium.com/genymobile/how-c-lambda-expressions-can-improve-your-qt-code-8cd524f4ed9f -
-
@rifky said in can't sending data outside qtcpsocket thread:
i change to
QTimer::singleShot(0, updata_socket,this {it's working
Sorry my fault, I did not notice that updata_socket is not a local variable but a member of your class.
But this will not resolve your threading issue, I think you should change this to:void UpdataServerThread::sendCommand(QByteArray cmd) { qDebug()<<"current thread :@sendCommand"<<QThread::currentThread(); // qDebug()<<"connected_client_ip::"<<connected_client_ip; qDebug()<<"UpdataServerThread::sendCommand::"<<cmd; if(QThread::currentThread() != updata_socket->thread()) { auto localVariable = updata_socket QTimer::singleShot(0, localVariable, [localVariable](){ localVariable->write("hi22"); }); } else updata_socket->write("hi22"); }
-
@KroMignon no problem, thx for helping me, I really appreciate it