最简单的QT TCP客户端

Simplest QT TCP client

本文关键字:客户端 TCP QT 最简单      更新时间:2023-10-16

我想连接到侦听服务器并传输一些数据。我查看了可用的示例,但它们似乎有额外的功能,似乎对我不是很有帮助(即连接,fortune等)。这是我到目前为止的代码:

QTcpSocket t;
t.connectToHost("127.0.0.1", 9000);

假设服务器正在侦听并且健壮,我需要实现什么来发送数据类型为QByteArray的数据变量?

使用QTcpSocket非常简单。重新开始…

void MainWindow::connectTcp()
{
    QByteArray data; // <-- fill with data
    _pSocket = new QTcpSocket( this ); // <-- needs to be a member variable: QTcpSocket * _pSocket;
    connect( _pSocket, SIGNAL(readyRead()), SLOT(readTcpData()) );
    _pSocket->connectToHost("127.0.0.1", 9000);
    if( _pSocket->waitForConnected() ) {
        _pSocket->write( data );
    }
}
void MainWindow::readTcpData()
{
    QByteArray data = pSocket->readAll();
}

请注意,从TcpSocket中读取数据时,您可能会在多个传输中接收数据。当服务器发送字符串"123456"给你时,你可能会收到"123"answers"456"。检查传输是否完整是你的责任。不幸的是,这几乎总是导致类是有状态的:类必须记住它所期望的传输,它是否已经开始以及它是否已经完成。到目前为止,我还没有找到一个优雅的方法来解决这个问题。

在我的例子中,我正在读取xml数据,有时我不会在一个数据包中获取所有数据。这里有一个优雅的解决方案。WaitForReadyRead也可以有一个超时然后在超时的情况下进行一些额外的错误检查。在我的情况下,我不应该接收到一个不完整的xml,但是如果它确实发生了,这将无限期地锁定线程无超时:

while(!xml.atEnd()) {
    QXmlStreamReader::TokenType t = xml.readNext();
    if(xml.error()) {
        if(xml.error() == QXmlStreamReader::PrematureEndOfDocumentError) {
            cout << "reading extra data" << endl;
            sock->waitForReadyRead();
            xml.addData(sock->readAll());
            cout << "extra data successful" << endl;
            continue;
        }  else {
            break;
        }
    }
    ...