2013-06-03 3 views
6

でQTcpSocketハンドルこれらと。クロススレッドQTcpSocketの扱いはnot feasibleです(マイケルの答えを参照)。Qtはグローバルスレッドプールから新しいスレッドに接続されたクライアントソケットを処理しようとすると、新しいスレッド

一部のエラー:

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を作成する方法はありますか?

答えて

8

私はthis pageは、あなたの答えを保持していると思う:

あなたは 他のスレッドにsocketDescriptorを渡し、QTcpSocketオブジェクトを作成する必要があり、別のスレッドで新しい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()を使用するようにしてください。

+0

moveToThread()はQThreadでのみ動作するようですが、私はQRunnableを使用しています。 – CDT

+1

'socketDescriptor'を' TCPConnectThread'コンストラクタに渡して、 'run'メソッドのスレッドに新しい' QTcpSocket'を作成しようとします。 –

+0

本当にありがとう!しかし、時々私は新しいQTcpSocketからデータを読み取ることに失敗することがあることを知りました。約10回に1回です。理由は分かりますか?ここ – CDT

関連する問題