ゲームラグ白書 › 一部のユーザーだけに起きる問題
固定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・端末基準のセッション識別バグか、多重起動の制限
- 確認手段
- ユーザー側の環境で確認
出典
- Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE Microsoft
SO_REUSEADDRで同じポートに2つ目のbindをするとポートを横取りし、どのソケットがパケットを受け取るかわからない - bind function (winsock.h) Microsoft
ポートを0でbindすると、動的ポート範囲(49152〜65535)から一意のポートを割り当てる - netstat Microsoft
-aはTCP・UDPポート、-nは数値アドレス、-oはプロセスID(PID)、-p udpはUDPだけを表示
あわせて読みたい原因
同じ層:一部のユーザーだけに起きる問題
同じ症状(表示されない・ゴースト)を起こすほかの層の原因
図と実験のあるメインページでこのカードを見る