threaded fortune-serverをQtの例から修正しました。 クライアントはサーバーに接続し、次にヘッダーを送信して認証します。QTcpSocketからデータを読み込む際の問題
tcpSocket = new QTcpSocket();
tcpSocket->connectToHost(addr, port);
QByteArray block = "someheader";
int x = tcpSocket->write(block);
qDebug() << x;
クライアントは、ここではOKらしいとqDebug
はblock
の実際のサイズを表示します。
サーバ側では、私はincomingConnection
をあらかじめ定義しておき、新しい接続ごとにスレッドを開始します。
void Server::incomingConnection(int socketDescriptor) {
const QString &str = vec[qrand() % vec.size()];
SpellThread *thread = new SpellThread(socketDescriptor, str);
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
qDebug() << " -- incoming connection";
thread->start();
}
私はsock
をチェックしてチェックすることがあります。
void SpellThread::run() {
qDebug() << " -- in spellthread";
connect(sock, SIGNAL(readyRead()), this, SLOT(checkBytes()));
//....
qDebug() << " -- end spellthread";
}
最初の問題は、私はクライアントからのデータを送信していたときに、readyRead
が発射されていないということである(sock
はこちらQTcpServer*
です)。
-- incoming connection
-- in spellthread
-- end spellthread
クライアントは、ヘッダ長の実際のサイズを出力しているが: メッセージである(IはcheckBytes
にデバッグメッセージを追加しました)。
第2の問題は、現在checkBytes
が非常に悪い設計されていることです。まず、ヘッダーがOKであることを確認してフラグを設定し、メッセージのサイズを取得して別のフラグを設定し、最後に実際のメッセージを取得します。これは非常に不器用です。私はまず信号をエスケープしようとしましたが、代わりにsock->waitForReadyRead()
を使用しました。ただし、常にfalseを返します。 (ドキュメントから: "カスタムデバイス用のブロッキングAPIを提供するためにこの関数を再実装する。デフォルトの実装は何もせず、falseを返す")。
Qtで複数のクライアントと複数の読み取り/書き込みを行うクライアント/サーバーアプリケーションを実際に作成するにはどうすればよいですか?アプリケーションの設計を改善し、現在の2つの問題を解決するための提案が本当に必要です。
クライアントが接続するときに多くの計算が必要となるため、スレッドが必要です。私はシグナルをまったく使用したくない - ちょうど新しいクライアントからいくつかのデータを読んでから、いくつかのデータを送り返したい。最終的にクライアントがデータを送信しない場合、タイムアウトになります。しかし、 'waitForReadyRead'はそのトリックを行わず常に失敗します。信号なしで私にいくつかの提案を教えてもらえますか? – Marii
あなたのコメントを考慮に入れて私の答えを編集しました。 – alexisdm
私は信号なしでバージョンを試しましたが、このコード行に問題がありました: 'while(sock.bytesAvailable()<4);'。私はソケットがバイトが来た時を知ることを期待しました。私はこれを以下のように変更しました: 'while(sock.bytesAvailable()<4)sock.waitForReadyRead();'そして今は問題ありません。あなたの答えをありがとう、私はそれを受け入れる。 :) – Marii