5

C++ でソケット ネットワーク プログラミングを使用しようとしています。「Hello World!」というテキストを送信しようとしています。C++ send() 関数を使用してサーバーに送信します。最初は、「Hello World!」以降、バッファーのサイズを 13 に設定しました。全部で 12 文字です (文字数より 1 つ多くする必要があります)。送信機能は、約7回送信した場合にのみサーバーに文字を送信します。最終的にサーバーに到達すると、次のようになります。

「ハローワールド!ハローワールド!ハローワールド!ハローワールド!ハローワールド!ハローワールド!ハローワールド!」

ここが面白い部分です。「ハローワールド!」バッファサイズを 256 (char buffer[256];) に設定すると、文はすぐに送信されます。そのようなサーバーになると、「Hello World!」と表示されます。2つの単語の後にたくさんのスペースがあります. なぜこれが起こっているのですか? 可能であれば、どうすれば修正できますか? 私にお知らせください。

ありがとう

4

5 に答える 5

7

readバッファを指定して(または)を呼び出しreceiveてソケットから読み取ると、読み取ったバイト数を指定する整数値が返されます。バッファーからそれだけを取得する必要があります。残りは無関係です:

int count = read(...);
// buffer[0 .. count - 1] contains the appropriate data.
于 2009-04-15T00:36:25.790 に答える
6

通常、Nagle のアルゴリズムはデフォルトでオンになっています。これにより、複数の小さなパケットが 1 つに結合されます。Nagle のアルゴリズムをオフにすると、小さなパケットをすぐに送信できます。

于 2009-04-15T01:21:44.620 に答える
4

データを送信する準備が整うまでデータを保存するためのバッファが存在します。送信バッファーのサイズは 256 です。256 文字がバッファーを介して送信されるまで、データは相手側に送信されません。送信する準備ができていることがわかっている場合は、バッファでフラッシュ メソッドを呼び出すことで、これを修正できます。

明確にするために、内部でバッファリングしている場合、send() を呼び出してデータを渡すと、OS (またはライブラリ) が再びバッファリングします。

使用しているライブラリがより具体的になり、コード スニペットが含まれている可能性がある場合は、適切なバッファ フラッシュ関数を見つけて送信できる可能性があります。

または、*nix を使用している場合は、Nagle のアルゴリズムをオフにして、OS が小さなパケットをバッファリングしないようにします。または、ソケットをセットアップするときは、必ず TCP_NODELAY オプションを使用してください。

于 2009-04-15T00:36:33.480 に答える
0

これが SOCK_STREAM ソケットであると仮定すると、注意すべき重要なことは、基礎となる TCP プロトコルがセグメント境界を維持しないということです。つまり、send() を複数回呼び出すと、送信したすべてのデータが、相手側で 1 回の recv() 呼び出しによって非常に簡単に返される可能性があります。または、1 回の send() 呼び出しで送信されたデータが、相手側で複数の recv() で返される場合があります。たとえば、ネットワークの輻輳により一部のパケットが遅延した場合です。これは TCP の設計の基本であり、アプリケーションはそれに応じて設計する必要があります。

また、Mehrdad が指摘したように、recv() 呼び出しは、ネットワークから読み取られたバイト数を返します。バッファ内のそのポイント以降はガベージであり、データはゼロで終了しません。

SOCK_DGRAM ソケットは、TCP のようなストリーム指向ではなく、完全にパケット指向の UDP を基盤として使用します。ただし、UDP は信頼性を保証しません (U は Unreliable を表します)。そのため、パケットの損失、重複、順不同などを自分で処理する必要があります。これは、ストリーム指向の I/O よりもはるかに困難です。

于 2009-04-15T02:40:35.477 に答える
0

ソケットのプログラミングは面倒で、エラーが発生しやすく、移植性がありません。低レベルの C API から保護し、プラットフォームに依存しない抽象化を提供するBoostACEなどのライブラリの使用を開始します。

于 2009-04-16T04:01:06.867 に答える