web-dev-qa-db-ja.com

TCPではなくUDPを使用するのが適切なのはいつですか?

TCPはパケット配信を保証しているので「信頼できる」と見なすことができますが、UDPは何も保証せず、パケットが失われる可能性があります。 TCPストリームではなく、アプリケーションでUDPを使用してデータを送信することの利点は何ですか?どのような状況でUDPがより良い選択となるでしょうか、そしてそれはなぜですか?

UDPはストリームを作成して維持するためのオーバーヘッドがないので高速であると思いますが、データが宛先に到達しない場合はこれは無関係ではないでしょうか。

280
Jeff L

これは私のお気に入りの質問の一つです。 UDPはとても誤解されています。

あなたが本当に他のサーバに素早く簡単に答えを得たい状況では、UDPが最もうまくいきます。一般的に、あなたは答えを1つの応答パケットにまとめたいと思うでしょう、そしてあなたは信頼性のためにあなた自身のプロトコルを実装するか、または再送する準備ができています。 DNSはこのユースケースの完璧な説明です。接続設定のコストが高すぎます(それでも、DNSはTCPモードをサポートします)。

もう1つのケースは、入ってくる新しいデータがその前のデータ/状態を置き換えるために失われる可能性があるデータを配信しているときです。天気データ、ビデオストリーミング、株価情報サービス(実際の取引には使用されていません)、またはゲームデータが頭に浮かぶ。

もう1つのケースは、膨大な量の状態を管理していて、TCPの使用を避けたい場合です。OSはそれほど多くのセッションを処理できないからです。これは今日ではまれなケースです。実際、アプリケーションの作成者がそのTCP状態に必要なリソースをきめ細かく制御できるように、user-land TCPスタックを使用できるようになりました。 2003年以前は、UDPは本当に街で唯一のゲームでした。

もう1つのケースはマルチキャストトラフィックです。 UDPは複数のホストにマルチキャストすることができますが、TCPはまったくこれを行うことができません。

326
drudru

TCP パケットが失われると、再送されます。これは、リアルタイムで特定の順序で処理されるデータに依存するアプリケーションには便利ではありません。

例としては、ビデオストリーミング、特に VoIP (例えば Skype )があります。しかし、そのような場合、ドロップされたパケットはそれほど大したことではありません。私たちの感覚は完璧ではないので、気付くことすらありません。これらの種類のアプリケーションがTCPの代わりに UDP を使用するのはそのためです。

61
Stephan202

UDPの「信頼性が低い」というのは形式主義です。送信は絶対に保証されていません。実際問題として、彼らはほとんどいつも通り抜けます。それらは単に承認されず、タイムアウト後に再試行されます。

TCPソケットのネゴシエーションおよびTCPパケットのハンドシェイクのオーバーヘッドは非常に大きいです。本当に巨大です。それほどのUDPオーバーヘッドはありません。

最も重要なのは、TCPよりもオーバーヘッドが少ない、信頼性の高い配信ハンドシェイクでUDPを簡単に補うことができるということです。これを読んでください: http://en.wikipedia.org/wiki/Reliable_User_Datagram_Protocol

UDPは、パブリッシュ/サブスクライブの種類のアプリケーションで情報をブロードキャストするのに役立ちます。 IIRC、TIBCOは状態変化の通知にUDPを多用します。

他の種類の一方向の「重要なイベント」または「ロギング」アクティビティは、UDPパケットでうまく処理できます。あなたはソケット全体を構築せずに通知を送りたいのです。あなたはさまざまなリスナーからの反応を期待していません。

システムの「ハートビート」または「私は生きている」というメッセージもまた良い選択です。行方不明者は危機ではありません。半ダース(行)が欠けています。

56
S.Lott

クライアントとサーバー間のUDP(IP)通信とTCP/IP通信の両方をサポートする製品に取り組んでいます。それは15年以上前にIPXから始まり、13年前にIPサポートが追加されました。 3年または4年前にTCP/IPサポートを追加しました。予想外のことです:UDPのTCPコード比は、おそらく80/20くらいでしょう。この製品はデータベースサーバーなので、信頼性が重要です。私達は他の答えで既に述べられたUDP(パケット損失、パケットダブリング、パケット順序など)によって課された問題の全てを扱わなければなりません。めったに問題がありませんが、それらは時々起こります、そしてそれを処理しなければなりません。 UDPをサポートすることの利点は、私たちがそれを私たち自身の用法に少しカスタマイズし、それからもう少しパフォーマンスを微調整することができるということです。

