C#でEthernet接続して受信電文をコンソールに表示するデバッグツールを作る方法

C#

C#でサーバーなどとEthernet通信をしたいとき、最初から高機能な通信ソフトを作る必要はありません。
まずは、指定したIPアドレスとポート番号に接続して、受信した電文をそのままコンソールに表示するだけの簡単なデバッグツールを作るのがおすすめです。

こうしたツールが1つあるだけで、通信相手が本当にデータを送っているのか、どのような文字列が返ってきているのか、改行コードが付いているのかなど、基本的な確認がとても楽になります。

また、C#で通信プログラムを作っていると、
「今ここまで処理が来ているのか」
「受信したデータは何か」
「例外が出る直前の値は何か」
を確認したくなる場面がたくさんあります。

そこで役立つのが、Visual Studioでのデバッグ時にWriteLine系の出力を使って確認する方法です。
たとえば、Console.WriteLine()Debug.WriteLine() を使えば、プログラムの流れや変数の中身を確認しやすくなります。

この記事では、初心者向けに次の2つを丁寧に解説します。

  • C#で任意のEthernet接続を行い、受信した電文をコンソールへ表示するデバッグツールの作り方
  • Visual Studioでデバッグ中にWriteLineを使って状態を確認する方法

どちらも開発現場では非常によく使う内容です。
特に、通信プログラムは「見えないデータ」を扱うため、接続確認ログ確認がとても重要になります。
最初の一歩として、まずはシンプルな受信確認ツールを作ってみましょう。

スポンサーリンク
スポンサーリンク

開発環境

今回は以下の環境を想定します。

  • Visual Studio
  • C#
  • .NET のコンソールアプリ

Windows Formsでも作れますが、最初はコンソールアプリの方が分かりやすいです。
コンソールなら Console.WriteLine() でそのまま確認できるため、通信の学習にも向いています。

コンソールアプリの作成方法

「新しいプロジェクトの作成」→「コンソールアプリ」→任意の名前で保存

C#でEthernet接続して受信電文を表示するサンプル

では、実際にコードを見ていきます。
今回は、相手のIPアドレスとポート番号を指定して接続し、受信したデータをコンソールへ出力するサンプルです。

