対象OS:Windows 7/Windows 8.1/Windows 10/Windows Server 2008 R2/Windows Server 2012/Windows Server 2012 R2/Windows Server 2016
TCP/IP関連のトラブルシューティングを行う場合に、必ずといってよいほど使うコマンドとして「netstat」コマンドがある(実行ファイル名はnetstat.exe)。このコマンドは、主にTCPの通信状態を調べるためには必須であり、ぜひともその使い方をマスターしておきたい。
netstatコマンドの最も基本的な使い方は、通信中のTCPコネクション(TCP接続)の状態を表示させることである。このコマンドを実行すると、ローカルPCのTCP/IPプロトコルスタック上において、現在アクティブになっているTCP通信の状態を表示できる。
TCPとは、2つのアプリケーション間で、信頼性のある通信路(コネクション)を開設し、お互いにデータなどをやりとりするための機能である。通信するアプリケーションは、同一PC上のアプリケーション同士でもよいし、異なるPC(ホスト)上にある2つのアプリケーション間でもよい。
例えばWebブラウザを使ってWebサーバにアクセスする場合、実際にはHTTP(Hypertext Transfer Protocol)というプロトコルが利用される。WebサーバのHTTPポート(TCPの80番ポート)とWebブラウザの間でTCPコネクションが開設され(クライアント側のポート番号は任意)、Webサーバへコマンドを送ったり、Webサーバからの応答メッセージを受信したりする。
現在どのようなTCP通信が行われているかは、netstatコマンドを使うと表示させることができる。まずは何もオプション引数を付けずにnetstatコマンドを実行してみる(以下、全てWindows 10上で実行)。
何もオプション引数を付けずにnetstatを実行すると、現在アクティブなTCPコネクションの状態が表示される(後述する「状態」が「LISTENING」ではないコネクションが表示される)。
「プロトコル」欄は使用中のネットワークプロトコルの種類であり、次項で述べる「-a」オプションを付けていない場合は、常に「TCP」と表示されているはずである。UDPにはコネクションを確立するという概念がないので(UDPではデータを単発的に送るだけなので)、このコマンドではUDPの通信状態は表示されない。
「ローカル アドレス」欄は、ローカル側のコンピュータ名(もしくはIPアドレス)と使用中のTCPのポート番号である。「外部アドレス」欄は、通信の相手となっているマシンのコンピュータ名(もしくはIPアドレス)とポート番号である。1つのマシンには複数のIPアドレスを付けることができるし、ローカルのループバックアドレス(IPv4なら「127.0.0.1」、IPv6なら「[::1]」など)が使われていることもあるので、「ローカル アドレス」に表示されるIPアドレスは固定的ではない。また同じマシン同士でもコネクションを確立できるので、「外部アドレス」が自分のIPアドレスの場合もある。
「:」記号の左側に表示されているのが「コンピュータ名」(もしくは「IPアドレス」)で、右側に表示されているのが「ポート」(サービス名か番号)である。例えば「MYPC001:16664」は「MYPC001」というPCの「16664」番のポートを表している。また「a110-232-152-80:http」は、「a110-232-152-80」というコンピュータの「http」というサービスのポート(80番)を表している。
TCPのコネクションは、「ローカルのIPアドレス/ローカルのポート番号/リモートのIPアドレス/リモートのポート番号」という4つの組み合わせで識別される。どれか1つでも値が異なれば別のコネクションとして扱われるので、例えばWebサーバとの通信を行っていると、同じような値のコネクションが複数表示されることがある。Webブラウザは、高速化のために複数のTCPコネクションを使うのが一般的だからだ。だがよく見ると、ローカル側(左側)のポート番号が違っているはずである。
netstatコマンドの「状態」欄は、その名の通りTCPコネクションの「状態」を表すものだ。TCPはステート(状態)を持つプロトコルであり、コネクションの開始や終了、通信方法などに関して細かい手順が決められている。サーバとクライアントのどちらの側から先に通信を開始するのか、データの送受信はどうするのか、終了する場合はどうするのか、などが厳密に決まっている。
また通信速度は有限なので、送信したコマンドが相手側へ届くまでにはタイムラグがある。ローカル側から先に終了コマンドを送ったとしても、それが相手側に届く前に、相手側から先に終了要求が到着することがある。そのような状況でも、破綻のないように処理手順が決められている。
次にTCPの状態遷移図を示しておく。TCPの詳細については解説「TCP(Transmission Control Protocol)」を参照していただきたい。この図中の白い四角の中にある中に書いてある「SYN_SENT」や「ESTABLISHED」がnetstatコマンドで表示されている「状態」になっている。
それぞれの状態の意味は次の通りである。これを調べることにより、コネクションの状態がどうなっているか、開始しようとしているのか、待ち受け中なのか、終了しようとしているのか、などが分かる。
状態 | 頻度 | 意味 |
---|---|---|
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コマンドの状態欄に表示される文字列は、TCPコネクションの開始から確立、終了までの一連の(内部的な)状態遷移を表している。ここでは最初にリッスンしている(待ち受けしている)方をサーバ、そのサーバに接続要求を送る方をクライアントとしている。TCPでは、SYNやFINを送ると、それに対するACK応答を必ず待つ(TCPは双方向通信をサポートしているので、SYNやFINの送信とACKの確認作業は双方向で行われる)。「頻度」は、netstatコマンドを実行したときに、その状態をユーザーが見る可能性の高さを表している。LISTENINGやESTABLISHEDはよく目にするが、それ以外のものはすぐに他の状態に遷移してしまうので、見る機会は少ない。 |
先の例では、IPアドレスやTCP/UDPポート番号が文字列で表示されていたが、「-n」オプションを付けると、IPアドレスやポート番号が全て数値で表示されるようになる。
TCP/IPのプロトコルでは、IPアドレスやポート番号は全てこのように数値で表現するのが基本である。しかしこれでは人間にとって非常に分かりづらいので、文字列を使って代用することもできるようになっている。このためのメカニズムとしては、IPアドレスならDNSやhostsファイルによる「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」コマンドなどで調べるか(TIPS「nslookupの基本的な使い方」参照)、最後に1回だけ-nなしでnetstatを実行すればよいだろう。
「-f」オプションを付けると、リモート(外部アドレス)のコンピュータ名がFQDNで表示されるようになる。例えば「a1234.sys.example.jp」というFQDN名を持つコンピュータと通信している場合、-fオプションがないと単にa1234としか表示されないが、-fを付けると完全なDNS名で表示される。表示が長くなって見づらくなるが、どのコンピュータと通信しているかが分かりやすくなる。
Copyright© 1999-2018 Digital Advantage Corp. All Rights Reserved.
会社で使っているクラウドサービス。データが「社外のインターネットの向こう側」にあることを意識していますか? 生産性と安全を両立するために必要なことは。
@IT Special
- PR -この記事に関連する製品/サービスを比較(キーマンズネット)
Windows Server Insider 記事ランキング
あなたにオススメの記事
- PR -