关于c ++:Qt-在新线程中处理QTcpSocket

Qt - Handle QTcpSocket in a new thread

尝试处理全局线程池中新线程中的已连接客户端套接字:

1
2
3
4
5
6
7
8
9
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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处理不可行(请参阅Michael的答案)。

一些错误:

1
2
3
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


我认为此页面包含您的答案:

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.

为此,您必须继承QTcpServer并覆盖虚拟方法incomingConnection

在该方法中,创建子线程,该子线程将为子套接字创建一个新的QTcpSocket

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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()