using System;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace TcpReceiveDebugTool
{
    internal class Program
    {
        static async Task Main(string[] args)
        {
            string ipAddress = "127.0.0.1";
            int port = 5000;

            Console.WriteLine("TCP受信デバッグツールを開始します。");
            Console.WriteLine($"接続先: {ipAddress}:{port}");

            try
            {
                using (TcpClient client = new TcpClient())
                {
                    Console.WriteLine("接続中...");
                    await client.ConnectAsync(ipAddress, port);
                    Console.WriteLine("接続成功");

                    using (NetworkStream stream = client.GetStream())
                    {
                        byte[] buffer = new byte[1024];

                        Console.WriteLine("受信待機中...");

                        while (true)
                        {
                            int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);

                            if (bytesRead == 0)
                            {
                                Console.WriteLine("相手が切断しました。");
                                break;
                            }

                            string receivedText = Encoding.ASCII.GetString(buffer, 0, bytesRead);

                            Console.WriteLine("----- 受信データ -----");
                            Console.WriteLine(receivedText);
                            Console.WriteLine("----------------------");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("エラーが発生しました: " + ex.Message);
            }

            Console.WriteLine("終了するには何かキーを押してください。");
            Console.ReadKey();
        }
    }
}

結果

このコードの解説

このコードでは、TCP通信に必要な最低限の処理だけを実装しています。
順番に見ていきます。

TcpClient

TcpClient は、TCP通信を行うためのクライアントクラスです。
サーバーへ接続する側として使います。

using (TcpClient client = new TcpClient())

この1行で通信のためのクライアントを作成しています。

ConnectAsync

指定したIPアドレスとポート番号へ接続します。

await client.ConnectAsync(ipAddress, port);

ここで接続に失敗する場合、よくある原因は次の通りです。

  • IPアドレスが間違っている
  • ポート番号が違う
  • 相手側のサーバーが起動していない
  • ファイアウォールに遮断されている

GetStream

接続後は NetworkStream を取得し、このストリームを通してデータを受信します。

using (NetworkStream stream = client.GetStream())

ReadAsync

実際の受信処理です。

int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);

ここで相手から届いたデータを buffer に読み込みます。
戻り値の bytesRead は、実際に受信したバイト数です。

もし bytesRead == 0 なら、相手が切断したと判断できます。

Encoding.ASCII.GetString

受信したデータを文字列として表示するために、バイト列から文字列へ変換しています。

string receivedText = Encoding.ASCII.GetString(buffer, 0, bytesRead);

通信相手がASCII文字列を送ってくる場合はこれで十分です。
ただし、相手がUTF-8やShift_JISを使っている場合は、文字コードを合わせる必要があります。

文字列ではなく「電文」を見たいときの考え方

受信した内容がきれいな文字列なら問題ありませんが、装置通信では以下のようなケースもあります。

  • 制御コードが含まれる
  • 改行コードが含まれる
  • バイナリデータが含まれる
  • 16進で見た方が分かりやすい

そういう場合には、文字列表示だけでなく、16進表示もあると便利です。
初心者向けの記事として今回は文字列表示を中心にしていますが、将来的には次のような関数も追加すると便利です。

static string BytesToHex(byte[] data, int length)
{
return BitConverter.ToString(data, 0, length).Replace("-", " ");
}

そして受信時に、

Console.WriteLine("HEX: " + BytesToHex(buffer, bytesRead));

と出力すれば、通信内容を16進形式でも確認できます。

Visual Studioでデバッグ中にWriteLineを使う方法

次に、Visual Studioでデバッグするときに役立つ WriteLine系の使い方 を解説します。

C#でよく使う出力方法には主に2つあります。

  • Console.WriteLine()
  • Debug.WriteLine()

この2つは似ていますが、用途が少し違います。

Console.WriteLineとは

Console.WriteLine() は、コンソール画面に文字を表示するための命令です。

Console.WriteLine("接続開始");
Console.WriteLine("受信データ: " + receivedText);

コンソールアプリならこれだけで簡単に確認できます。
今回の受信デバッグツールでも、最も基本となる確認方法です。

特に初心者のうちは、処理の途中に Console.WriteLine() を入れて、

  • 今どこまで実行されたか
  • 変数に何が入っているか
  • 例外の前に何が起きているか

を確認すると、原因調査がしやすくなります。

たとえば次のように書きます。

Console.WriteLine("ReadAsyncの直前です");
int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
Console.WriteLine("ReadAsyncの直後です");
Console.WriteLine("受信バイト数: " + bytesRead);

これだけでも、どこで止まっているかが見えやすくなります。

Debug.WriteLineとは

Debug.WriteLine() は、Visual Studioの出力ウィンドウへメッセージを出すための命令です。
コンソールがないアプリでも使いやすいのが特徴です。

使用するには、次の using を追加します。

using System.Diagnostics;

そして、次のように書きます。

Debug.WriteLine("接続開始");
Debug.WriteLine("受信バイト数: " + bytesRead);
Debug.WriteLine("受信内容: " + receivedText);

この出力は、Visual Studioでデバッグ実行中に
表示 → 出力
から確認できます。

特にWindows FormsやWPFのようにコンソールが出ないアプリでは、Debug.WriteLine() がとても便利です。

Console.WriteLineとDebug.WriteLineの違い

初心者の方は、まず次のように覚えると分かりやすいです。

Console.WriteLine

  • コンソール画面に表示する
  • コンソールアプリで使いやすい
  • 実行中に見た目で分かりやすい

Debug.WriteLine

  • Visual Studioの出力ウィンドウに表示する
  • GUIアプリでも使いやすい
  • デバッグ時の内部確認に向いている

通信プログラムでは、両方を使い分けられるようになるととても便利です。

「出力ウィンドウ」での出力した例です。

初心者がつまずきやすいポイント

ここで、通信ツールとWriteLineの利用でつまずきやすい点を整理します。

文字化けする

相手装置の文字コードがASCIIではない可能性があります。
UTF-8やShift_JISの可能性もあるため、仕様書を確認しましょう。

受信できない

接続できても、相手がまだ何も送信していない場合があります。
この場合、ReadAsync() は待機状態になります。

1回の受信で1電文とは限らない

TCP通信では、1回の送信が必ず1回の受信になるとは限りません。
将来的には、終端コードや固定長で電文を区切る工夫が必要です。

Debug.WriteLineが見えない

Visual Studioの出力ウィンドウを開いていないと見えません。
「表示」→「出力」から確認します。

まとめ

今回は、次の2つを解説しました。

  1. C#で任意のEthernet接続を行い、受信した電文をコンソールへ表示するデバッグツールの作成方法
  2. Visual Studioでデバッグ中にWriteLineを使って状態を確認する方法

最初はシンプルなツールで確認。
接続して、受信して、表示する。
この基本ができるだけでも、対象機器との通信理解がかなり深まります。

さらに、Console.WriteLine()Debug.WriteLine() を使いこなせるようになると、通信プログラムの動作確認や不具合調査が一気にやりやすくなります。

タイトルとURLをコピーしました