代码之家  ›  专栏  ›  技术社区  ›  Hernán

Qt 5.2:QLocalServer接收重复的readyRead信号

  •  1
  • Hernán  · 技术社区  · 12 年前

    我对设计一个简单的QLocalServer QLocalSocket IPC系统感到困惑。

    QLocalServer等待新的连接,并将信号连接到正确的插槽。

    void CommandProcessor::onNewConnection()
    {
        QLocalSocket* pLocal = _server->nextPendingConnection();
    
        connect(pLocal,SIGNAL(disconnected()),this,SLOT(onSocketDisconnected()));
        connect(pLocal,SIGNAL(readyRead()),this,SLOT(onSocketReadyRead()));
        connect(pLocal,SIGNAL(error(QLocalSocket::LocalSocketError)),this, SLOT(onSocketError(QLocalSocket::LocalSocketError)));
    
        qDebug("Socket connected. addr=%p", pLocal);
    }
    
    The readyRead slot implementation is:
    
    void CommandProcessor::onSocketReadyRead() 
    {
        QLocalSocket* pLocalSocket = (QLocalSocket *) sender();
        qDebug("SocketReadyRead. addr=%p", pLocalSocket);
    
        QDataStream in(pLocalSocket);
        in.setVersion(QDataStream::Qt_5_2);
        pLocalSocket->readAll(); 
    
    
        qDebug("%s pLocalSocket->bytesAvailable() = %d", Q_FUNC_INFO, pLocalSocket->bytesAvailable());
    }
    

    此readAll已完成 故意 检查我如何按顺序获得两个readyRead信号(来自同一个槽指针,我验证了这一点)。

    客户端操作相当简单:

       QByteArray data;
        QDataStream out(&data, QIODevice::ReadWrite);
        out.setVersion(QDataStream::Qt_5_2);
    
        cmd.toDataStream(out);
    
        // write blocksize at first field
    
        out.device()->seek(0);
        out << data.size() - sizeof(BLOCKSIZE_T);
        qint64 bw = _socket->write(data);
    

    _套接字->写入(数据) 调用在服务器上触发重复readyRead (即使服务器端已通过ReadAll调用读取所有数据)。

    有迹象表明我应该去哪里看吗?

    1 回复  |  直到 12 年前
        1
  •  2
  •   Kuba hasn't forgotten Monica    12 年前

    的语义 QIODevice 是这样的 readyRead 信号简单地意味着可能有数据可供读取。这并不意味着一定有数据可用,也不意味着一定数量的数据一定可用。实现当然会尽力避免伪信号,但它们可以自由发出任意数量的“伪”信号。如果一个 readyRead(已读) 信号丢失。

    当你得到信号时,你应该做的是读取任何可用的数据。这就是全部。绝对不能保证你会在任何特定的“分块”中获得数据。例如,如果连接的一端进行了单个1kByte的写入,则连接的另一端可能会得到任意数量的 readyRead(已读) 信号。

    所有可以保证的是,如果你 只有 当您获得 readyRead(已读) 信号,您不会丢失任何数据-因此,您不需要从任何位置读取,只需要从连接到 readyRead(已读) 信号

    因此,您所看到的完全正常 readyRead(已读) 火灾。包括零字节。

    推荐文章