多線程中使用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