すべてのネットワークは異なるものになるでしょうが、UDP通信プロトコルは一般的に私たちにとって少し速いです。懐疑的な読者は、私たちがすべてを正しく実装したかどうかを正しく疑います。加えて、あなたは2桁の担当者を持つ男から何を期待できますか?それにもかかわらず、私は今好奇心からテストを実行しました。テストは100万レコードを読み取りました(*からいくつかを選択してください)。個々のクライアント要求ごとに返すレコード数を1、10、そして100に設定しました(各プロトコルで3回のテスト実行)。サーバーは100Mbit LAN上でほんの2ホップ先でした。数字は他の人が過去に見つけたものと一致するようでした(UDPはほとんどの状況で約5%速いです)。ミリ秒単位の合計時間は、この特定のテストでは次のとおりです。

  1. 1レコード
    • IP:390,760ミリ秒
    • TCP:416,903ミリ秒
  2. 10レコード
    • IP:91,707ミリ秒
    • TCP:95,662ミリ秒
  3. 100レコード
    • IP:29,664ミリ秒
    • TCP:30,968ミリ秒

送信された合計データ量は、IPとTCPの両方でほぼ同じでした。 TCP/IPで「無料」で入手できるもの(チェックサム、シーケンス番号など)と同じものがいくつかあるため、UDP通信には余分なオーバーヘッドがあります。たとえば、Wiresharkは、次のレコードセットに対する要求は、UDPでは80バイト、TCPでは84バイトであることを示しました。

29
Mark Wilkins

UDPはコネクションレス型プロトコルであり、データパケットが順不同で到着し、信頼性がなく、データパケットが問題なく即時に送信されるSNMP(簡易ネットワーク管理プロトコル)、DNS(ドメインネームシステム)などのアプリケーションで使用されます。

UDPは接続確立を含まないので、接続確立遅延を回避する必要があるDNSのような用途のために、UDPはTCPよりも好ましい。

ネットワーク管理が頻繁に行われるとき、すなわち信頼性が高く輻輳制御されたデータ転送を達成することが困難であるとき、ネットワーク管理がしばしば行われなければならないので、SNMPにおいて使用される。

乾杯

15
Arnkrishn

ここにはすでにたくさんの良い答えがありますが、1つ非常に重要な要素と要約を追加します。 UDPは、輻輳制御を使用しないため、正しいチューニングではるかに高いスループットを達成できます。 TCPでの輻輳制御は、非常に重要です。それは接続の現在の容量を推定することを試みることによってネットワークの混雑を最小にするために接続のレートとスループットを制御します。パケットがコアネットワークのように非常に信頼性の高いリンクを介して送信される場合でも、ルーターのサイズは限られています。これらのバッファはそれらの容量までいっぱいになり、その後パケットは破棄され、TCPは受信確認の欠如によるこの破棄に気付き、容量の見積もりに接続の速度を絞ります。 TCPもスロースタートと呼ばれるものを使いますが、スループット(実際には輻輳ウィンドウ)は、パケットがドロップされるまでゆっくりと増加し、その後、パケットがドロップされるまで下げられ、再びゆっくりと増加します。これにより、TCPスループットが変動します。大きなファイルをダウンロードすると、これがはっきりとわかります。

UDPは輻輳制御を使用していないので、ドロップポイントまでバッファを最大化しようとしないので、より速く、そしてより低い遅延を経験することができる。 UDPは輻輳制御を採用していないがTCPを採用しているので、UDPフローに譲渡するTCPから容量を奪うことができます。

それでもUDPは輻輳やパケットドロップに対して脆弱であるため、アプリケーションは何らかの理由でこれらの少ない損失を処理できるように準備する必要があります。おそらく再送信またはエラー訂正コードを使用します。

