QT多線程中使用QTcpSocket遇到的讀寫數據問題

多線程中使用QTcpSocket
在run()方法中new QTcpSocket;而後監聽readyRead()信號connect(m_pTcpSocket,SIGNAL(readyRead()),this,SLOT(sloat_RecvData()));服務器

問題是當須要給服務器發送一段命令時(使用m_pTcpSocket->write(byteArray);)程序會報出警告QSocketNotifier: socket notifiers cannot be enabled from another thread
我在QThread的子類WorkerThread中使用QTcpSocket來鏈接TCP服務器並給服務器發送數據。
void WorkerThread::run()
{
  m_pTcpSocket = new QTcpSocket();
  while (1) {
    …;
    m_pTcpSocket->connectToHost(QHostAddress::LocalHost, 8001);  // 鏈接服務器
    m_pTcpSocket->waitForConnected(3000);              // 等待確保鏈接成功
    int nByteWrite = m_pTcpSocket->write(strMessage.toUtf8());                 // 發送數據到服務器 
  }
}
能夠鏈接到服務器,可是調用write發送數據時,服務端一直接收不到,表示這裏發送失敗了,客戶端發不出數據了~
解決
後來在使用完write()方法後,再使用flush()方法,就能夠發送消息了。
qt的官方文檔裏說,調用了flush()方法後,能夠把緩衝的數據馬上發送出去。
估計QTcpSocket中的write()方法是帶有緩衝的。
void WorkerThread::run()
{
  m_pTcpSocket = new QTcpSocket();
  while (1) {
    …;
    m_pTcpSocket->connectToHost(QHostAddress::LocalHost, 8001);
    m_pTcpSocket->waitForConnected(3000);
    int nByteWrite = m_pTcpSocket->write(strMessage.toUtf8());
    m_pTcpSocket->flush();
  }
}多線程

上面的客戶端TcpSocket成功地將數據write發送給了服務端,可是又發現客戶端readyRead信號一直不進它的槽函數sloat_RecvData()。真是一波剛平一波又起啊,如今客戶端又收不到數據了~
解決
檢查connect(tcpSocket, SIGNAL(readyRead()),this,SLOT(update_message()));返回值爲true,說明信號槽鏈接起來了~
服務端檢查write函數的返回值,爲非零,說明也發出去了~
線程while(1)循環很快,在該循環中,循環過快,致使connect來不及處理數據,因此使用waitForReadyRead()將循環進行阻塞,當有數據讀入時取消阻塞,進入下一輪循環。
void WorkerThread::run()
{
  m_pTcpSocket = new QTcpSocket();
  while (1) {
    …;
    m_pTcpSocket->connectToHost(QHostAddress::LocalHost, 8001);
    m_pTcpSocket->waitForConnected(3000);
    int nByteWrite = m_pTcpSocket->write(strMessage.toUtf8());
    m_pTcpSocket->flush();
    m_pSocket->waitForReadyRead();
  }
}socket

在多線程中是socket,確實挺棘手的!記錄一下,僅供參考~tcp

相關文章
相關標籤/搜索