2

私は初めてC++でUDPソケットを使用していますが、それらがどのように機能するかがわかりません。sendto/recvfromおよびsend/recvは通常、実際に送信または受信されたバイト数を返すことを知っています。この値は任意に小さく(ただし少なくとも1つ)、ソケットのバッファーにあるデータの量(読み取り時)またはバッファーに残っている空き領域の量(書き込み時)によって異なります。

一度に1バイトが送受信され、データグラムが順不同で受信されることを保証するだけの場合sendto、 UDPプロトコルの一貫性を維持するにはどうすればよいでしょうか。recvfromこれは、メッセージのバイトを受信したときに任意にシャッフルできることを意味しませんか?メッセージが一度に送受信されることを保証する方法はありますか?

4

4 に答える 4

3

それよりも少し強いです。UDP は完全なパッケージを提供します。バッファ サイズは任意に小さくすることができますが、パケットで送信されるすべてのデータを含める必要があります。ただし、サイズの制限もあります。大量のデータを送信する場合は、データをパケットに分割し、自分で再構成できるようにする必要があります。また、配送を保証するものではないため、すべてが確実に届くように確認する必要があります。

しかし、TCP のすべてを UDP で実装できるので、それは可能でなければなりません。

通常、UDP で行うことは、個別の小さなパケットを作成することです。

比喩的に言えば、UDP はハガキを送るようなものであり、TCP は電話をかけるようなものだと考えてください。はがきを送る場合は、必ず届くという保証はないので、返事を返してもらうなどの対応が必要です。電話があれば、接続が確立されていることがわかり、すぐに応答が聞こえます。

于 2009-04-23T02:05:42.900 に答える
1

UDPソケットでの着信データの待機専用のスレッドでブロッキング選択(NULLタイムアウトパラメーター)を使用するクライアントプログラムがあります。ブロックしている場合でも、selectは、単一の読み取り記述子が「準備完了」であるという表示とともに戻ることがありました。後続のrecvfromは0を返しました。

いくつかの実験の結果、少なくともWindowsでは、UDPパケットをホスト上のポートに送信すると、それを予期していないため、後続のrecvfromが0バイトになる可能性があることがわかりました。ある種の拒否通知がもう一方の端から来ているのではないかと思います。これを、クライアントの着信トラフィックを探すサーバーでプロセスを開始するのを忘れたことを思い出させるものとして使用します。

ところで、代わりに有効であるが未使用のIPアドレスを「送信」すると、selectは準備完了ステータスを返さず、期待どおりにブロックします。また、ブロッキングソケットと非ブロッキングソケットでは違いがないこともわかりました。

于 2012-03-21T15:21:56.483 に答える
1

実際には、長さが 0 バイトの UDP データグラムを送信できます。送信されるのは、IP ヘッダーと UDP ヘッダーだけです。反対側の UDP recvfrom() は長さ 0 を返します。TCP とは異なり、UDP には「接続」がないため、これはピアが接続を閉じたことを意味しません。

于 2009-04-23T03:55:05.587 に答える
1

いいえ。sendto を使用すると、1 バイトまでのパケットを送信できます。1 回の sendto 呼び出しとして 10 バイトを送信すると、これらの 10 バイトは 1 つのパケットに送信され、予想どおりコヒーレントに受信されます。

もちろん、これらの 10 バイトを 1 つずつ送信し、それぞれに sendto 呼び出しを使用することにした場合、実際には 10 個の異なるパケット (それぞれに 1 バイトが含まれる) を送受信し、それらは任意の順序である可能性があります。

郵便で本を送るのと同じです。本全体を 1 つの箱に梱包することも、すべてのページを切り離して個別の手紙として送信することもできます。前者の場合、パッケージはよりかさばりますが、注文された単一のエンティティとして本を受け取ります。後者では、各パッケージは非常に軽いですが、それを読んで頑張ってください ;)

于 2009-04-23T02:12:44.147 に答える