C++ Builder CE code fragment

TIdIcmpClientを使ってlatencyを計る件 ついでに関数化もするかな

の続きです。上の記事を書いている時に、なにげに

“c++ builder tidicmpclient latency”

という検索キーワードをBing君に投げたら、すかさず数秒の沈黙後にCopilot君が何か言ってきました。

Certainly! If you’re looking to measure latency using the TIdICMPClient component in C++ Builder, you can follow these steps to create a simple application that pings a server and calculates the round-trip time.

Here’s a concise example:

#include <vcl.h>
#include <IdICMPClient.hpp>
#include <IdGlobal.hpp>
#pragma hdrstop

#pragma package(smart_init)
#pragma resource "*.dfm"

TForm1 *Form1;

__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}

void __fastcall TForm1::ButtonPingClick(TObject *Sender)
{
    TIdICMPClient *ICMPClient = new TIdICMPClient(this);
    try
    {
        ICMPClient->Host = "8.8.8.8"; // Replace with the desired IP address or hostname
        ICMPClient->ReceiveTimeout = 5000; // Timeout in milliseconds

        ICMPClient->Ping();
        if (ICMPClient->ReplyStatus->ReplyStatusType == rsEcho)
        {
            ShowMessage("Ping successful! Latency: " + IntToStr(ICMPClient->ReplyStatus->MsRoundTripTime) + " ms");
        }
        else
        {
            ShowMessage("Ping failed!");
        }
    }
    __finally
    {
        delete ICMPClient;
    }
}

Explanation:

  1. Include necessary headers: Ensure you include the headers for VCL and Indy components.
  2. Create and configure TIdICMPClient: Instantiate the TIdICMPClient component, set the Host property to the target IP address or hostname, and configure the ReceiveTimeout.
  3. Ping and measure latency: Use the Ping method to send an ICMP echo request. Check the ReplyStatus to determine if the ping was successful and retrieve the round-trip time.
  4. Display results: Show a message with the latency or an error message if the ping fails.

This example demonstrates a basic approach to measuring network latency using TIdICMPClient in C++ Builder. Feel free to adapt and expand it based on your specific requirements.

これでほぼ動いてしまうので、なんだかなあ。なんですが、ICMPClient->ReplyStatus->MsRoundTripTimeでいつものpingプログラムの出力の

ラウンドトリップの概算時間がms単位で得られるというのを教えてくれました。時々Copilot君が役に立つことがあるようです。で、動かして見ましょうかね?

ちなみにCopilot君の提示したソースではちいさなエラーがでて動かないので、直して動かしました。動くソースは、以下です。NameをButtonPingとしTButtonをフォームに置いてください。ダブルクリックしてから、中身を入れ替えてください。

#include <vcl.h>

#include <IdICMPClient.hpp>
#include <IdGlobal.hpp>

#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ButtonPingClick(TObject *Sender)
{
	TIdIcmpClient *ICMPClient = new TIdIcmpClient(this);
    try
    {
        ICMPClient->Host = "8.8.8.8"; // Replace with the desired IP address or hostname
        ICMPClient->ReceiveTimeout = 5000; // Timeout in milliseconds

        ICMPClient->Ping();
        if (ICMPClient->ReplyStatus->ReplyStatusType == rsEcho)
        {
			ShowMessage("Ping successful! Latency: " + IntToStr((int)ICMPClient->ReplyStatus->MsRoundTripTime) + " ms");
        }
        else
        {
            ShowMessage("Ping failed!");
        }
    }
    __finally
    {
        delete ICMPClient;
	}
}

そもそもTIdICMPClientじゃなくてTIdIcmpClientだし。(笑)C++は関数名、変数名には厳しいですよ。ついでに関数化しておきましょうかね。まずヘッダーのping.hは、

#ifndef PingH
#define PingH
//---------------------------------------------------------------------------

#include <IdICMPClient.hpp>
#include <IdGlobal.hpp>

String ping(String host);

#endif

ping.cppは、

#include "ping.h"

String ping(String host)
{
	TIdIcmpClient* icmp = new TIdIcmpClient();

	icmp->Host = host;
	icmp->ReceiveTimeout = 600;
	icmp->Ping();

	if( icmp->ReplyStatus->ReplyStatusType == rsTimeOut )
		return "time out";
	else
		return icmp->ReplyStatus->MsRoundTripTime;

    delete icmp;

}

これをドライブするテストプログラムは、フォームにTEditTButtonTLabelを各一個置いて、

#include <vcl.h>
#pragma hdrstop

#include "ping.h"

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    Label1->Caption = ping(Edit1->Text);
}

これだけです。もちろんping.hping.cppをプロジェクトに加えてください。何度か出てきたIPアドレス“8.8.8.8”という数字的には特徴のあるアドレスは一体何なのかを知りたい方は、1回nslookupしてみると吉かもしれません。

コメント