TCP/IP通信の状態を調べる「netstat」コマンドを使いこなす【Windows OS】Tech TIPS(1/2 ページ)

TCP/IP関連のトラブルシューティングでは定番といえるWindows OS標準の「netstat」コマンド。主にTCPの通信状態を調べるコマンドであり、通信の状態や通信相手、通信しているプロセス、通信量などの情報を知ることができる。その使い方を解説する。

» 2023年02月01日 05時00分 公開

この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。

「Tech TIPS」のインデックス

連載目次

TCP/IP通信の状態を調べる「netstat」コマンドを使いこなす

対象OS:Windows 10/Windows 11、Windows Server 2012/Windows Server 2012 R2/Windows Server 2016/Windows Server 2019/Windows Server 2022


 TCP/IP関連のトラブルシューティングを行う場合に、必ずといってよいほど使うコマンドとして「netstat」コマンドがある(実行ファイル名はnetstat.exe)。このコマンドは、主にTCPの通信状態を調べるためには必須であり、ぜひともその使い方をマスターしておきたい。

netstatの基本――通信中のTCPコネクションの調査

 netstatコマンドの最も基本的な使い方は、通信中のTCPコネクション(TCP接続)の状態を表示させることである。このコマンドを実行すると、ローカルPCのTCP/IPプロトコルスタック上において、現在アクティブになっているTCP通信の状態を表示できる。

●「TCP」とは? 「コネクション」とは?

 TCPとは、2つのアプリケーション間で、信頼性のある通信路(コネクション)を開設し、お互いにデータなどをやりとりするための機能である。通信するアプリケーションは、同一PC上のアプリケーション同士でもよいし、異なるPC(ホスト)上にある2つのアプリケーション間でもよい。

 例えばWebブラウザを使ってWebサーバにアクセスする場合、実際にはHTTP(Hypertext Transfer Protocol)というプロトコルが利用される。WebサーバのHTTPポート(TCPの80番ポート)とWebブラウザの間でTCPコネクションが開設され(クライアント側のポート番号は任意)、Webサーバへコマンドを送ったり、Webサーバからの応答メッセージを受信したりする。

TCPの通信モデル TCPの通信モデル
TCPは、2つのコンピュータ間(アプリケーション間)で通信路(コネクション)を開設し、お互いにデータをやりとりするための機能である。例えばWebサーバへ接続する場合、TCPを使ってWebサーバ(の80番ポート)とWebブラウザの間で通信路を作成する。TCPでは、それぞれのポート番号とIPアドレスの組み合わせでコネクションを識別する。

●netstatコマンドを実行してTCP通信を覗いてみる

 現在どのようなTCP通信が行われているかは、netstatコマンドを使うと表示させることができる。まずは何もオプション引数を付けずにnetstatコマンドを実行してみる(以下、全てWindows 11上で実行)。

引数なしでnetstatコマンドを実行する 引数なしでnetstatコマンドを実行する
netstatコマンドにオプションなどの引数を付けずに実行すると、現在アクティブなTCPコネクションの一覧が表示される。

 何もオプション引数を付けずにnetstatを実行すると、現在アクティブなTCPコネクションの状態が表示される(後述する「状態」が「LISTENING」ではないコネクションが表示される)。

 以下では、netstatが表示するTCPコネクション一覧の各列について説明していく。

●「プロトコル」列

 「プロトコル」列には使用中のネットワークプロトコルの種類が表示される。後述する「-a」オプションを付けていない場合は、常に「TCP」と表示されているはずである。UDPにはコネクションを確立するという概念がないので(UDPではデータを単発的に送るだけなので)、このコマンドではUDPの通信状態は表示されない。

●「ローカル アドレス」「外部アドレス」列

 「ローカル アドレス」は、ローカル側のコンピュータ名(もしくはIPアドレス)と使用中のTCPのポート番号である。「外部アドレス」は、通信の相手となっているマシンのコンピュータ名(もしくはIPアドレス)とポート番号である。

 「ローカル アドレス」に表示されるIPアドレスは固定的ではない。1台のマシンには複数のIPアドレスを付けることができるし、ローカルのループバックアドレス(IPv4なら「127.0.0.1」、IPv6なら「[::1]」など)が使われていることもあるからだ。また同じマシン同士でもコネクションを確立できるので、「外部アドレス」が自分のIPアドレスの場合もある。

 「:(コロン)」の左側に表示されているのが「コンピュータ名」または「IPアドレス」で、右側に表示されているのが「ポート」(サービス名番号)である。例えば「MYPC001:16664」は「MYPC001」というPCの「16664」番のポートを表している。また「a110-232-152-80:http」は、「a110-232-152-80」というコンピュータの「http」というサービスのポート(80番)を表している。

