2016-09-25 6 views
1

SORRY FOR BAD ENGLISH奇妙な行動

なぜ私は、サーバー上の2つのsend() -s、およびクライアント上の2つのrecv() -sを、時には最初recv()持っている場合最初のコンテンツだけを取ることなく、サーバからsend()の内容を取得し、もう1つのrecv()をもう1つの「正当な」コンテンツとすることができますsend()

この作品を他の方法で入手するにはどうすればよいですか?

答えて

1

これは仕様です。

TCPストリームは、2つのエンドポイント間でバイトを送信できるチャネルですが、送信はストリームベースであり、メッセージベースではありません。

メッセージを送信する場合は、エンコードする必要があります。たとえば、受信者に本文に期待するバイト数を知らせる「サイズ」フィールドを付加します。

100バイトを送信してから100バイトを送信した場合、受信者は2つの異なる読み取りコマンドで同時に200回または50 + 150回を表示する可能性があります。メッセージの境界線が必要な場合は、データを自分で入れなければなりません。

メッセージを送信できる下位層(データグラム)がありますが、サイズは限られていますが、配信は保証されていません(つまり、メッセージが失われたり、複製されたり、異なる順序で到着する)。 TCPストリームはこのデータグラムサービスの上に構築され、2つのエンドポイント間でデータを確実に転送するために必要なすべてのロジックを実装します。

代わりに、ZeroMQのようなエンドポイント間の信頼性の高いメッセージパスを提供するように設計されたライブラリがあります。

+0

しかし、最初の 'rec()'に何も送信しないように2番目の 'send()'にどのように伝えることができますか?あなたのソリューションは、「send()2」から「text 2」を「recv()1」で受け入れられた「text 1」と混合しないようにしています。しかし、私はsend()2のデータが失われています。なぜなら、送信者と誰も送信者からテキストを受け取るのを待っていないからです。どのように私は正確な送信と正確なrecvの間で同期化できますか? –

+0

@ dfsfgできません。それがこの答えの要点です。このような機能は機能しません。 –

0

ほとんどの場合、SOCK_STREAMタイプのソケットを使用します。これはTCPソケットです。つまり、一方の側にデータをプッシュし、もう一方の側から同じ順序で欠落したチャンクを取りませんが、デリミタはありません。したがって、send()はデータを送信するだけで、recv()は現在の瞬間に利用可能なすべてのデータを受信します。

SOCK_DGRAMを使用すると、UDPが使用されます。しかし、そのような場合には、すべてsend()がデータグラムを送信し、recv()がそれを受信します。しかし、データグラムがシャッフルされたり失われたりすることはありませんので、このような問題を自分で処理しなければなりません。最大データグラムサイズにも制限があります。

TCP接続に固執することもできますが、区切り文字を自分で送信する必要があります。