ネットワーク

Classes

ClassDescription
Public classIPInfo
IP 情報
Public classTcpClientEventArgs
TCP受信イベント引数クラス
Public classTcpClientThread
TCP/IP送受信スレッド
Public classTcpServerEventArgs
TCPサーバーイベント引数クラス
Public classTcpServerThread
TCP/IP サーバースレッド
Public classUdpClientEventArgs
UDP受信イベント引数クラス
Public classUdpClientThread
UDP送受信スレッド

Delegates

DelegateDescription
Public delegateTcpClientEventHandler
TCP受信イベントハンドラのデリゲート
Public delegateTcpServerEventHandler
TCPサーバーイベントハンドラのデリゲート
Public delegateUdpClientEventHandler
UDP受信イベントハンドラのデリゲート

Remarks

このネームスペースには、TCP/IP 通信や UDP 通信を行うフレームワークを集約しています。 主に、画像処理アプリケーションに TCP/IP 通信や UDP 通信を実装するコストの低減を目的としています。

目次:


スレッド

下記のクラスが TCP/IP 通信、UDP 通信を行うスレッドです。

FVIL.Parser ネームスペースに集約されるフレームワークを使用する場合は、 下記 例1 のように ParserInfo から取得できます。 自身で直接生成する場合は、下記 例2 のように IPInfo を使用します。
具体的な使用例については 画像処理アプリケーションフレームワーク のサンプルコードを参考にしてください。


例1) ParserInfo から取得する方法
C# Copy imageCopy
FVIL.Net.TcpServerThread thread = ((FVIL.Parser.IAuxTcpServer)ParserInfo).Threads[0];

例2) IPInfo から生成する方法
C# Copy imageCopy
FVIL.Net.IPInfo info = new FVIL.Net.IPInfo("127.0.0.1", 50000, "host");
FVIL.Net.TcpServerThread thread = new FVIL.Net.TcpServerThread(info);
thread.Start();

[↑戻る]


選択ダイアログ

IPInfo クラスの CreateSelectDialog(array<Object>[]()[][]) メソッドを実行すると 下図ダイアログのインスタンスを生成できます。 生成されたインスタンスの ShowDialog メソッドで表示して使用してください。

C# Copy imageCopy
FVIL.Net.IPInfo info = new FVIL.Net.IPInfo();
Form form = info.CreateSelectDialog();
if (form.ShowDialog(this) == DialogResult.OK)
{
    FVIL.Net.TcpServerThread thread = new FVIL.Net.TcpServerThread(info);
}

[↑戻る]


プロパティフォーム

下記のクラスの CreatePropertyDialog を実行すると下図ダイアログのインスタンスを生成できます。

生成されたインスタンスの Show または ShowDialog メソッドで表示して使用してください。

C# Copy imageCopy
FVIL.Net.IPInfo info = new FVIL.Net.IPInfo("127.0.0.1", 50000, "host");
FVIL.Net.TcpServerThread thread = new FVIL.Net.TcpServerThread(info);
thread.Start();
Form form = thread.CreatePropertyDialog();
form.ShowDialog(this);
thread.Dispose();

TCP/IP サーバー:


TCP/IP クライアント:


UDP クライアント:

[↑戻る]


通信手順

TCP/IP クライアントからサーバーへ送信する例を示します。
この例では
SendAsBinary(Object) を使用して送信しています。 このメソッドを使用するには送信対象のクラスが Serializable 属性を持たなければなりません。

C# Copy imageCopy
/// <summary>
/// TCP/IP 通信テスト
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void menuOpen_Click(object sender, EventArgs e)
{
    FVIL.Net.IPInfo info = new FVIL.Net.IPInfo("127.0.0.1", 50000, "friend");
    TcpServer = new FVIL.Net.TcpServerThread(info);
    TcpServer.Notify += new FVIL.Net.TcpClientEventHandler(TcpServer_Notify);
    TcpServer.Start();

    TcpClient = new FVIL.Net.TcpClientThread(info);
    TcpClient.Start();
}

/// <summary>
/// TCP/IP サーバー
/// </summary>
FVIL.Net.TcpServerThread TcpServer = null;

/// <summary>
/// TCP/IP クライアント
/// </summary>
FVIL.Net.TcpClientThread TcpClient = null;

/// <summary>
/// TCP/IP 通信:解放
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void menuClose_Click(object sender, EventArgs e)
{
    TcpClient.Dispose();
    TcpServer.Dispose();
}

/// <summary>
/// TCP/IP 通信:送信
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void menuSend_Click(object sender, EventArgs e)
{
    FVIL.Data.CFviPoint data = new FVIL.Data.CFviPoint(111.1, 222.2);
    TcpClient.SendAsBinary(data);
}

/// <summary>
/// TCP/IP 通信:受信イベントハンドラ
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void TcpServer_Notify(object sender, FVIL.Net.TcpClientEventArgs e)
{
    Console.WriteLine("TimeStamp = {0}", e.TimeStamp);
    Console.WriteLine("Exception = {0}", e.Exception);

    if (e.Data != null)
    {
        FVIL.Net.TcpClientThread client = (FVIL.Net.TcpClientThread)sender;
        object data = client.ReadAsBinary(e.Data);

        Console.WriteLine("data = {0}", data.GetType().FullName);

        if (data is FVIL.Data.CFviPoint)
        {
            FVIL.Data.CFviPoint point = (FVIL.Data.CFviPoint)data;
            Console.WriteLine("point.X = {0}", point.X);
            Console.WriteLine("point.Y = {0}", point.Y);
        }
    }
}

出力結果:
	TimeStamp = 2012/05/31 19:40:59
	Exception = 
	data = FVIL.Data.CFviPoint
	point.X = 111.1
	point.Y = 222.2
	

[↑戻る]


設計上の注意

SendAsBinary を使用するとパケットの設計が容易になる利点がありますが欠点もあります。

利点:
  • 従来の通信手順(固定長の構造体での送受信)より簡潔に記述できること。
  • 可変長データの送受信のハンドシェイクが不要になること。
欠点:
  • 大量のデータの伝送に向いていないこと。
  • 短周期の伝送に向いていないこと。

データが大きい場合は、1つのパケットが断片化されて送信されてくる為、 TcpClientThreadUdpClientThread では、受信時のディレイを設けています。 受信スレッドは、最初のデータが到達しても残りのデータの到達を一定期間待機します。 この時、後続の別パケットが到達すると受信したデータは複数のパケットが混在したものになりデータの復元に失敗します。

上記のような特性が問題となる場合は、Send メソッドを使用して送受信のハンドシェイクを行ってください。 その場合は、受信イベントハンドラ内に独自のデータ収集処理を実装してください。 その際、ReceiveDelayTime を 0 に設定してください。 そうすると DataAvailable が false になると Receive が完了する為、直ちに受信イベントを発行します。


関連:

[↑戻る]