●「状態」列

 「状態」は、その名の通りTCPコネクションの「状態(ステート)」を表すものだ。例えば「LISTENING」は待ち受け状態、「ESTABLISHED」は通信が確立した状態、「TIME_WAIT」はコネクションの終了待ち状態をそれぞれ表していて、通信中にはこれらの状態から別の状態に移る「状態遷移」がひんぱんに生じる(詳しくはすぐ後で説明する)。

●TCPコネクションの識別単位

 netstatで1行ずつ表示されるTCPのコネクションは、次の4つの組み合わせで識別される。

  • ローカルのIPアドレス
  • ローカルのポート番号
  • リモートのIPアドレス
  • リモートのポート番号

 このうち、どれか1つでも値が異なれば別のコネクションとして扱われるので、例えばWebサーバとの通信を行っていると、同じような値のコネクションが複数表示されることがある。Webブラウザは、高速化のために複数のTCPコネクションを使うのが一般的だからだ。しかし、よく見るとローカル側(左側)のポート番号が違っているはずである。

netstatの「状態」列に表示されるTCPの「状態遷移」とは?

 netstatでTCPの通信を調べるには、TCPのステート(状態)の移り変わり、すなわち「状態遷移」について理解しておく必要がある。TCPの詳細については解説「TCP(Transmission Control Protocol)」を参照していただくとして、ここでは状態遷移にフォーカスして説明しよう。

 TCPはステート(状態)を持つプロトコルであり、コネクションの開始や終了、通信方法などに関して細かい手順が決められている。サーバとクライアントのどちらの側から先に通信を開始するのか、データの送受信はどうするのか、終了する場合はどうするのか、などが厳密に決まっている。

 また通信速度は有限なので、送信したコマンドが相手側へ届くまでにはタイムラグがある。ローカル側から先に終了コマンドを送ったとしても、それが相手側に届く前に、相手側から先に終了要求が到着することがある。そのような状況でも、破綻のないように処理手順が決められている。

 次の図はTCPの状態遷移を大まかに表している。この図中の白い四角の中に書いてある「SYN_SENT」や「ESTABLISHED」などが、netstatコマンドの「状態」列に表示される。

TCPの状態遷移図 TCPの状態遷移図
TCPの規格書(RFC793)に記載の状態遷移図を簡略化して、分かりやすくしたものだ。四角の中に書かれているのがTCPの状態名。矢印は可能な遷移の経路。矢印のそばにある文字は「トリガ(アクション)」を表しており、ある「トリガ」となるイベントが発生すると指定された「アクション」を実行して、次の状態へ遷移する。各状態の詳細は下表で説明する。

 上図で色分けされたブロックは、TCPの状態を大まかに分類したものだ。それぞれの意味を下表に記す。

TCPの状態(大分類) 意味
パッシブオープン TCPの接続要求を受け付ける側。いわゆるサーバ側は、このLISTEN状態でクライアントからの接続を待ち受けしている。例:Webサーバなど
アクティブオープン TCPの接続要求を送信する側。LISTEN状態のTCPのポートに対して、接続を試みる側。例:Webブラウザなど
通信確立 TCPの接続が確立して、通信中の状態。双方からデータを送信可能な状態(通信路がアクティブな状態)
アクティブクローズ 先に終了要求を送信する側
パッシブクローズ 相手から終了要求を受け取って、自分自身も終了処理を実行する状態
TCPの状態(大分類)

 細かい状態(図中の白い四角)の意味は次の通りである。これを調べることにより、コネクションの状態がどうなっているか、開始しようとしているのか、待ち受け中なのか、終了しようとしているのか、などが分かる。

