広告が嫌いですか? 行く 広告なし 今日

開発者向け TCP と UDP の違い — プロトコルが実際に重要なとき

更新日

TCPとUDPを互換性のあるチェックボックスのように扱うのをやめましょう。信頼性の保証が実際にあなたにどれだけのコストをもたらすか、DNSがUDPを使用する理由、そしてあなたのゲームが遅くなる理由について説明します。

開発者向けTCPとUDP — プロトコルが実際に重要になるとき1

あなたはマルチプレイヤーのゲームを開発しています。プレイヤーがラグについて不満を述べています。サーバーのコードを最適化し、データベースのクエリを減らし、p99の遅延が良好であることを確認しました。問題は単純です:TCPを使っているだけです。それだけです。それがラグです。

TCPとUDPは、プロトコルチェックリストの2つのボックス以上のものではありません。それはネットワークがどのように振る舞うかに関する根本的な賭けを表しています。間違った選択は単にパフォーマンスを損なうだけでなく、問題が発生したときに失敗の性質を変えるのです。

TCPが下す賭け

TCPは、信頼性があり、順序が保たれたバイトストリームをあなたに保証します。パケットが失われた場合、TCPは再送を行います。パケットが順序がずれている場合、TCPはそれらを再順序にします。あなたのアプリケーションは、常にクリーンで順序の取れたデータを受信します。

その保証は、以下の3つのコストをもたらします:

  • ハンドシェイクの遅延 — TCPは、1バイトのアプリケーションデータが送信される前に3-wayハンドシェイクを必要とします。50msのリターンタイムのネットワークでは、最初のリクエストが開始される前に150msが消費されます。
  • ヘッド・オブ・ライン・ブロッキング — これはゲームで殺されるものです。パケット#5が失われた場合、TCPはパケット#6、#7、#8をバッファに保持し、#5が再送され、到着するまで待機します。ストリームはブロッキングされます。プレイヤーの100ms前の位置更新は、ネットワークが自身を整理する間、バッファに残っています。
  • コンゲスト制御のオーバーヘッド — TCPのコンゲストウィンドウアルゴリズム(CUBIC、BBRなど)が損失を検知した場合、送信速度を制御します。損失のあるネットワークでは、これはネットワークが苦しみているときに送信速度を低下させることを意味し、ユーザーが最も感じることになります。

UDPが実際に提供するもの

UDPは、データグラムを送信し、後を見ません。ハンドシェイク、確認、再送はありません。パケットが失われた場合、それは消えます。受信者は、到着した順番で到着したものを受け取ります。

それは制限ではなく、ポイントです。低遅延を必要とする場合、配信保証よりも低遅延を優先する場合、UDPはそのトレードオフを明確にします。信頼性の論理はアプリケーション層に移動し、実際に再送が必要なものをスマートに判断できるようになります。

ゲームにおいて、50ms前のプレイヤーの位置更新は無価値です — あなたは現在のものが必要です。TCPでは、バッファに保持して待つ必要があります。UDPでは、最新の状態を送信し、古いものにスキップします。パケットの損失が増える場合でも、経験はスムーズになります。

TCPとUDP:実際に重要な比較

財産TCPUDP
接続の設定3-wayハンドシェイク(最初のバイトが送信される前に1.5×RTTを追加)なし — すぐに送信
配信保証はい — 損失時に再送いいえ — 送信して忘れる
パケットの順序スタックによって強制されるあなたの問題
ヘッド・オブ・ライン・ブロッキングはい — 1つのパケットが失われるとストリームが停止するいいえ — 各データグラムは独立している
コンゲスト制御組み込まれている(CUBIC、BBRなど)なし — 自分で実装またはスキップ
典型的な遅延オーバーヘッド冷たい接続では150–300msマイクロ秒未満
ユースケースHTTP/1.1、HTTP/2、データベース、ファイル転送、メールDNS、ゲーム、ライブビデオ、HTTP/3(QUIC)

各プロトコルが実際に属する場所

DNSはUDPで動作 — そしてその中には教訓がある

あなたのアプリケーションが行うすべてのDNSクエリは、デフォルトでUDPで行われます。リクエストは1つのパケットに収まり、応答も1つのパケットに収まり、1回のリターントリップで答えを得ます。ハンドシェイクのオーバーヘッドやサーバー側で維持する状態がありません。

応答が大きすぎる場合(DNSSECレコード、多くのAレコード)には、DNSはTCPに切り替わります。しかし、一般的なケース — ホスト名の検索 — は純粋なUDPです。なぜなら、3-wayハンドシェイクが実際のクエリより長くなるからです。

この行動を実際に見ることができるツールは IO Tools DNS Lookup tool — ドメインを入力し、個々のレコードタイプがどれだけ速く解決するかを観察してください。そのスピードは、ハンドシェイクオーバーヘッドを削除しているUDPによるものです。

ゲーム:UDPは唯一の解決策です

主要なゲームネットワーキングライブラリ — ValveのGameNetworkingSockets、EpicのEOSトランスポート、UnityのUTP — はすべてUDPに基づいています。その理由は、ヘッド・オブ・ライン・ブロッキングです。

