C++ 最简单的 QT TCP 客户端

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7923485/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 17:43:21  来源:igfitidea点击:

Simplest QT TCP client

c++cqtnetwork-programming

提问by Robin

I would like to connect to a listening server and transmit some data. I looked at the examples available but they seem to have extra functions that do not seem very helpful to me (i.e. connect, fortune, etc.). This is the code I have so far:

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

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

Assuming the server is listening and robust, what do I need to implement to send a data variable with datatype QByteArray?

假设服务器正在侦听并且健壮,我需要实现什么才能发送具有 datatype 的数据变量QByteArray

回答by Robin

very simple with QTcpSocket. Begin as you did...

使用 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();
}

Be aware, though, that for reading from the TcpSocket you may receive the data in more than one transmission, ie. when the server send you the string "123456" you may receive "123" and "456". It is your responsibility to check whether the transmission is complete. Unfortunately, this almost always results in your class being stateful: the class has to remember what transmission it is expecting, whether it has started already and if it's complete. So far, I haven't figured out an elegant way around that.

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

回答by Viktor Stremler

In my case I was reading xml data, and sometimes I would not get all in one packet. Here is an elegant solution. WaitForReadyRead could also have a time out in it and then some extra error checking in case that timeout is reached. In my case I should never receive an incomplete xml, but if it did happen this would lock the thread up indefinetly without the timeout:

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