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,确实挺棘手的!记录一下,仅供参考~

posted on 2019-05-28 16:12  我来乔23  阅读(11010)  评论(1编辑  收藏  举报

导航