クライアントサーバのsocket通信をWireshark3を使いパケットをキャプチャーして内容を確認してみた
クライアントサーバで、クライアントとサーバでどのような通信をしているか確認します。
前回作成した
「Python クライアントサーバソケット機能 TCPプロトコル編」
クライアントサーバの通信を行い、Wiresharkを用いて通信内容を確認します。
同時にWiresharkの使い方も簡単に説明しますね。
パケットの確認方法
「クライアント」と「サーバ」環境を作成し実行して、Wireshark3を使い通信情報(パケット)を取得してデータの流れを確認します。
テスト環境
一台のパソコンに以前に作成した(下記参照)Pythonで構築したサーバとクライアントのプログラムをanaconda-jupyterで実行して、Wireshark3で確認しました。
【参照ページ】
クライアントサーバの動作における変更点
Wireshark3でパケットの流れをわかりやすくするために
のサーバのIPアドレスを
127.0.0.1 から 127.0.0.2 に変更します。
これで
サーバのIPアドレスは「127.0.0.2」
クライアントのIPアドレスは「127.0.0.1」
になります。
Wiresharkのメインウィンドウの構成について
メインウィンドウは3段で構成されています。
上から
・パケット一覧
・パケット詳細
・パケットバイト列
クライアントサーバの実行およびパケット取得
1.wiresharkを起動します。
2.自分のパソコン内の通信をキャプチャするので
「adapter for loopback traffic capture」をクリックします。
3.wiresharkの表示フィルターに以下の情報を入力して「Enter」キーを押下。
「ip.addr==127.0.0.2」
※これで今回のパケットしか表示されないようになります。
4.次にanaconda-jupyterを立ち上げ、Pythobのサーバプログラムとクライアントプログラムを表示そます。
・Pythonサーバプログラム
・Pythonクライアントプログラム
5.サーバープログラムを起動します。
6.クライアントプログラムを起動します。
7.クライアントサーバの処理が終了後に、wiresharkのメニュー上部の「赤い四角」のボタンを押下してキャプチャーを終了します。(「赤い四角」が「灰色の四角」ボタンに変わります。)
8.これで、パケットの取得が完了して解析する準備ができました。
IPアドレスとポート番号の確認
IPアドレスとポート番号が無いと通信はできません。
wiresharkの情報より、今回のテストでは
【サーバ】
IPアドレス 127.0.0.2
ポート番号 49152
【クライアント】
IPアドレス 127.0.0.1
ポート番号 52413
となります。
※サーバのポート番号は以下の通り、Pythonのプログラムで設定済みです。
# ダイナミックポート番号(49152~65535)
D_PORT_NO = 49152
クライアントのポート番号はシステムで任意に割り当てられています。
今回 52413 です。
パケットの確認
今回のクライアントとサーバのパケットのやり取りは合計で9回です。
(No951からNO959までです。)
下記の図を見て下さい。
赤枠で囲まれている上下に2つのブロックがあります。
コネクションの確立(通信の開始)
上の図の上部の3パケットのブロックは「コネクションの確立」で通信の開始を意味します。
通信の最初にコネクションの確立を行います。
コネクションの確立は「3ウェイ・ハンドシェイク」と言います。
(C)はクライアント、(S)はサーバを意味しています。
「3ウェイ・ハンドシェイク」の流れはコントロールフラグの状態を変化させて意味を持たせます。
※コントロールフラグとは、TCPヘッダーの項目です。
[SYN]:コネクション確立要求
[ACK]:確認応答
No951 (C)→[SYN] →(S)
※サーバさんコネクションの確立をして良いですか?
No952 (C)←[SYN][ACK]←(S)
※サーバはコネクションの確立OKです。クライアントさんコネクションの確立をして良いですか?
No953 (C)→[ACK] →(S)
※クライアントはコネクションの確立OKです。
これで、サーバとクライアントの合意が取れたので通信の開始ができます。
データ転送のやり取り
こちらがメインの処理になります。(2パケット)
[PSH]:速やかに受信データをアプリケーション層に渡してください。
[ACK]:確認応答
No954 (C)←[PSH][ACK]←(S)
※クライアントさんに速やかに受信データをアプリケーション層に渡してください。
データ:Server accessed.(1)
No955 (C)→[ACK] →(S)
※サーバさん、データを受け取りました。
コネクションの解放(通信の終了)
上の図の下部の4パケットのブロックは「コネクションの解放」で通信の終了を意味します。
[FIN]:コネクション解放要求
[ACK]:確認応答
No956 (C)→[FIN][ACK]→(S)
※サーバさんデータ通信が完了したのでコネクションの解放をお願いして良いですか?
No957 (C)←[ACK] ←(S)
※サーバはコネクションの解放OKです。
No958 (C)←[FIN][ACK]←(S) データ通信完了の確認。
※クライアントさんへ、サーバからもコネクションの解放しても良いですか?
No959 (C)→[ACK] →(S)
※クライアントはコネクションの解放OKです。
これでサーバとクライアントの通信は完了になります。
パケットバイト列について
パケットバイト列は実際のパケットの詳細が16進数で確認できます。
通常の機器同士の通信であれば
・EthernetⅡフレーム
・Internet Protocol Version 4
・Transmission Control Protocol
の流れでデータが表示されるのですが、
今回のクライアントサーバの処理は機器同士をケーブルでつなぐ方法ではなく、1台のパソコンで終結しているため「インサーネットフレーム」ではありません。
その代わりに、「Null/Loopback」がIPレイヤーの前に4バイトついています。
02 00 00 00
この内容はデータが「IPv4」であることを示しています。
※Pythonのサーバのプログラムで
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
の「socket.AF_INET」がIPv4 専用のインターネットファミリを指定しています。
よって、今回のデータは
・Null/Loopback
・Internet Protocol Version 4
・Transmission Control Protocol
のデータの構成になります。
IP:Internet Protocol Version 4(IPv4ヘッダー)
TCP:Transmission Protocol
クライアントサーバのsocket通信でWireshark3を使いパケットをキャプチャーして内容を確認してみたのまとめ
私の確認のために行いました。
分かりにくかったら・・・すいません。
Wiresharkを使えばパケットの意味まで理解できます。
通信している電気信号が可視化できるのですから。
素晴らしいツールです。
一度、自分で解析してみてください。理解が深まると思います。