その結果、UDPでは次のことが可能になります。

  • ネットワークのドロップ率がアプリケーションが処理できる限度内であれば、TCPよりも高いスループットを達成できます。
  • 少ない遅延でTCPより速くパケットを配信します。
  • 接続を設定するための最初のハンドシェイクがないため、接続を早く設定できます。
  • マルチキャストパケットを送信しますが、TCPは複数の接続を使用する必要があります。
  • 固定サイズのパケットを送信しますが、TCPはセグメント単位でデータを送信します。 300バイトのUDPパケットを転送すると、もう一方の端で300バイトを受け取ります。 TCPでは、送信ソケットに300バイトを供給することができますが、受信側は100バイトしか読み取らないため、途中でさらに200バイトあることをどうにかして把握する必要があります。アプリケーションがバイトストリームではなく固定サイズのメッセージを送信する場合、これは重要です。

まとめると、UDPは、適切な再送信メカニズムも実装している限り、TCPが可能なすべてのタイプのアプリケーションに使用できます。 UDPは非常に高速で、遅延が少なく、接続ベースで輻輳の影響を受けず、固定サイズのデータ​​グラムを送信し、マルチキャストに使用できます。

14
Andy

UDPはオーバーヘッドが少なく、オーディオやビデオなどのリアルタイムデータのストリーミングなど、データが失われても問題ない場合には適しています。

13
Dana Holt

私がこの質問に対して知っている最も良い答えの1つは Hacker NewsのユーザーzAy0LfpBZLC8mAC から来ています。この答えはとても良いです私はそのままそれを引用するつもりです。

TCPは完全な順序どおりの配信を保証するため、キュー先頭ブロッキングを使用しているため、送信中にパケットが紛失した場合は、紛失したパケットの再送信を待つ必要があります。重複を含み、パケットの到着順序や到着順序を保証するものではありません(実際には、ポート番号と(オプションの)ペイロードチェックサムが追加されたIPです)、たとえばテレフォニーには問題ありません。数ミリ秒の音声が欠落していても問題はありませんが、遅延は非常に面倒なので、再送信を気にする必要はなく、重複パケットをドロップし、並べ替えたパケットを数百ミリ秒のジッタバッファで正しい順序に並べ替えるだけです。そして、パケットが間に合わなかったり、まったく表示されない場合、それらは単にスキップされ、コーデックでサポートされている場合は補間される可能性があります。

また、TCPの大部分はフロー制御です。可能な限り多くのスループットを確保するためですが、ネットワークに負担をかけずに済みます(ネットワークが過負荷になるとパケットがドロップされるので冗長です)。 UDPはそれを持っていません - コーデックを使ったテレフォニーにはある程度の帯域幅が必要なので、テレフォニーのようなアプリケーションには意味がありますが、「遅くする」ことはできません。また、帯域幅を追加しても通話は速くなりません。

リアルタイム/低レイテンシのアプリケーションに加えて、UDPはDNSルックアップのような非常に小さなトランザクションには意味があります。レイテンシの観点からも、また接続の破棄の観点からもTCP接続の確立と破棄のオーバーヘッドがないからです。帯域幅の使用あなたの要求が典型的なMTUよりも小さく、そして応答もおそらくそうであるなら、あなたはサーバで何の状態も保つ必要性なしで、一回の往復で行われることができます。そのような用途にも。

それから、もちろんUDPを使って独自のTCP置換を構築することはできますが、ネットワークのダイナミクスをある程度理解していなければ、おそらくあまり良い考えではありません。現代のTCPアルゴリズムはかなり洗練されています。

また、私はそれがそのようなSCTPやDCCPなど、UDPとTCP以上のものがあることを言及すべきであると思います。現在の唯一の問題は、(IPv4)インターネットがエンドユーザアプリケーションでUDPとNAT以外のプロトコルを使用することを不可能にするTCPゲートウェイでいっぱいであるということです。

12
Shital Shah

すでに述べたように、UDPはオーバーヘッドが少なく、ビデオやオーディオなどのストリーミングには適しています。パケットを失ってから再送信して追いつくことをお勧めします。

TCP配送についての保証はありません、あなたは単にソケットが切断されたかどうか、あるいは基本的にデータが届かないかどうかを言われるべきです。さもなければそれがそこに着くときそれはそこに着く。

