0

TCP ソケットの send() について質問があります。

違いはありますか:

char *text="Hello world";
char buffer[150];

for(i=0;i<10;i++)
    send(fd_client, text, strlen(text) );

char *text="Hello world";
char buffer[150];

buffer[0]='\0';
for(i=0;i<10;i++)
    strcat(buffer, text);

send(fd_client, buffer, strlen(buffer) );

recv を使用する受信側に違いはありますか? 両方とも 1 つの TCP パケットになりますか?

TCP_NODELAY が設定されていても?

4

2 に答える 2

0

知る方法は本当にありません。TCPの実装に依存します。それがUDPソケットである場合、それらは間違いなく異なる結果をもたらします。最初のケースでは複数のパケットがあり、2番目のケースでは1つのパケットがあります。

TCPは、適切と思われるパケットを自由に分割できます。ストリームをエミュレートし、パケットメカニズムをユーザーから遠ざけて抽象化します。これは仕様によるものです。

于 2012-04-25T12:41:05.543 に答える
0

TCP はストリームベースのプロトコルです。Send を実行すると、一部のデータが OS の TCP レイヤー バッファーに入れられ、OS は定期的にデータを送信します。ただし、Send の呼び出しが速すぎると、前の配列が送信される前に、OS の TCP レイヤーにいくつかの配列が配置される可能性があります。つまり、スタックのようなもので、持っているものは何でも送信し、すべてを 1 つの大きな配列に入れます。
送信は、OS TCP レイヤーによるセグメンテーションで行われます。また、OS バッファーが 1 つのセグメント サイズを満たすのに十分な大きさになる前に、少量のデータの送信を防ぐ Nagle のアルゴリズムもあります。

そうです、違いがあります。

TCP はストリームベースのプロトコルです。単一の送信が同じ量のデータで単一の受信になるとは限りません。
データは融合する可能性があり、常にそのことを覚えておく必要があります。

ところで、あなたの例に基づいて、最初のケースでは、クライアントはすべてのバイトを一緒に受け取るか、何も受け取りません。その間に、1 つの大きなセグメントの送信が途中で落ちた場合、サーバー OS は自動的にそれを再送信します。大きなパケットのドロップの可能性が高くなるため、大きなセグメントを再送信すると、一部のトラフィックが失われます。ただし、これはドロップされたパケットの割合に基づいており、実際のケースではまったくない場合があります.

2 番目の例では、すべてを一緒に受け取ったり、パーツを個別に受け取ったり、一部をマージしたりできます。ネットワーク読み取りをそのように実装する必要はありません。受信する予定のバイト数を知っており、そのバイト数だけを読み取る必要があります。そうすれば、未読のバイトが残っていても、次の「読み取り」で読み取られます。

于 2012-04-25T13:05:26.213 に答える