こんにちは、ENGかぴです。
Wiresharkはイーサーネットのパケットを解析するフリーソフトです。Wiresharkを使ってパケットを解析する方法の一例としてArduinoのEthernetライブラリのTCP/UDP通信のパケットを確認します。
動作確認にはVB.NETで作成したアプリとArduino UNOの拡張ボードであるETHERNET SHIELD(Arduino Ethernet Shield 2)を使用しています。
Wiresharkを使ってArduinoのEthernetライブラリのパケットを確認します。Wiresharkのダウンロードとインストールについては下記記事にまとめています。
TCPパケットの確認
TCP通信を行うためにVB.NETで作成したアプリを使用します。TCPクライアントの実装方法を2つ紹介していますが、どちらのアプリでもTCPクライアントとしての動作は同様です。
VB.NET(VB2022)でTCPクライアント(非同期)を実装
VB.NET(VB2022)でTCPクライアント(タスク処理)を実装
Arduinoのソースコードは下記記事のものを使用します。
Arduinoの電源を入れてアプリでTCPクライアントを接続します。接続後、「送信」ボタンをクリックするとArduinoは温湿度データを含む文字列のパケットで応答します。WiresharkはアプリとArduino間のパケットの様子をキャプチャーした結果を表示します。
複数のパケットで文字列を送る場合
Wiresharkでパソコン(192.168.11.100)とArduino(192.168.11.2)のパケットを確認します。
ProtocolからTCP通信のパケットであることが分かります。また、Arduinoから受信したパケットのInfoのLen=(パケットのデータ数)を確認すると2,10,15などのように複数のパケットが生成されていることが分かります。
No.28のパケットを確認するとバイナリデータの一部に「Humidity:」が表示されているため文字列のパケットであることが分かります。
複数のパケットによって通信網が渋滞する原因にもつながるため、なぜ複数のパケットでArduinoが応答しているかをArduinoのEthernetライブラリでLAN通信するのソースコートから考察します。
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close");
client.println("Refresh: 5");
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
//温湿度のデータ
client.print("Humidity: ");
client.print(temp_humi[0]);
client.print(" %\t");
client.print("Temperature: ");
client.print(temp_humi[1]);
client.println(" *C");
client.println("<br />");
client.println("</html>");
文字列毎にclientオフジェクトのprintln()メソッドで指定しています。println()メソッド毎にパケットが生成されます。またprintln()メソッドによる改行コードが挿入されるため改行コードだけのパケット(Len=2)が生成されています。
TCP通信はパケット1つにつき最大1460バイト使用できるため、小サイズの文字列を複数のパケットに分けて送信するのは効率が悪いと言えます。
広告
PR:わからないを放置せず、あなたにあったスキルを身に着けるコツを教える テックジム 「書けるが先で、理解が後」を体験しよう!
1つのパケットで文字列を送る場合
小サイズの文字列を複数のパケットで送信するのは効率が悪いため、文字列を1つにまとめて1つのパケットで送信するようにします。
String str ="";
str += "HTTP/1.1 200 OK \r\n";
str += "Content-Type: text/html \r\n";
str +="Connection: close \r\n";
str +="Refresh: 5 \r\n";
str += "<!DOCTYPE HTML> \r\n";
str +="<html> \r\n";
//温湿度のデータ
str += "Humidity: ";
str += temp_humi[0];
str += " %\t";
str += "Temperature: ";
str += temp_humi[1];
str += " *C \r\n";
str += "<br> \r\n";
str +="</html> \r\n";
client.print(str);
String型の変数を宣言し、文字列を(+=)で追加します。文字列の末端の”\r\n”は改行コードです。println()メソッドを使用すると改行コードでパケットが分割されてしまいます。println()メソッドによる改行コードのパケットが生成されないようにするため文字列に改行コードを含めています。
1つにまとめた文字列(str)をclientオブジェクトのprint()メソッドに指定することで1つのパケットで応答することができます。
Arduinoの応答のパケットを確認します。No.8を確認するとInfoのLen=168から文字列が168バイトであることが分かります。またパケットを確認すると文字列のバイナリデータが確認できます。
Arduinoの応答パケットが分割されずに1つのパケットで送信できているため、通信網にとってはパケットの総数が減っており効率が良くなっていると言えます。
容量オーバーを気にせずにパケットを送信したい場合は「複数のパケットで文字列を送る場合」の方法の方が良い場合もあります。
UDPパケットの確認
UDP通信は通信相手のIPとポートが一致していれば接続の確立をしなくても双方向通信ができます。UDP通信のユニキャストとブロードキャストのパケットを確認します。Arduinoのソースコードは下記記事のものを使用します。
ArduinoのEthernetライブラリでUDPクライアントを実装する
Arduinoの電源を入れると温湿度データを測定し、UDP通信で指定のアドレスに文字列を送信します。ArduinoのUDP通信を行うソースコードは以下の通りです。
Udp.print("Temperature: ");
Udp.print(temp_humi[1]);
Udp.print(" *C");
Udp.endPacket();//パケット準備完了(送信)
ArduinoのEthernetライブラリでUDP通信する場合は、Udpオブジェクトのprint()メソッドで一時的に文字列を保存してendPacket()メソッドを使用すると文字列を送信する仕組みです。そのためパケットが複数に分割されることはありません。
ユニキャストの場合
Wiresharkでパソコン(192.168.11.100)とArduino(192.168.11.2 Arduinoの7ピンをGND)のパケットを確認します。
ProtcolがUDPになっていることからUDP通信のパケットであることが分かります。またInfoのLen=39から39バイトのデータであることが分かります。バイナリデータを確認するとArduinoが送信した温湿度データであることが分かります。
ブロードキャストの場合
次にブロードキャストを確認するため、Arduinoの送信先アドレスを「255.255.255.255」になるように(Arduinoの6ピンと7ピンをオーブン)します。
キャプチャーしたパケットのプロトコルの詳細を示す左下の欄のEthernet ⅡのDestinationを確認するとBroadcast(ff:ff:ff:ff:ff:ff)になっており、ブロードキャストとして認識できていることが分かります。
パケットを確認するとInfoのLen=39から39バイトのデータであることが分かります。バイナリデータを確認するとユニキャストと同様の温湿度データであることが分かります。
PR:RUNTEQ(ランテック )- マイベスト3年連続1位を獲得した実績を持つWebエンジニア養成プログラミングスクール
まとめ
Wiresharkの使用例としてArduinoのEthernetライブラリのTCP/UDP通信のパケットを確認しました。
TCP通信では文字列の生成方法によってパケットが複数に分かれてしまうことが分かりました。Arduinoのclientオブジェクトのprintln()メソッド(print()メソッド)を使用するたびにパケットが生成されることがパケット解析によって分かりました。
通信網にとってパケットが複数に分割されると効率が悪いため、print()メソッドに指定する文字列を1つの文字列にまとめることでパケットが分割されないようにする検討を行いました。
UDP通信のユニキャストとブロードキャストについてパケットを確認するとInfoがLen=39になっておりArduinoの文字列が確認できました。またブロードキャストの詳細を左下の欄のDestinationを確認するとブロードキャストと認識していることが分かりました。
関連リンク
Wiresharkのダウンロードとインストールについて下記記事にまとめています。
Arduinoのライブラリを使って動作確認を行ったことを下記リンクにまとめています。
Arduinoで学べるマイコンのソフト開発と標準ライブラリの使い方
Seeeduino XIAOで学べるソフト開発と標準ライブラリの使い方
ESP32-WROOM-32Eで学べるソフト開発と標準ライブラリの使い方
PR:エンジニア転職なら100%自社内開発求人に強い【クラウドリンク】
VB.NET(VB2022)のデスクトップアプリで動作確認したことを下記リンクにまとめています。
VB.NET(VB2022)のデスクトップアプリ開発でできること
マイクロソフトはVisual Studio以外にもVSCodeという便利なエディターを提供しています。下記リンクではVSCodeのインストールの仕方からC言語開発環境の作り方までをまとめています。
最後まで、読んでいただきありがとうございました。
Wiresharkを使用するとTCP/UDP通信のパケットを解析することができるため、イーサーネットを使用したシステムのデバッグが効率よく行えるため大きなメリットになります。