开发者

Persistent Qt Local Socket IPC

I'm developing an application that uses IPC between a local server and a client application. There is nothing particular to it, as it's structured like the Qt documentation and examples.

The problem is that the client sends packets frequently and connecting/disconnecting from the server local socket (named pipe on NT) is very slow. So what I'm trying to achieve is a "persistent" connection between the two applications.

The client application connects to the local server (QLocalServer) without any problem:

void IRtsClientImpl::ConnectToServer(const QString& name)
{   
    connect(_socket, SIGNAL(connected()), this,  SIGNAL(connected()));
    _blockSize = 0;
    _socket->abort();
    _socket->connectToServer(name, QIODevice::ReadWrite);
}

And sends requests also in the traditional Qt manner:

void IRtsClientImpl::SendRequest( quint8 cmd, const QVariant* const param_array, 
                                 unsigned int cParams )
{
    // Send data through socket

    QByteArray hdr(PROTO_BLK_HEADER_PROJ);
    QByteArray dataBlock;
    QDataStream out(&dataBlock, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_5);

    quint8 command = cmd;

    out << blocksize_t(0)   // block size
        << hdr      // header
        << quint32(PROTO_VERSION_PROJ) // protocol version
        << command            // command
        << cParams;           // number of valid parameters

    for (unsigned int i = 0; i < cParams; ++i)
        out << param_array[i];

    // Write the current block size
    out.device()->seek(0);
    out << dataBlock.size() - sizeof(blocksize_t);
    _socket->write(dataBlock);
}

No problem. But the trick resides on the readyRead() signal in the server-side. Here's the current implementation of the readyRead() handling slot:

void IRtsServerImpl::onReadyRead()
{
    QDataStream in(_lsock);
    in.setVersion(QDataStream::Qt_4_5);

    if (_blocksize == 0)
    {
        qDebug("Bytes Available on socket: %d", _lsock->bytesAvailable());
        if (_lsock->bytesAvailable() < sizeof(blocksize_t))
            return;

        in >> _blocksize;
    }

    // We need more data?
    if (_lsock->bytesAvailable() < _blocksize)
        return;

    ReadRequest(in);

    // Reset
    _blocksize = 0; 

}

Without setting _blocksize to zero I could not receive more data, only the first block group (I would expect an entire block to arrive without segmentation since this is through a pipe, but it does not, go figure). I expect that behavior, sure, since the _blocksize does not 开发者_运维百科represent the current stream flow anymore. All right, resetting _blocksize does the trick, but I can't resend another packet from the client without getting an increasing array of bytes on the socket. What I want is to process the request in ReadRequest and receive the next data blocks without resorting to connecting/reconnecting the applications involved.

Maybe I should 'regulate' the rate of the incoming data?

Thank you very much.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