2012-01-18 16 views
9

İstemcilerin ve sunucuların birbirleri arasında seri hale getirilmiş nesneleri geçirebileceği iki yönlü bir istemci-sunucu programı uygulamaya çalışıyorum. Bunu Qt (QTcpSocket ve QTcpServer) kullanarak yapmaya çalışıyorum. Java gibi programlar yaptım ama Qt kullanarak nasıl yapılacağını anlayamıyorum. fortune client ve fortune server örneklerini inceledim ama görebildiğim kadarıyla, istemci sadece sunucuyu sinyalliyor ve sunucu bazı verileri gönderiyor. İstemci ve sunucu için nesneleri ileri geri göndermeye ihtiyacım var. Tam bir çözüm aramıyorum, tek aradığım şey doğru yönde bir rehberlik.QTcpSocket ve QTcpServer kullanarak Qt iki yönlü istemci sunucusu

Bağlantı kabul eden ancak verileri kabul etmeyen bazı kodlar yazdım.

SUNUCU

bu sınıf sunucusudur; bir bağlantıyı kabul etmeli ve gönderilmekte olan tamponun boyutunu çıkarmalı. Ancak 0

#include "comms.h" 

Comms::Comms(QString hostIP, quint16 hostPort) 
{ 
    server = new QTcpServer(this); 
    hostAddress.setAddress(hostIP); 
    this->hostPort = hostPort; 


} 

void Comms::attemptConnection(){ 
    connect(server, SIGNAL(newConnection()), this, SLOT(connectionAccepted())); 
    //socket = server->nextPendingConnection(); 
    server->listen(hostAddress,hostPort); 
    //receivedData = socket->readAll(); 
} 

void Comms::connectionAccepted(){ 
    qDebug()<<"Connected"; 
    socket = new QTcpSocket(server->nextPendingConnection()); 

    char* rec = new char[socket->readBufferSize()]; 
    qDebug()<<socket->readBufferSize(); 
} 

MÜŞTERİ

Bu sınıf çıktısı istemcisidir. 'Merhaba' dizesini göndermeli. Bu

#include "toplevelcomms.h" 
#include "stdio.h" 

TopLevelComms::TopLevelComms(QString hostIP, quint16 hostPort) 
{ 
    tcpSocket = new QTcpSocket(); 
    hostAddress.setAddress(hostIP); 
    this->hostPort = hostPort; 
} 


void TopLevelComms::connect(){ 
    tcpSocket->connectToHost(hostAddress,hostPort,QIODevice::ReadWrite); 
    //tcpSocket->waitForConnected(1); 

    QString string = "Hello"; 
    QByteArray array; 
    array.append(string); 
    qDebug()<<tcpSocket->write(array); 
} 

yanlış yapıyorum söyle yoksa bana Qt istediğini kurma genel mantığını söyle (bildiğim kadarıyla) başarıyla gönderir.

cevap

9

QTcpSocket varsayılan olarak asenkron, böylece connectToHost arayıp aynı bağlamda yazarken o olmayacak Soket bağlı olmadığı için gönderildi.

void TopLevelComms::connect(){ 
    tcpSocket->connectToHost(hostAddress,hostPort,QIODevice::ReadWrite); 
    if(tcpSocket->waitForConnected()) // putting 1 as parameter isn't reasonable, using default 3000ms value 
    { 
     QString string = "Hello"; 
     QByteArray array; 
     array.append(string); 
     qDebug()<<tcpSocket->write(array); 
    } 
    else 
    { 
     qDebug() << "couldn't connect"; 
    } 
} 

Not: Eğer "müşteri" kodunu değiştirmek gerekir Eğer

void Comms::attemptConnection(){ 
    connect(server, SIGNAL(newConnection()), this, SLOT(connectionAccepted())); 
    //socket = server->nextPendingConnection(); 

    if(server->listen(hostAddress,hostPort)) 
    { 
     qDebug() << "Server listening"; 
    } 
    else 
    { 
     qDebug() << "Couldn't listen to port" << server->serverPort() << ":" << server->errorString(); 
    } 
    //receivedData = socket->readAll(); 
} 

Ve son şey dinlemek mümkün iseniz da onay vermedi. QTcpServer :: nextPendingConnection() böylece yerine yeni bağlantı biz ayrı yuvaya

void Comms::readSocket() 
{ 
    // note that dynamic size array is incompatible with some compilers 
    // we will use Qt data structure for that 
    //char* rec = new char[socket->readBufferSize()]; 
    qDebug()<<socket->readBufferSize(); 
    // note that QByteArray can be casted to char * and const char * 
    QByteArray data = socket->readAll(); 
} 

sana mecbur etmek okuma hareket edecek şimdi

void Comms::connectionAccepted(){ 
    qDebug()<<"Connected"; 
    // WRONG! it will use QTcpSocket::QTcpSocket(QObject * parent) 
    //socket = new QTcpSocket(server->nextPendingConnection()); 
    // use simple asign 
    socket = server->nextPendingConnection(); 
    // move reading to slot 
    connect(socket, SIGNAL(readyRead()), this, SLOT(readSocket())); 
} 

ebeveyn olarak nextPendingConnection ile yeni QTcpSocket oluşturmanızı alma, QTcpSocket dönmek unutmayın itiraf et, bu küçük kod örneğinde olduğu gibi bir çok hata olduğunu. TCP/IP bağlantıları hakkında bilgi sahibi olmalısınız. Bunlar akışlar ve tüm veri yığınlarının size bir kerede alacağı garanti edilmiyor.

+1

Çok teşekkürler, veriyi sokete gönderebiliyordum.Ancak hala bir sebepten dolayı 0 tampon büyüklüğüne ulaşıyorum. Bir fikrin neden? – PTBG

+0

Dokümanlardan "Okuma arabelleği boyutu 0 (varsayılan değer), arabelleğin boyut sınırlaması olmadığını ve hiçbir verinin kaybolmadığını" belirtir. Bu nedenle, gerçek içerik hakkında hiçbir bilgi vermez. 'Socket-> size()' veya 'socket-> bytesAvailable()' yi kullanmalısınız. –

4

Zamanlama sorununuz var gibi görünüyor. İstemciniz ve sunucunuz farklı işlemler olduğundan, sunucunuzun connectionAccepted() işlevinin soketten okumayı denemeden önce TopLevelComms::connect() tümünün (ağ veri aktarımı ile birlikte) yürütülmesini garanti etmenin hiçbir yolu yoktur.

Sana QTcpSocket en waitForReadyRead() fonksiyonunun yararlanmak eğer, daha iyi şans gerektiğini sanıyorum:

void Comms::connectionAccepted(){ 
    qDebug()<<"Connected"; 
    socket = new QTcpSocket(server->nextPendingConnection()); 

    if(socket->waitForReadyRead()) { 
     char* rec = new char[socket->readBufferSize()]; 
     qDebug()<<socket->readBufferSize(); 
    } 
} 
İlgili konular