한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

ゲームラグ白書 › 一部のユーザーだけに起きる問題

固定UDPポートの衝突 Two clients bound to the same local UDP port

原因ID pt-port-collision · 主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発

図と実験のあるメインページでこのカードを開く →

クライアントが決まったローカルポートを使うように作られていると、同じPCの2つ目のクライアントはそのポートを使えないか、1つ目とパケットを分け合って受け取ることになります。

なぜ 2つのクライアントが同じローカルUDPポートを開こうとする(再利用オプションで無理に共有) → すると OSが届いたパケットを片方のソケットにだけ渡すか、どちらが受け取るかを保証しない。ルーターとサーバーも2つのクライアントを同じアドレスとみなす → 画面では 片方はワールドのパケットを受け取れず、NPC・ほかのプレイヤーが表示されないか切断される

症状
表示されない・ゴースト, 切断, 接続不可・無限ロード
要因
パケットロス
誰に起きるか
同じPCの片方のクライアントだけ
いつ
接続直後・メンテ明け, 常に
担当
主担当 ゲーム開発チーム・クライアント開発 · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応
クライアント:ローカルポートはOSに自動で選ばせる(0番をバインド)。サーバー:接続ごとに発行したセッショントークンで接続を区別。
グラフでは
一部だけ高い · クライアントごとの受信パケット数
確認箇所
ユーザーのPCで2つのクライアントを起動したまま、コマンドプロンプトでnetstat -ano -p udpを実行し、ゲームプロセス(PID)ごとに開いているローカルUDPポートを確認。サーバー側では、2つのセッションが同じグローバルIP・同じポートから来ているかを確認
該当する場合
2つのゲームプロセスが同じローカルポートにバインドされているか、サーバーから2つのセッションが同じIP・ポートに見える。片方だけ起動すれば正常
該当しない場合
2つのクライアントが別々のローカルポートを使っているのに片方がおかしいなら、IP・端末基準のセッション識別バグか、多重起動の制限
確認手段
ユーザー側の環境で確認

出典

  1. Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE Microsoft
    SO_REUSEADDRで同じポートに2つ目のbindをするとポートを横取りし、どのソケットがパケットを受け取るかわからない
  2. bind function (winsock.h) Microsoft
    ポートを0でbindすると、動的ポート範囲(49152〜65535)から一意のポートを割り当てる
  3. netstat Microsoft
    -aはTCP・UDPポート、-nは数値アドレス、-oはプロセスID(PID)、-p udpはUDPだけを表示

あわせて読みたい原因

同じ層:一部のユーザーだけに起きる問題

同じ症状(表示されない・ゴースト)を起こすほかの層の原因

図と実験のあるメインページでこのカードを見る