Самый простой клиент QT TCP

Я новичок в QT.. Я хотел бы подключиться к слушающему серверу и передать некоторые данные. Я посмотрел доступные примеры, но у них, похоже, есть дополнительные функции, которые мне кажутся не очень полезными (connect, fortune и т.д.)

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

Предполагая, что сервер прослушивает и надежный. Что мне нужно для отправки QByteArray из переменной "data".

Большое значение.

Ответы

Ответ 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". Вы несете ответственность за проверку того, завершена ли передача. К сожалению, это почти всегда приводит к тому, что ваш класс является сдержанным: класс должен помнить, какую передачу он ожидает, начал ли он уже и если он завершится. До сих пор я не выяснил элегантный способ этого.

Ответ 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;
        }
    }
    ...