TCPの状態(詳細) 頻度 意味
CLOSED 未使用状態のTCPポート。通常これが表示されることはない
LISTENING 待ち受け状態(リッスン状態)のポート。netstatに「-a」オプションを付けると表示される
SYN_SENT サーバに対して、通信開始の要求(SYN:Synchronize)を送信したが、まだそれに対する応答(ACK:Acknowledgement)を受け取っていない状態。相手が無応答のときもこの状態になる。ACKを受け取るとESTABLISHEDへ遷移する
SYN_RECEIVED クライアントからSYN要求を受け取った直後の状態。SYNに対するACKを送信するとESTABLISHEDへ遷移する
ESTABLISHED TCPコネクションが確立して通信している状態。netstatでは最もよく見る状態。どちらかが終了処理を始めると、FIN_WAIT_1もしくはCLOSE_WAITへ遷移する
FIN_WAIT_1 自分の側から先にFINを送信した状態。そのFINに対するACKを相手から受信すると、FIN_WAIT_2へ遷移するが、先に相手からのFINを受けるとCLOSINGへ遷移する
FIN_WAIT_2 FINに対するACKを受信した状態。相手からのFINを受信して、それに対するACKを返すと、TIME_WAITへ遷移する
CLOSE_WAIT 相手からのFINを受け取った状態。アプリケーションが終了すると、FINを送信してからLAST_ACKへ遷移する
CLOSING FINに対する相手からのACKを受けるとTIME_WAITへ遷移する
LAST_ACK 送信したFINに対するACK待ち状態。ACKを受け取るとCLOSEDへ遷移して終了する(netstatの表示から消える)
TIME_WAIT コネクションの終了待ち状態。しばらく待ったあと、CLOSEDへ遷移して終了する(netstatの表示から消える)
TCPの状態(詳細)
ここでは最初にリッスンしている(待ち受けしている)方をサーバ、そのサーバに接続要求を送る方をクライアントとしている。「頻度」列は、netstatコマンドを実行したときに、その状態をユーザーが見る可能性の高さを表している。

 前述のようにnetstatコマンドの「状態」列に表示される文字列は、TCPコネクションの開始から確立、終了までの一連の(内部的な)状態遷移を表している。「LISTENING」「ESTABLISHED」はよく目にする一方で、それ以外のものはすぐに他の状態に遷移してしまうので、見る機会は少ない。

IPアドレスやポート番号を数値で表示させるには(「-n」オプション)

 netstatではデフォルトで、IPアドレスやTCP/UDPポート番号が文字列で表示される。「-n」オプションを付けると、IPアドレスやポート番号が全て数値で表示されるようになる。

netstat -nで数値表示させる netstatの「-n」オプションで数値表示させる
netstat -n」コマンドを実行すると、ポート番号やPC名(ホスト名)などが文字列ではなく、数値のみで表示される。IPアドレスから名前を求める名前解決処理を行わないので、結果が素早く表示される。ただしIPアドレスがそのまま表示されるので、通信相手などが分かりづらい。通常は「-n」オプション付きで素早く実行させ、必要に応じて「-n」オプションなしで利用するとよいだろう。

 TCP/IPでは、IPアドレスやポート番号は全てこのように数値で表現するのが基本である。しかしこれでは人間にとって非常に分かりづらいので、文字列を使って代用することもできるようになっている。

 そのためのメカニズムとしては、IPアドレスならDNShostsファイルによる「FQDN/ホスト名←→IPアドレス」の相互変換システムがある(これを「名前解決」という)。ポート番号ならservicesファイルによる「サービス名←→ポート番号」の相互変換機能がある。hostsファイルやservicesファイルは、Windows OSでは「%windir%\system32\drivers\etc」フォルダに置かれている。

 netstatに「-n」オプションを付けないと、これらの変換機構を使って、なるべくIPアドレスやポート番号を具体的なホスト名やサービス名に変換して出力するので、人間にとっては分かりやすい(変換できないものについては、そのまま数値で出力される)。しかし1台のホストに複数のIPアドレスが付けられていたり、サービス名だけでははっきりとは分からなかったりする場合は、「-n」オプションを使って実際の数値で確認する必要がある。

 また「-n」オプションを付けて実行すると、DNSサーバなどに対する問い合わせが行われないので、結果がすぐに表示されるという利点もある。

 Webブラウザでインターネット上のサイトを閲覧しているような場合には、外部IPアドレスがインターネット上のホストになる。この場合は、外部のDNSサーバに対してDNSの逆引き(IPアドレスからFQDN/ホスト名への変換)を実行するので、かなり待たされる。さらにはコネクションごとに逆引き操作が必要になるので、通信の状態を素早く調べたい場合には「-n」オプションを付けて逆引きを抑制した方がよい。

 どうしても具体的なホスト名が必要ならば、別途「nslookup」コマンドなどで調べるか(Tech TIPS「DNSトラブル解決の定番、nslookupの基本的な使い方(社内ネットワーク編)」参照)、最後に1回だけ「-n」オプションなしでnetstatを実行すればよいだろう。

ホスト名をFQDNで表示させるには(「-f」オプション)

 「-f」オプションを付けると、リモート(外部アドレス)のコンピュータ名がFQDNで表示されるようになる。

 例えば「a1234.sys.example.jp」というFQDNを持つコンピュータと通信している場合、「-f」オプションがないと単に「a1234」としか表示されない。そこで「-f」オプションを付けると、完全なDNS名で表示される。表示が長くなって見づらくなる半面、どのコンピュータと通信しているかが分かりやすくなる。

netstatの「-f」オプションで、ホスト名をFQDNで表示させる netstatの「-f」オプションで、ホスト名をFQDNで表示させる

       1|2 次のページへ

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。