尝试在全局线程池的新线程中处理连接的客户端套接字:
m_threadPool = QThreadPool::globalInstance();
void TCPListenerThread::onNewConnection()
{
QTcpSocket *clientSocket = m_tcpServer->nextPendingConnection();
clientSocket->localPort();
m_connectThread = new TCPConnectThread(clientSocket);
m_threadPool->start(m_connectThread);
}
这是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");
}
}
我一直在犯这些错误。似乎跨线程QTcpSocket
处理是not feasible(参见迈克尔的回答)。
一些错误:
QSocketNotifier: socket notifiers cannot be disabled from another thread
ASSERT failure in QCoreApplication::sendEvent: "Cannot send events t objects owned by a different thread.
我应该在另一个帖子中处理QTcpSocket
吗?
如果我想在另一个帖子中处理QTcpSocket
,我该怎么办?
或者有没有办法从文件描述符创建QTcpSocket
?
答案 0 :(得分:8)
我认为this page有你的答案:
如果要将传入连接作为新的QTcpSocket处理 另一个线程中的对象你必须将socketDescriptor传递给 其他线程并在那里创建QTcpSocket对象并使用它 setSocketDescriptor()方法。
为此,您必须继承QTcpServer
并覆盖虚拟方法incomingConnection
。
在该方法中,创建子线程,为子套接字创建新的QTcpSocket
。
例如:
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
}
};
或尝试在套接字上使用moveToThread()
。