1

単純な 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 は、2 つの 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);

_socket->write(data)呼び出しは、サーバーで重複した readyRead をトリガーします(サーバー側が ReadAll 呼び出しですべてのデータを読み取った場合でも)。

私がどこを見なければならないかの兆候はありますか?

4

1 に答える 1

2

QIODeviceareのセマンティクスは、 readyReadsignal は単に、読み取り可能なデータがある可能性が高いことを意味します。利用可能なデータが確実にあるという意味ではなく、特定の量のデータが利用可能であることが保証されているという意味でもありません。実装は確かにスプリアス信号を回避するために最善を尽くしますが、「スプリアス」信号をいくらでも自由に発行できます。readyRead信号が見逃された場合、それはもっと悪い問題 (実際にはバグです!) になります。

あなたがすべきことは、信号を受信したときに利用可能なデータを読み取ることです。それで全部です。特定の「チャンク」でデータを取得できるという保証はまったくありません。たとえば、接続の一方の端が単一の 1kByte 書き込みを行う場合、接続のもう一方の端は任意の数のreadyRead信号を受け取る可能性があります。

保証されているのは、信号を受信したときにのみデータを読み取る場合、readyReadデータを見逃すことはないということです。したがって、信号に接続されたスロット以外の場所から読み取る必要はありませんreadyRead

だから、あなたが見ているものは完全にOKです。readyReadが発火したときに利用可能なデータの量を処理する必要があります。ゼロバイトを含みます。

于 2014-02-11T22:06:15.603 に答える