【问题标题】:Simplest QT TCP client最简单的 QT TCP 客户端
【发布时间】:2011-12-16 22:23:01
【问题描述】:

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

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

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

【问题讨论】:

    标签: c++ c qt network-programming


    【解决方案1】:

    使用 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”和“456”。您有责任检查传输是否完成。不幸的是,这几乎总是导致你的类是有状态的:类必须记住它期待什么传输,它是否已经开始以及它是否完成。到目前为止,我还没有想出一个优雅的方法来解决这个问题。

    【讨论】:

    • 非常感谢 Robin,您能提供一些接收数据的代码吗?
    • 这部分代码是否会与 main.cpp 或 mainwindow.cpp 分开?还有,有没有头文件需要考虑?
    • @adivk:从void MainWindow::可以看出,这些方法属于MainWindow类。因此它们应该在 mainwindow.cpp 中,并且您还必须在 mainwindow.h 中添加声明。至于头文件,您可能需要#include &lt;QByteArray&gt;#include &lt;QTcpSocket&gt;。但是请记住,这个线程已有 4.5 年的历史,上面的代码可能是用 Qt4.2 编写的。如果您使用不同的 Qt 版本,详细信息可能会有所不同。
    • 我需要与在 main.cpp 文件中设置客户端相关的任何内容吗?
    • @adivk:似乎您有一些超出此问题范围的特定想法。那么为什么不将您的问题作为一个新问题发布呢?您可能会惊讶于获得高质量答案的速度有多快! (不要以 cmets 的身份发布问题。)
    【解决方案2】:

    在我的情况下,我正在读取 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;
            }
        }
        ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-04
      • 2015-12-29
      • 2011-12-17
      • 2011-09-04
      • 1970-01-01
      • 2011-11-16
      • 1970-01-01
      相关资源
      最近更新 更多