競技型FPSでは、15msごとに64tickの位置更新を送信しています。1つのパケットが失われた場合、TCPは次の5つのパケットを再送待ちに留め、75msのストutterをちょうど間違ったタイミングで導入します。UDPでは、次の更新をすぐに送信します。クライアントはそのギャップを補完します。経験はスムーズになります。

ほとんどのゲームネットワーキングコードはUDPに基づいており、データが必要な場合にのみ、選択的な信頼性(シーケンス番号、優先度キュー、選択的ACK)を実装しています。位置データは設計上信頼性がありません。古い読み取りは、読み取りがないよりも悪です。

ビデオストリーミング:使用ケースに依存する

ライブストリーミング(Twitch、スポーツ中継)はUDPベースのプロトコル(RTP、WebRTC、SRT)を使用しています。いくつかのフレームが失われても問題ないが、遅延は許容できない。ライブマッチの30秒をバッファリングして平滑な配信を保証することはできません。

VOD(Netflix、YouTube)は実際にはTCPを使用しています。バッファリングがコストを隠しているためです。数秒のプレバッファが、TCPの再送オーバーヘッドを無視させます。あなたが昨日の出来事を見ている場合、遅延のペナルティは意味を持ちません。

HTTP/3はUDP上で動作 — そしてウェブパフォーマンスを変える

HTTP/3はQUIC上で動作し、QUICはUDP上で動作します。GoogleはQUICを構築し、ウェブトラフィックのTCPのヘッド・オブ・ライン・ブロッキング問題を解決するために設計しました。HTTP/2 over TCPでは、1つのパケットが失われた場合、その接続を共有するすべてのマルチプレクスストリームが停止します。QUICは、トランスポート層でストリームマルチプレクスを実装し、独立した確認を実行することで、1つのパケットが失われた場合、1つのストリームだけが停止します。

QUICはハンドシェイクにTLSを統合し、冷たい接続の設定を1回のリターントリップ(セッションリソースの場合は0-RTT)に削減します。損失のあるネットワーク(モバイル接続、混雑したWi-Fi)では、これは意味のある改善です。2024年現在、およそ 30%のウェブサイトがHTTP/3をサポートしています、そしてすべての主要なブラウザがデフォルトで有効にしています。Cloudflareや現代的なCDNの後ろでデプロイしている場合、明示的に設定しなくてもHTTP/3を提供している可能性があります。

実用的な決定ツリー

新しいプロトコルまたはサービスのトランスポートを選択する際の質問は「TCPまたはUDP?」ではなく「どの失敗を耐えられるか?」です。

  • すべてのバイトが順番に到着しなければ、操作は失敗する → TCP。ファイルアップロード、データベース接続、API呼び出し、メール。データが欠落すると、データが破損またはパースエラーになります。
  • 遅延が配信保証よりも重要である → UDP。ゲーム、ライブビデオ、音声通話、センサーテレメトリ。古い読み取りは、読み取りがないよりも悪です。
  • 1メッセージごとに両方必要 → UDP上で選択的な信頼性を構築します。QUICはこれを行います。WebRTCのSCTPデータチャンネルもこれを行います。ENetやGameNetworkingSocketsなどのライブラリもこれを行います — ただし、自分で実装する場合、誤りを容易に引き起こすため、非常に難しい作業になります。

一つの誤りを指摘します:「内部トラフィック」というのはUDPを無視して使えると誤解していることです。データセンター内のパケット損失は稀ですが、ゼロではありません — ハードウェアの故障、ピーク負荷時のネットワーク混雑、誤設定されたスイッチ。アプリケーションがパケット損失時にデータを静かに腐食する場合、内部ネットワークはあなたを救いません。

まとめ

TCPは、ほとんどのアプリケーションコードのデフォルトとして適しています。API呼び出し、データベースとの通信、ファイル転送を行う場合、TCPの保証はまさに必要であり、人間の時間スケールではオーバーヘッドは見えません。

UDPは、遅延が硬い制約であり、アプリケーションが信頼性との関係を所有できる場合に適しています。これは特定の問題セット — リアルタイムゲーム、ライブメディア、カスタムプロトコル — ではなく、TCPが遅いと感じたときに一般的なパフォーマンス最適化を求めるものではありません。

実際に間違っているのは、UDPが速い場合にTCPを使うことではなく、どのプロトコルを選ぶのか、なぜ選ぶのかを知らないこと、そして失敗モードが現れたときに驚くことです。

広告なしで楽しみたいですか? 今すぐ広告なしで

拡張機能をインストールする

お気に入りのブラウザにIOツールを追加して、すぐにアクセスし、検索を高速化します。

に追加 Chrome拡張機能 に追加 エッジ拡張 に追加 Firefox 拡張機能 に追加 Opera 拡張機能

スコアボードが到着しました!

スコアボード ゲームを追跡する楽しい方法です。すべてのデータはブラウザに保存されます。さらに多くの機能がまもなく登場します!

ニュースコーナー 技術ハイライト付き

参加する

価値ある無料ツールの提供を継続するためにご協力ください

コーヒーを買って