Trying to handle a connected client socket in a new thread from global thread pool:
m_threadPool = QThreadPool::globalInstance();
void TCPListenerThread::onNewConnection()
{
QTcpSocket *clientSocket = m_tcpServer->nextPendingConnection();
clientSocket->localPort();
m_connectThread = new TCPConnectThread(clientSocket);
m_threadPool->start(m_connectThread);
}
Here's TCPConnectThread
:
class TCPConnectThread : public QRunnable {
TCPConnectThread::TCPConnectThread(QTcpSocket *_socket)
{
m_socket = _socket;
this->setAutoDelete(false);
}
void TCPConnectThread::run()
{
if (! m_socket->waitForConnected(-1) )
qDebug("Failed to connect to client");
else
qDebug("Connected to %s:%d %s:%d", m_socket->localAddress(), m_socket->localPort(), m_socket->peerAddress(), m_socket->peerPort());
if (! m_socket->waitForReadyRead(-1))
qDebug("Failed to receive message from client") ;
else
qDebug("Read from client: %s", QString(m_socket->readAll()).toStdString().c_str());
if (! m_socket->waitForDisconnected(-1))
qDebug("Failed to receive disconnect message from client");
else
qDebug("Disconnected from client");
}
}
I have been getting endless errors with these. It seems cross-thread QTcpSocket
handling is not feasible(See Michael's answer).
Some errors:
QSocketNotifier: socket notifiers cannot be disabled from another thread
ASSERT failure in QCoreApplication::sendEvent: "Cannot send events t objects owned by a different thread.
Should I handle QTcpSocket
in a different thread ?
What should I do if I want to handle QTcpSocket
in a different thread ?
Or is there way to create a QTcpSocket
from a file descriptor ?
I think this page holds your answer:
If you want to handle an incoming connection as a new QTcpSocket object in another thread you have to pass the socketDescriptor to the other thread and create the QTcpSocket object there and use its setSocketDescriptor() method.
To do this, you'll have to inherit from QTcpServer
and override the virtual method incomingConnection
.
Within that method, create the child thread which will create a new QTcpSocket
for the child socket.
For example:
class MyTcpServer : public QTcpServer
{
protected:
virtual void incomingConnection(int socketDescriptor)
{
TCPConnectThread* clientThread = new TCPConnectThread(socketDescriptor);
// add some more code to keep track of running clientThread instances...
m_threadPool->start(clientThread);
}
};
class TCPConnectThread : public QRunnable
{
private:
int m_socketDescriptor;
QScopedPointer<QTcpSocket> m_socket;
public:
TCPConnectionThread(int socketDescriptor)
: m_socketDescriptor(socketDescriptor)
{
setAutoDelete(false);
}
protected:
void TCPConnectThread::run()
{
m_socket.reset(new QTcpSocket());
m_socket->setSocketDescriptor(m_socketDescriptor);
// use m_socket
}
};
or try to use moveToThread()
on the socket.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With