最も単純なQT TCPクライアント

リスニングサーバーに接続してデータを送信したいと考えています。利用可能な例を見てみましたが、私にはあまり役に立たないような余分な機能(接続、占いなど)があるようです。これはこれまでのコードです:

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

サーバーがリスニングと堅牢であると仮定して、データ型 QByteArray でデータ変数を送信するために実装する必要があるのは何ですか?

15

2 答え

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"が返されます。送信が完了したかどうかを確認するのはあなたの責任です。残念ながら、これはほとんどの場合、あなたのクラスはステートフルになります。クラスは、それがすでに開始しているかどうか、そして完了しているかどうかを伝える必要があります。これまでのところ、私はそれについてエレガントな方法を考え出していない。

22
追加された
確かに。私はそれに応じて私の答えを編集しました。
追加された 著者 Robin,
@adivk: void MainWindow :: から、メソッドがMainWindowクラスに属することがわかります。したがって、mainwindow.cppにあるはずです。また、mainwindow.hに宣言を追加する必要があります。ヘッダファイルに関しては、おそらく #include #include の両方が必要になるでしょう。しかし、このスレッドは4.5歳であり、上記のコードはおそらくQt4.2で書かれていたことに留意してください。別のQtバージョンを使用すると詳細が異なる場合があります。
追加された 著者 Robin,
@adivk:あなたはこの質問の範囲を超えて念頭に置いて何かを持っているようです。あなたの質問を新しい質問として投稿してみませんか?あなたは高品質の回答をどのくらい早く得ることができるかに驚くかもしれません! (コメントをコメントとして投稿しないでください)
追加された 著者 Robin,
このコードは、main.cppやmainwindow.cppから離れていますか?また、考慮する必要があるヘッダファイルはありますか?
追加された 著者 walksignison,
main.cppファイルにクライアントを設定することに関連するものが必要でしょうか?
追加された 著者 walksignison,
Robinさん、データを受け取るためのコードをいくつか用意してください。
追加された 著者 user990246,
ありがとうございます!!
追加された 著者 user990246,

私の場合、XMLデータを読んでいましたが、時にはすべてを1つのパケットにまとめることはできませんでした。 ここに優雅な解決策があります。 WaitForReadyReadにはタイムアウトがあります。 タイムアウトに達した場合のエラーチェックを行います。私の場合、私は決してすべきではない 不完全なxmlを受け取るが、もし起これば、これはスレッドをindefinetlyにロックするだろう タイムアウトなし:

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;
        }
    }
    ...
5
追加された
いい答えです。多くの人に感謝します。
追加された 著者 Taz742,