あなたが忘れている大きなことは、UDPがパケットベースで、TCPがバイトストリームベースであるということです。あなたが送った "TCPパケット"が反対側に現れるパケットであるという保証はありません。ルータやスタックが望むように。そのため、ソフトウェアには、バイトを解析して使用可能なデータのまとまりに戻すという追加のオーバーヘッドがあり、かなりのオーバーヘッドがかかる可能性があります。 UDPは順番が乱れている可能性があるため、パケットに番号を付けるか、他のメカニズムを使用して順序を変更しなければならない場合があります。しかし、あなたがそのudpパケットを取得したとしても、それが残っているのと同じ順序ですべて同じバイトで到着します、変更はありません。したがって、udpパケットという用語は意味がありますが、tcpパケットは必ずしもそうではありません。 TCPには、アプリケーションからは見えない独自の再試行および順序付けメカニズムがあります。UDPを使用してニーズに合わせて調整することができます。

UDPは、両端でコードを書くのがはるかに簡単です。基本的には、ポイントツーポイント接続を作成して維持する必要がないからです。私の質問は通常、TCPのオーバーヘッドが必要な状況はどこにあるのでしょうか。あなたが受け取ったTCP "パケット"が送信された完全なパケットであると仮定するような近道をするなら、あなたはより良いですか? (長さ/内容をチェックしたくない場合は、2つのパケットを捨てる可能性があります)

8
old_timer

ビデオストリーミングは、UDPを使用する完璧な例です。

7
Daniel A. White

ビデオゲームのネットワーク通信は、ほとんどの場合UDPを介して行われます。

各更新にはプレイヤーが見ることができるものの完全な現在の状態が含まれているので、スピードは最も重要であり、更新が見逃されてもそれは本当に重要ではありません。

5
17 of 26

あるケースでは、他のユーザーが強調しているように、パケットの到着保証は重要ではないため、UDPを使用するのが問題ありません。 UDPよりもTCPの方が望ましい場合もあります。

TCPの代わりにUDPを使用したいというユニークなケースの1つは、別のプロトコル(トンネル、仮想ネットワークなど)を介してTCPをトンネリングしている場合です。 TCPを介してTCPをトンネリングすると、それぞれの輻輳制御が互いに干渉します。したがって、一般的にはUDP(または他の何らかのステートレスプロトコル)を介してTCPをトンネリングすることが好まれます。 TechRepublicの記事を参照してください。 TCPT over TCPの理解:エンドツーエンドのスループットと待ち時間に対するTCPトンネリングの効果

3
Brian M. Hunt

主な質問は「どのような状況でUDPがより良い選択になるのか」に関連していました。

上には多くの素晴らしい答えがありますが、欠けているのは、輸送の不確実性がTCPのパフォーマンスに与える影響の正式な客観的評価です。

モバイルアプリケーションの急成長と、それに伴う「時々接続される」または「時々切断される」パラダイムでは、接続が確立されにくいときにTCPが接続を維持しようとする試みのオーバーヘッドが強くなる状況が確実にあります。 UDPの場合とその「メッセージ指向」の性質。

これで数学/ research/numberを持っていませんが、接続性が一般的に悪い場合にTCPを使用して達成できるよりも、UDPを介したACK/NAKおよびメッセージ番号付けを使用して信頼性の高いアプリを作成しました。そしてかわいそうなTCPはただ時間を使い、私のクライアントのお金はただ接続しようとしているだけでした。あなたはこれを多くの西側諸国の地方や農村地域で得ています…。

3

それは常に明確なカットではありません。しかし、パケットを確実に無損失で確実に配信する必要がある場合は、TCPを使用してください。

一方、UDPは、情報の順序がそれほど重要ではない場合、またはデータが単一のパケットに収まる可能性がある場合に、短い情報のパケットを送信するのに適しています。

同じ情報を多数のユーザーにブロードキャストしたい場合にも適しています。

それ以外の場合は、シーケンスデータを送信しているときに適していますが、データの一部が失われても心配はありません(VOIPアプリケーションなど)。

TCPの機能の一部(ただし全部ではない)が必要なのはUDPよりも大きいため、プロトコルが複雑になることがあります。それが、アプリケーション層が追加機能を実装しなければならないところです。そのような場合は、UDPも適しています(インターネットラジオなど、順序は重要ですが、すべてのパケットが通過する必要はありません)。

それが使用される/使用される可能性がある場所の例1)LAN上の多数のマシンに正しい時間を放送するタイムサーバ。 2)VoIPプロトコル3)DNSルックアップ4)LANサービスを要求する。どこにいますか? 5)インターネットラジオ6)と他の多くの...

Unixでは、今日実装されているUDPプロトコルのリストを得るためにgrep udp/etc/servicesとタイプすることができます...何百もあります。

