En basit QT TCP istemcisi

Bir dinleme sunucusuna bağlanmak ve bazı verileri iletmek istiyorum. Mevcut örneklere baktım ama bana çok yardımcı olmayan ekstra işlevler var gibi görünüyorlar (örneğin, false , vb.). Şimdiye kadar sahip olduğum kod:

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

Sunucunun dinlediğini ve güçlü olduğunu varsayarak, QByteArray veri türü olan bir veri değişkeni göndermek için ne yapmam gerekir?

15

2 cevap

QTcpSocket ile çok basit. Yaptığın gibi başla ...

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

Yine de, TcpSocket'den okumak için verilerin birden fazla iletimde, örn. Sunucu size "123456" dizesini gönderdiğinde "123" ve "456" mesajlarını alabilirsiniz. Aktarımın tamamlanmış olup olmadığını kontrol etmek sizin sorumluluğunuzdadır. Ne yazık ki, bu neredeyse her zaman sizin sınıfınızın durumsal olduğunu ortaya çıkarır: sınıfın, ne tür bir aktarım beklediğini, halihazırda başladığı ve tamamlanmış olup olmadığını hatırlaması gerekir. Şimdiye kadar, bunun etrafında zarif bir şekilde anlayamadım.

22
katma
Emin. Cevabımı buna göre düzenledim.
katma yazar Robin, kaynak
@adivk: Yöntemlerin MainWindow sınıfına ait olduğu void MainWindow :: 'dan görebilirsiniz. Bunun gibi mainwindow.cpp içinde olmalı ve ayrıca mainwindow.h bildirimini eklemeniz gerekir. Başlık dosyalarına gelince, muhtemelen hem #include hem de #include seçeneğine sahip olursunuz. Yine de, bu iş parçasının 4.5 yaşında olduğunu ve yukarıdaki kodun muhtemelen Qt4.2 ile yazıldığını unutmayın. Farklı bir Qt sürümü kullanıyorsanız, ayrıntılar farklılık gösterebilir.
katma yazar Robin, kaynak
@adivk: Bu sorunun kapsamının ötesine geçen akla özel bir şeyiniz var gibi görünüyor. Öyleyse sorunuzu yeni bir soru olarak neden göndermiyorsunuz? Yüksek kaliteli cevaplar almanın ne kadar hızlı olduğuna şaşırabilirsiniz! (Yorumları yorum olarak yayınlamayın.)
katma yazar Robin, kaynak
kodun bu biraz main.cpp veya mainwindow.cpp ayrı olacak mı? Ayrıca, dikkate alınması gereken herhangi bir başlık dosyaları var mı?
katma yazar walksignison, kaynak
istemciyi main.cpp dosyasında kurmakla ilgili bir şeye ihtiyacım olur mu?
katma yazar walksignison, kaynak
Çok fazla Robin, veri almak için biraz kod verebilir misiniz?
katma yazar user990246, kaynak
Teşekkürler bayım!!
katma yazar user990246, kaynak

Benim durumumda xml verilerini okuyordum ve bazen tek bir pakette yer alamıyordum. İşte zarif bir çözüm. WaitForReadyRead ayrıca bir zaman aşımı olabilir ve Daha sonra zaman aşımına ulaşıldığında kontrol eden bazı ekstra hatalar. Benim durumumda asla tamamlanmamış bir xml alırsınız, ancak eğer gerçekleşirse, bu iş parçacığını sonsuza kadar kilitler zaman aşımı olmadan:

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
katma
iyi cevap. çok teşekkürler adamım.
katma yazar Taz742, kaynak