2010-12-29 12 views
2

私はTCPがストリームのようなデータ送信を提供していることを知っていますが、主な質問は、 - TCPを介してデータを送信する際にどのような状況が起こる可能性がありますか?
1.メッセージをNチャンクに分割してMTUサイズに合わせることができます。
2. 1つのrecvコールで2つのメッセージを読み取ることができます。TCPフラグメンテーション

次の状況がありますか?
MTUたとえば1500バイト。
クライアントコールは1498バイトのデータで送信されます。
クライアントコールは100バイトのデータで送信されます。
サーバーはrecvを呼び出し、1500バイトのデータを受信します。
サーバーはrecvを呼び出し、98バイトのデータを受信します。

したがって、2番目のクライアントからの2バイトの送信が最初のサーバーrecvで受信される状況になります。 foolowsとして定義

マイプロトコル:
4バイト - データ長
データコンテンツ。

4バイト(データ長)が2つのチャンクに分割されると思いますか?

+0

それを分割しない場合でも、それはどんな違いを生むん。あなたのデータはすべて、目的地に正しく中継され、TCPによって保証されます。 http://en.wikipedia.org/wiki/Transmission_Control_Protocol – DumbCoder

+0

TCPに関する限り、「メッセージ」はありません。あなたのコードにメッセージの概念があるならば、TCPは何も知らない。 –

答えて

6

はい、バイトのストリームは、の任意のバイト境界で分割されます。あなたは確かに8つの異なる方法のいずれかであなたの4バイトのデータ長ヘッダ分割を持つことができます。

4 
1-3 
2-2 
3-1 
1-1-2 
1-2-1 
2-1-1 
1-1-1-1 

これらのいくつかは他よりも発生する可能性が高くなりますが、あなたは彼らのために考慮しなければなりません。これを扱うことができ、コードは次のようになります。

unsigned char buf[4]; 
size_t len = 0; 
while (len < sizeof(buf)) { 
    ssize_t n = recv(s, buf+len, sizeof(buf)-len, 0); 
    if (n < 0) { 
     // error handling here 
    } 
    len += n; 
} 
length = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); 
+2

重要なことは、処理を続行する前に完全な4バイトをブロックして待つ場合、*これは問題ではないことです。 TCPはその作業を行い、断片化されたデータを透過的に再構成します。 – cdhowie

+0

@cdhowie - これは真実かもしれませんが、コードとワイヤの間にあるすべてのソフトウェアが各SendData呼び出しで1対1の方法でパケットを構築するという保証はありません。つまり、ある行の下のどこかで、呼び出しに渡されたバイト配列が状況に応じて大きすぎると判断された場合、メッセージが複数のパケットに分割されないことを保証するものはありません。 –