2
Matt

速度が必要な場合はUDP、パケットが必要ない場合は精度、精度が必要な場合はTCP。

UDPは、パケットの精度に依存しないようにプログラムを記述しなければならないという点で、多くの場合困難です。

2
bgw

UDPは、アプリが正確なデータ複製ではなく「リアルタイム」データを重視する場合に使用できます。たとえば、VoIPはUDPを使用でき、アプリはパケットの並べ替えを心配しますが、最終的にはVoIPはすべてのパケットを必要とするわけではありませんが、もっと重要なこととして、それらの多くの連続フローが必要です。たぶんここであなたは声質における「グリッチ」を持っています、しかし主な目的はあなたがメッセージを受け取ることであり、それが反対側で完全に再現されることではありません。 UDPは、接続の作成とTCPとの同期の費用がペイロードを上回る状況でも使用されます。 DNSクエリはその好例です。クエリごとに1パケットアウト、1パケットバック。 TCPを使用する場合、これはもっともっと集中的になります。 DNSの応答が返ってこない場合は、再試行してください。

2
RC.

UDPはコネクションレスプロトコルであることがわかっています。

  1. 単純な要求 - 応答通信を必要とするプロセスに適しています。
  2. 内部フロー、エラー制御を持つプロセスに適しています
  3. ブロードキャスティングおよびマルチキャストに適しています

具体例:

  • sNMPで使用される
  • rIPなどの一部の経路更新プロトコルに使用されます。
2
vikki

Stevenによる Unixネットワークプログラミング の22.4節、「TCPの代わりにUDPを使用する場合」を参照してください。

また、この他のSOを見てください。 UDPは常にTCPより速いという誤解

スティーブンスが言うことは以下のように要約されることができます:

  • ブロードキャストとマルチキャストにはUDPを使用することが唯一の選択肢です(新しいアプリケーションにはマルチキャストを使用する)。
  • あなたは単純なリクエスト/返信アプリケーションにUDPを使用することができますが、あなたはあなた自身のacks、タイムアウトおよび再送信を組み込む必要があるでしょう。
  • バルクデータ転送にUDPを使用しないでください。
2

TCPとUDPを比較すると、UDPのようなコネクションレスプロトコルは速度を保証しますが、パケット伝送の信頼性は保証しません。たとえば、ビデオゲームでは通常、信頼性の高いネットワークは必要ありませんが、速度が最も重要であり、ゲームにUDPを使用すると、ネットワーク遅延が減少するという利点があります。

enter image description here

2
Elenasys

私たちは、同じ数のPCに何千ものwinformsクライアントを持つWebサービスを持っています。 PCはDBバックエンドとの接続がなく、すべてのアクセスはWebサービス経由で行われます。そのため、UDPポートで待機する中央ロギングサーバーを開発し、すべてのクライアントが(log4net UDPアペンダーを使用して)受信したDBテーブルにダンプされるxmlエラーログパケットを送信することにしました。いくつかのエラーログが見逃されても何千ものクライアントがあってもそれほど気にしないので、メインのWebサービスをロードしない専用のロギングサービスで速いです。

1
softveda

途中でデータの一部を失っても、送信されているデータが完全に破壊されない場合は、TCPを介してUDPを使用します。その用途の多くは、ゲームなどのリアルタイムアプリケーション(FPS)です。ここでは、常にすべてのプレーヤーがどこにいるのかを知る必要はありません。データはプレイヤーがどこにいるのかを正確に教えてくれるでしょう)、そしてリアルタイムのビデオストリーミング(1つの破損したフレームは視聴体験を台無しにすることはありません)。

1
Zachary Murray

私はTCPがおそらくうまくいくかもしれないときにUDPを提案することに少し消極的です。問題は、TCPが何らかの理由で機能していない場合、接続が遅すぎたり輻輳したりしているために、UDPを使用するようにアプリケーションを変更してもうまくいかないことです。悪い接続はUDPにも悪いです。 TCPはすでに混雑を最小限に抑えるという非常に優れた仕事をしています。

UDPが必要とされる場所について私が考えることができる唯一のケースはブロードキャストプロトコルのためのものです。アプリケーションに2つの既知のホストが含まれている場合、UDPはコードの複雑さを大幅に増加させるために、パフォーマンス上の限界的な利点しか得られない可能性があります。