2012-01-18 12 views
9

クライアントとサーバーがシリアル化されたオブジェクトを相互に渡すことができる双方向のクライアントサーバープログラムを実装しようとしています。私はこれをQt(QTcpSocketとQTcpServer)を使ってやろうとしています。私はこのようなプログラムをjavaで実装しましたが、Qtを使ってそれを行う方法を理解することはできません。私はfortune clientfortune serverの例をチェックアウトしましたが、わかりましたが、クライアントは単にサーバーに信号を送るだけで、サーバーからデータが送信されます。クライアントとサーバーがオブジェクトを前後に送信する必要があります。私は完全な解決策を探していない、私が探しているのは正しい方向へのガイダンスです。QtcpSocketとQTcpServerを使用するQt双方向クライアントサーバー

私は、接続を受け付けるがデータを受け入れないコードを書きました。

サーバ

このクラスは、サーバーです。接続を受け入れ、送信されているバッファのサイズを出力する必要があります。しかし、それは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(); 
} 

CLIENT

を出力している。このクラスは、クライアントです。それは文字列 'hello'を送信する必要があります。それは私が間違ってやっているものを私に教えて、または私がQtの中で何をしたいの確立の一般的なロジックを教えてください(私の知る限りでは)成功し

​​

を送信します。

答えて

9

QTcpSocketは、デフォルトでは非同期ですので、あなたはconnectToHostを呼び出し、同じ文脈で書くとき、それはできませんソケットが接続されていないため送信されました。

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"; 
    } 
} 

注:あなたはあなたの「クライアント」のコードを変更する必要がありますが

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

そして最後を聞くことができるしている場合もチェックしていませんでした。 QTcpServerは:: nextPendingConnection()QTcpSocketを返すので、代わりに新しい接続を使用すると、親

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

としてnextPendingConnectionで新しいQTcpSocketを作成することを取る今、私たちは、私は別のスロットに

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

をしなければなりません読んで移動することに注意してくださいそのような小さなコードサンプルに関しては、多くの誤りであることを認めている。 TCP/IP接続についての知識が必要です。それらはストリームであり、データチャンク全体が一度に届くという保証はありません

+1

ありがとうございました。ありがとう、私はソケットを介してデータを送信できました。しかし、何らかの理由でまだバッファサイズが0になっています。どんな考え? – PTBG

+0

ドキュメントから "0(既定値)の読み取りバッファサイズは、バッファにサイズ制限がないことを意味し、データが失われないことを保証します"。したがって、実際のコンテンツには何の示唆も与えません。 'socket-> size()'または 'socket-> bytesAvailable()'を使うべきです。 –

4

タイミングの問題があるようです。あなたのクライアントとサーバーは異なるプロセスなので、サーバーのconnectionAccepted()関数がソケットからの読み取りを試みる前に、TopLevelComms::connect()の全体が(ネットワークデータ転送と共に)実行されていることを保証する方法はありません。

私はあなたがQTcpSocketのwaitForReadyRead()機能を利用する場合、あなたはより良い運を持っている必要があることを疑う:

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

    if(socket->waitForReadyRead()) { 
     char* rec = new char[socket->readBufferSize()]; 
     qDebug()<<socket->readBufferSize(); 
    } 
} 
関連する問題