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,確實挺棘手的!記錄一下,僅供參考~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM