2009-04-15 10 views
5

C++でソケットネットワークプログラミングを使用しようとしています。テキスト「Hello World!」を送信しようとしています。 C++のsend()関数を使用してサーバーに送信します。最初は、 "Hello World!"以降のバッファサイズを13に設定しました。全部で12文字です(文字数を1文字以上増やす必要があります)。 send関数は、約7回送信すると文字をサーバーに送信するだけです。そして、最終的にサーバーに来たら、それは次のようになります:C++ソケット256バイトバッファ

"Hello World!Hello World!Hello World!Hello World!Hello World!こんにちは!Hello World!"

ここに面白い部分があります。 「Hello World!」私はバッファサイズを256に設定するとすぐに文章を送ります(char buffer [256];)。しかし、そのようなサーバーになると、「Hello World!」と表示されます。 2つの単語の後にスペースの全体の束と。なぜこれが起こっているのですが、可能であればどうしたらいいですか?私にお知らせください。整数値が読み込まれたバイト数を指定することが返され

おかげ

+0

文字列を無効にしましたか? "Hello World!\ 0" – Alan

答えて

7

あなたがソケットから読み取るために、あなたの緩衝液でread(またはreceive)を呼び出し、。あなたはバッファからそれだけを取るべきです。残りは無関係です。

int count = read(...); 
// buffer[0 .. count - 1] contains the appropriate data. 
+0

データを受け取るサーバーはC# – QAH

+0

QAHで作成されています。これはC#ソケットのSocket.Receiveメソッドにも当てはまります。 –

4

送信準備ができるまで、データを保存するバッファがあります。送信バッファーサイズは256です。バッファーを介して256文字が送信されるまで、データは相手側に送信されません。これを解決するには、送信準備ができていることがわかったらバッファにflushメソッドを呼び出します。

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

あなたが使用しているライブラリを特定し、コードスニペットを含めると、適切なバッファフラッシュ関数が見つかる可能性があります。

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

6

Nagleのアルゴリズムは、通常、デフォルトでオンになっています。これはいくつかの小さなパケットを一つにまとめます。 Nagleのアルゴリズムをオフにすると、小さなパケットがすぐに送信されます。

0

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

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

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

+0

UDPはユーザデータグラムプロトコルです。その名前には信頼できないものは何もありません。あなたはそれが比較的信頼できないということは間違いありません:) –

0

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