3

を書いていQTcpServerます。telnet.exeテスト用のクライアントとして使用しました。新しいクライアント接続時に、サーバーHi!がクライアントにメッセージを送信し、それが表示されます。これまでのところ、すべて問題ありません。

しかし、telnet.exeウィンドウに何かを入力すると、各文字readyRead()に対して a が出力されます。の後にのみ送信したい! どうしたの?それはWindowsの性質ですか?私のLinuxボックスで使用したことが原因で、予想どおり、の後に文字列のみが送信されます。\r\ntelnet.exetelnet\r\n

4

3 に答える 3

3

CTRLメッセージを入力する代わりに、 +]を押してから入力しますsend YOURMESSAGE\r\n

于 2011-10-06T09:49:40.970 に答える
3

残念ながら、それが Windows telnet.exe クライアントの仕組みであり、これを変更する方法はありません。

TCP ストリームを処理するときに、このようなクライアント固有の動作に依存してはなりません。TCP はメッセージ境界を保証しませが、クライアントによって書き込まれたのと同じ順序でデータが配信されることを保証します。プロトコルを設計するときは、これを考慮する必要があります。

着信データをバッファリングし、これをアプリケーション プロトコル レベルで処理する必要があります。一般的な解決策には、メッセージ ターミネータ シーケンスの定義 (および、通常のメッセージ内に表示できる場合はそのシーケンスをエスケープするメカニズム) が含まれます。たとえば、このシナリオでは \r\n がターミネータ シーケンスになる可能性があります。フォローアップ メッセージの長さを指定するか、専用のメッセージング ライブラリ ( ZeroMQActiveMQなど- ただし、残念ながら Qt のネットワークは使用できません) を使用できます。

于 2011-04-04T12:58:35.290 に答える
1

はい、CRLFを使用するWindowsとLinuxの間にはいくつかの違いがあります。これは「正常」です。

うまく機能する1つのアプローチは、バッファを利用して、データの準備ができるかタイムアウトするのを待つことです。たとえば、セパレータトークンは「\ r」にすることができ、ドロップした後に「\n」を取得した場合も同様です。

カスタムプロトコルからのトークンを期待する例を次に示します。

int Connection::readDataIntoBuffer(int maxSize)
 {
     if (maxSize > MaxBufferSize)
         return 0;

     int numBytesBeforeRead = buffer.size();
     if (numBytesBeforeRead == MaxBufferSize) {
         abort();
         return 0;
     }

     while (bytesAvailable() > 0 && buffer.size() < maxSize) {
         buffer.append(read(1));
         if (buffer.endsWith(SeparatorToken))
             break;
     }
     return buffer.size() - numBytesBeforeRead;
 }

http://doc.qt.nokia.com/stable/network-network-chat-c​​onnection-cpp.htmlを参照してください

必要なものに応じて、別の提案は、いくつかの標準プロトコルに固執することです。このように、さまざまなタイプのクライアントでテストできます。

カスタムプロトコルに固執したい場合は、独自のクライアントを作成し、サーバーと連携するための適切なテストケースを作成することをお勧めします。Qtはそれを簡単かつ高速にします;)ネットワークの例を見てください。

編集:

readline()の代わりに検討することもできread()ます。read()の代わりに改行を待ちます(以下のドキュメントの抜粋を参照してください)。ただし、これでは、回線をいつ終了するかを制御できなくなります。QTcpSocketQIODevice

qint64 QIODevice::readLine ( char * data, qint64 maxSize )

ドキュメントから:

次のいずれかの条件が満たされるまで、データが読み取られます。

  • 最初の'\n'文字が読み取られます。
  • maxSize-1バイトが読み取られます。
  • デバイスデータの終わりが検出されます。

Qtの秘密の要素は、非同期信号駆動設計です。いくつかのアイデアについては、記事「スレッド、イベント、およびQObject」の「ネットワーク/ステートマシン」セクションを参照してください。

于 2011-04-04T13:29:11.740 に答える