0

QT でソケット プログラミングを行っており、TCP/IP 経由でデータを転送するためのプロトコルを設計する必要があります。

これで、私のプロトコル設計は単純になりました。書き込みごとにソケットに書き込まれるデータの最初のバイトがコマンドになるように、コマンドを送信します。したがって、socket->write("CDATA") を使用して最初のバイトをソケットに書き込むときはいつでも、この場合の "C" は、サーバーが何かを行うためのコマンドを意味します。

サーバー上で書き込みが複数の読み取りに分割されるかどうかということを1つだけ知りたいですか?サーバーには読み取り用のバッファーサイズがあることを知っています。しかし、書き込みがサーバーのバッファ制限内にある場合、クライアントの socket->write() をサーバーでの複数の読み取りで受信できますか?

この質問をクリアするために、例を示します。サーバー上のソケットのバッファー読み取りサイズが 4096 バイトであるとします。クライアントは socket->write("CDATA") をサーバーに書き込みます。サーバーがこれを複数回の読み取りで受信する可能性はありますか? サーバーにwhileループがあるため:

while{
 char str[] = socket->read();
 // What is the coomand in the first byte 
 if(str[0] == "C"){
  // Do something
 }
}

クライアントから送信されたデータが複数の読み取りで受信された場合 (クライアントが 1 回の書き込みで送信した場合でも)、私のプロトコル設計は失敗します。

4

1 に答える 1

1

サーバーがこれを複数回の読み取りで受信する可能性はありますか?

はい、TCP/IP は好きなようにメッセージを断片化できます。TCP はステートフル ストリーム プロトコルです。一方の端に入力したバイトは、もう一方の端から同じ順序で出てくることが保証されています。IP はコネクションレスで、データグラム ベースです。TCP over IP を伝送する性質上、データ パケットが分割、マージ、または転送中に処理される状況が発生する可能性があります。

ネットワーク通信の複雑さに合わせてプログラムをサニタイズする方法を見つける必要があります。あなたはできる:

  • UDP などのデータグラム プロトコルを使用します (送信された順序でデータを取得するという保証が失われ、パケットがドロップされる可能性もあります。今日のネットワークはかなり堅牢です。これは通常問題ではありません)。

    [DATAGRAM (size specified in datagram header)]
    
  • 常にネットワークから固定サイズのブロックを読み取る

    [DATA - block of data of some fixed size]
    
  • 受信データのサイズを先頭に添付されたヘッダーとして含めます

    [LENGTH - 4 byte integer][DATA - block of data of size LENGTH]
    
  • ある種の区切り文字を使用してデータの終わりを示し、それを取得するまで読み続けます

    [DATA - indeterminately sized data][DELIMITER - end-of-data control sequence]
    

ライブラリ メソッドを使用してこの動作を実行できる可能性が高く、コードをほとんど必要としません。

于 2012-11-08T18:37:07.770 に答える