関連記事
GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ
概要
以下、自分用のメモです。よく忘れるのでここにメモメモ。。。。
私の周りで発生した問題だったのですが、ソケット処理で特定のポート番号でリスナー起動して接続受付する普通のプログラム作っていたが
ある日、それまで動いていたアプリが突然以下のエラーを吐きました。
System.Net.Sockets.SocketException (0x80004005): アクセス許可で禁じられた方法でソケットにアクセスしようとしました
スタックトレース見ると System.Net.Sockets.Socket.DoBind メソッドの呼び出しで発生しているので、そのまんまバインド出来ていないのは分かるのですが、このポートを利用しているプログラムなんて存在しない状態です。なので、普通に考えるとバインド出来るはず。
そういうときは、このポート番号が除外ポート範囲に入っていないかどうかを確認すると、解決する可能性が高いです。
Windowsの「除外ポート範囲」とは Hyper-VとかWSL2とかDocker Desktopなどの機能が、コンテナ間通信やNATのためにOSレベルで排他的に予約(占有)しているポート範囲のこと。
この範囲のポートはアプリケーションからBind(待受)できません。管理者権限でも無理。winnatサービスが管理しています。
今回のパターンでは、まさにこのパターンでした。最終的に「除外ポート範囲」ではない部分のポート番号に直したら動きました。
以下は、その除外ポート範囲を探す際に使えるコマンドのメモです。
ポート範囲を探すコマンド
除外ポート範囲を探す
netsh interface ipv4 show excludedportrange protocol=tcp
実行すると例えば以下のように出たりします。
プロトコル tcp ポート除外範囲 開始ポート 終了ポート ---------- -------- 50000 50059 * 54096 54096 63212 63311 63312 63411 63507 63606 63665 63764 63765 63864 * - 管理されている除外ポート。
この範囲のポート番号はバインド出来ません。
動的ポートの範囲を調べる
netsh int ipv4 show dynamicport tcp
大抵、以下のように出るはずです。
プロトコル tcp の動的ポートの範囲 --------------------------------- 開始ポート : 49152 ポート数 : 16384
前述した、 Hyper-VとかWSL2とかDocker Desktopなどは、この動的ポートの範囲から利用するポートブロックを確保します。
なので、開始ポートより小さいポート番号を利用するべきですね。
なので、1024 から 49151 ポートまでを使うのが安全ってことになります。つまり俗に言う「User Ports」の範囲でポート番号を使うのが安全。
(個人的には1024から9999までもあまり使いません。大抵10000以降を利用することが私の場合は多いです)
参考情報
過去の記事については、以下のページからご参照下さい。
サンプルコードは、以下の場所で公開しています。