ゲームラグ白書 › L8 ソケットとプロトコル
WindowsのUDPソケットのWSAECONNRESETエラー WSAECONNRESET on a Windows UDP socket
原因ID sk-udp-connreset · 主担当 ゲーム開発チーム・サーバー開発
図と実験のあるメインページでこのカードを開く →
Windowsサーバーがすでに去ったクライアントにUDPを送ると、「ポート到達不能」(ICMP)の通知が返ってきます。その通知のせいで次の受信呼び出しがエラーで終わりますが、サーバーのコードがこのエラーをソケット自体の故障として扱うと、そのソケットを使っている全員が影響を受けます。
なぜ 出ていったばかりのクライアントのアドレスにUDPを送り続け、「ポート到達不能」(ICMP)の通知が返ってくる → すると Windowsが次の受信呼び出しをWSAECONNRESET(10054)エラーで終わらせ、サーバーのコードが受信を止めるかソケットを閉じる → 画面では そのソケットを使っていた全員が一斉にフリーズ・切断
- 症状
- 切断, フリーズ
- 要因
- パケットロス, ストール
- 誰に起きるか
- サーバー全体
- いつ
- ときどきランダムに, 接続直後・メンテ明け
- 担当
- 主担当 ゲーム開発チーム・サーバー開発
- ゲーム開発チームの対応
- WSAIoctlでSIO_UDP_CONNRESETを無効にしてこの通知を受け取らない、受信エラーが起きてもログだけ残して受信を続ける。
- グラフでは
- 接続が一斉に切れる · 接続数、受信エラーのログ
- 確認箇所
- ゲームサーバーのログからUDP受信のエラーコード(WSAECONNRESET、10054)と、受信ループが止まったりソケットを閉じたりした記録を探し、サーバー側のパケットキャプチャで直前にICMP Port Unreachableが届いたかを確認
- 該当する場合
- 接続が一斉に切れる直前にWSAECONNRESETの受信エラーが記録され、その前に、出ていったばかりのクライアントのアドレスからICMP Port Unreachableが届いている
- 該当しない場合
- Linuxサーバーであるか、コードでSIO_UDP_CONNRESETを無効にしていれば該当しない
- 確認手段
- ゲームサーバー・クライアントのログ・メトリクスが必要
出典
- Winsock IOCTLs Microsoft
SIO_UDP_CONNRESETで、UDPの「ポート到達不能」(PORT_UNREACHABLE)通知の報告を有効・無効にする - recvfrom function (winsock.h) Microsoft
UDPソケットのWSAECONNRESETは、以前の送信がICMP Port Unreachableを受け取ったという意味 - Windows Sockets Error Codes Microsoft
WSAECONNRESETのエラー番号は10054
あわせて読みたい原因
同じ層:L8 ソケットとプロトコル
同じ症状(切断)を起こすほかの層の原因
図と実験のあるメインページでこのカードを見る