0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

WindowsTCP/IPネットワーク

Last updated at Posted at 2025-02-24

はじめに

本記事は自分の学習記録&技術力向上を目的としており、ほぼすべてが以下のページからの抜粋となっております。営利目的ではありません。詳しいことを学びたい方は以下ページを参照したほうがよいです。

引用元:

netstatとは

Windowsのコマンド。実行ファイル名はnetstat.exe。
現在アクティブになっているTCPコネクションの状態を表示することができる。

TCPの通信モデル

以下のようにIPアドレスとポート番号を指定してTCPコネクションを確立する。

例えばWebブラウザを使ってWebサーバにアクセスする場合、実際にはHTTP(Hypertext Transfer Protocol)というプロトコルが利用される。WebサーバのHTTPポート(TCPの80番ポート)とWebブラウザの間でTCPコネクションが開設され(クライアント側のポート番号は任意)、Webサーバへコマンドを送ったり、Webサーバからの応答メッセージを受信したりする。
image.png
TCPの通信モデル
TCPは、2つのコンピュータ間(アプリケーション間)で通信路(コネクション)を開設し、お互いにデータをやりとりするための機能である。例えばWebサーバへ接続する場合、TCPを使ってWebサーバ(の80番ポート)とWebブラウザの間で通信路を作成する。TCPでは、それぞれのポート番号とIPアドレスの組み合わせでコネクションを識別する。

引用元:https://atmarkit.itmedia.co.jp/ait/articles/0207/20/news003.html

netstatコマンド実行

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

引用元:https://atmarkit.itmedia.co.jp/ait/articles/0207/20/news003.html

各列の説明

  • 「プロトコル」列

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

  • 「ローカルアドレス」「外部アドレス」列
    コンピュータ名(もしくはIPアドレス)と使用中のTCPのポート番号が表示。

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

同じマシン同士でもコネクションを確立できるので、「外部アドレス」が自分のIPアドレスの場合もある。

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

  • 「状態」列

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

TCPはステート(状態)を持つプロトコルであり、コネクションの開始や終了、通信方法などに関して細かい手順が決められている。サーバとクライアントのどちらの側から先に通信を開始するのか、データの送受信はどうするのか、終了する場合はどうするのか、などが厳密に決まっている。
また通信速度は有限なので、送信したコマンドが相手側へ届くまでにはタイムラグがある。ローカル側から先に終了コマンドを送ったとしても、それが相手側に届く前に、相手側から先に終了要求が到着することがある。そのような状況でも、破綻のないように処理手順が決められている。

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

TCPコネクションには「アクティブ」側と「パッシブ」側がある。

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

CLOSEDは表示されない。
「-a」オプションをつけるとLISTENING状態のTCPコネクションが出てくる。
SYN_SENTはSYNに対する応答ACKを受信していない状態。送信相手が無応答の時もこの状態になる。

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

「LISTENING」状態とはどういうことか

「LISTENING」状態とは、プロセスが聞く準備ができている状態のことをいう。
ポートが開いていたとしてもプロセスが死んでいると通信できない(netstatでLISTENING状態か確認)。
プロセスが聞く準備ができている状態でもポートが空いていないと通信できない(ポートが別プロセスに使用されていないか、ファイアーウォール機能で閉じられていないか確認)。

プロセスとコネクションの関連を調べるには(「-o」、「-b」オプション)

「-o」オプションを付けてnetstatを実行すると、そのコネクションを所有しているプロセスのID(PID)も表示される。
image.png
netstatの「-o」オプションでコネクションを所有しているプロセスを調べる
「-o」オプションを付けると、そのコネクションを所有しているプロセスのID番号が表示される。

「-o」ではなく「-b」オプションを付けると、実際のプロセス名が表示される。これを実行するには、コマンドプロンプトを管理者権限で起動する必要がある。
image.png

TCPListener.ps1を実行すると、LISTEN状態になる。

PowerShellでTCPコネクションを張ってみた

TCPListener.ps1
# ポート番号を変数で指定
$port = 5000

# .NETの TcpListener クラスを使い、指定ポートを待ち受け
$listener = New-Object System.Net.Sockets.TcpListener([IPAddress]::Any, $port)
$listener.Start()
Write-Host "Listening on port $port ... (press Ctrl+C to stop)"

try {
    while ($true) {
        # クライアントからの接続があるまで Accept で待機
        $client = $listener.AcceptTcpClient()

        # ここから先は好きなようにデータを読み書きできます
        # 簡易的には、何もしないで即切断でもOK
        Write-Host "Connection accepted from" $client.Client.RemoteEndPoint

        # 必要に応じて処理...
        # 例: $stream = $client.GetStream(); ...; $stream.Close()

        # セッションを張り続けたいのでコメントアウト
        # $client.Close()
    }
}
finally {
    $listener.Stop()
}

接続させたいPCのIPアドレスに変更し、TCPClient.ps1を実行する。FireWall設定でポートは開けておくこと。

TCPClient.ps1
# 接続先サーバーIPまたはホスト名
$serverIp = "127.0.0.1"
# 接続先ポート (サーバー側の Listener が待ち受けているポート)
$port = 5000

Write-Host "Attempting to connect to $serverIp:$port..."

# .NET の TcpClient クラスを使用してサーバーに接続
$client = New-Object System.Net.Sockets.TcpClient
$client.Connect($serverIp, $port)

Write-Host "Connected to $serverIp:$port. (press Ctrl+C to stop)"

# Stream を取得 (サーバーとの送受信用)
$stream = $client.GetStream()

try {
    while ($true) {
        # ここに、任意の処理(読み書き等)を入れることができる
        #
        # 例: サーバーからデータ受信
        # if ($stream.DataAvailable) {
        #     $buffer = New-Object Byte[] 1024
        #     $readBytes = $stream.Read($buffer, 0, $buffer.Length)
        #     if ($readBytes -gt 0) {
        #         $receivedText = [System.Text.Encoding]::UTF8.GetString($buffer, 0, $readBytes)
        #         Write-Host "Received: $receivedText"
        #     }
        # }
        #
        # 例: サーバーに定期的にメッセージを送る
        # $message = "Hello from client."
        # $bytes = [System.Text.Encoding]::UTF8.GetBytes($message)
        # $stream.Write($bytes, 0, $bytes.Length)
        #
        # 何もしないで Idle 状態を維持したい場合は Sleep だけでOK

        Start-Sleep -Seconds 1
    }
}
finally {
    Write-Host "Closing connection..."
    $stream.Close()
    $client.Close()
}

Test-NetConnectionコマンドは内部で何をしている?

指定ポートが空いているかを確認するためのコマンド。長期でTCPコネクションを張り続けてくれるものではない。
3WayHandShakeしてコネクションを切る(約0.03秒で)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?