2012-03-01 30 views
0

私は、複数のパケットをバッファに積み重ねて読み込みを行い、長いパケットで複数の送信試行のループを完全に送信する必要がある可能性があることを知っています。しかし、私はこれらのケースで梱包について質問があります:ソケットの送受信(TCP/IP)

  1. 読み取ることが待っている複数のパケットがある場合、私はのrecv(または任意の代替(低レベル)の関数)を呼び出す場合、それはすべてのスタックにそれらを返します私のバッファに入れるか、それらのうちの1つだけ(または私のバッファが不足している場合は最初の部分の一部)?
  2. 複数の繰り返しを必要とする長いパケットを送信すると、1つのパケットまたは複数のパケットとしてカウントされますか?送信されたパッケージがいっぱいではないことは、基本的には疑問です。

これらの質問は、私がWebソケットのパッケージについて考えたときに思い浮かぶものです。パケットの先頭と末尾に特殊文字を使用すると、複数のパッケージを区切ることができないという結論につながります。

P.S.すべての質問はTCP/IPに関するものですが、UDPについての情報(回答)も共有することを歓迎します。

答えて

2

TCPソケットはストリームベースです。順序は保証されていますが、各recv/readで受信するバイト数は、送信側からの保留中のバイトのチャンクである可能性があります。ペイロードをメッセージにチャンクする方法を示すフレーミング情報を追加することで、TCPの上にメッセージベースのトランスポートをレイヤーすることができます。これがWebSocketsの役割です。各WebSocketメッセージ/フレームは、少なくとも2バイトのヘッダー情報で始まり、それに続くペイロードの長さが含まれます。これにより、受信者は完全なメッセージを待って再アセンブルすることができます。

たとえば、標準Websocket APIまたは同様のAPI(ブラウザなど)を実装するライブラリ/インターフェイスの場合、onmessageイベントは受信したメッセージごとに1回発生し、イベントのデータ属性にはメッセージ全体が含まれます。

古いHixieバージョンのWebSocketでは、各フレームが '\ x00'で開始され、 '\ xff'で終了していたことに注意してください。プロトコルの現在の標準化されたIETF 6455(HyBi)バージョンは、フレームの処理をはるかに簡単にする長さを含むヘッダー情報を使用します(ただし、古いものと新しいものはまだメッセージベースで、基本的に同じAPIを持っています)。

1

TCP接続では、バイトのストリームが提供されます。したがって、そのように扱います。アプリケーションメッセージの境界は保持されません.1つの送信は複数の受信に対応し、もう1つの送信は周囲に対応します。あなたは両側にループが必要です。

UDPは、データグラム(すなわちメッセージ)ベースです。ここでは、(ソケット上の低レベルのフラグを混乱させない限り)1つの読み取りは常に単一のデータグラムをデキューします。アプリケーションバッファが保留中のデータグラムよりも小さく、その一部だけを読み込んだ場合、残りの部分は失われます。その周りの方法は、送信するデータグラムのサイズを通常のMTU 1500(IPとUDPヘッダーが少ないので実際は1472)に制限することです。

関連する問題