2013-06-03 13 views
6

में QTcpSocket संभाल वैश्विक थ्रेड पूल से एक नया सूत्र में एक से कनेक्ट किसी क्लाइंट सॉकेट को संभालने के लिए कोशिश कर रहा है:क्यूटी - एक नया धागा

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 बनाने का कोई तरीका है?

उत्तर

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' कन्स्ट्रक्टर में पास करने का प्रयास करें और थ्रेड 'रन' विधि में एक नया 'QTcpSocket' बनाएं। –

+0

वास्तव में धन्यवाद! लेकिन मैंने पाया कि कभी-कभी मैं नई QTcpSocket से डेटा को पढ़ने में विफल रहता हूं, लगभग 10 में से 1 बार। क्या तुम देखते हो क्यों? ग्राहक ग्राहक ग्राहक से पढ़ें से जुड़ा से डाटा डिस्कनेक्ट किया गया: – CDT

संबंधित मुद्दे