7章:TCPサーバプログラム自作の検討(3)

    作成2015.10.12
     準備運動が完了したので、いよいよ第1次の自作プログラムの作成です。

  1. 第1次の自作プログラム作成概要
    (1)開発環境
    *Windows7
    *Visual Studio Express 2012 for Windows Desktop
    *Visual C# Windows フォームアプリケーション
    を使用します。


  2. Form1.csのデザイン
     Form1.csのデザインを以下のように作成しました。



    上記Form1.csのデザインにおいて
    (1)timer1
    *Enabled=True
    *Interval=100(ms)
    (2)button1=接続
    (3)button2=切断
    (4)button3=\r\n送信
    (5)textBox1=13000(ポートNo)
    (6)textBox2=(送信データ)
    (7)textBox3=(受信データ)
    *Multiline=True
    *ScrollBars=Both
    を設定します。

    注(1)ツールボックスで選択したハーツは全てメインスレッド上で動作します。
    注(2)timer1は繰り返し動作の開始タイミング用として使用しますが、timer1_Tickは割込み処理ではなく、メインスレッド上で動作します。
    注(3)同一スレッド間では、難解なデリゲート機能を使用しないで、各パーツの機能が自由に使えるため、プログラムコードが簡潔になります。


  3. イベント関数の発生
     イベント関数の発生はForm1.csのデザインから自動発生する必要があります。直接書くとForm1.Desingners.csの内容と不一致となります。
    (1)private void Form1_Load(object sender, EventArgs e)
    (2)private void timer1_Tick(object sender, EventArgs e)
    (3)private void button1_Click(object sender, EventArgs e)
    (4)private void button2_Click(object sender, EventArgs e)
    (4)private void button3_Click(object sender, EventArgs e)


  4. Form1.csのソースプログラム
     Form1.csのソースプログラムは以下となります。
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using System.Net;
    using System.Net.Sockets;
    
    namespace MyTcpListener
    {
        public partial class Form1 : Form
        {
            TcpListener server = null;
            int gNo = 0;
            bool fOK = true;
            Int32 port;
            IPAddress localAddr;
            Byte[] bytes = new Byte[256];
            String data = null;
            TcpClient client;
            NetworkStream stream;
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                button1.Enabled = true;
                button2.Enabled = false;
                button3.Enabled = false;
            }
    
            private void timer1_Tick(object sender, EventArgs e)
            {
                if (fOK) { TimeP(); }
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                port = Convert.ToInt32(textBox1.Text); 
                IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
                localAddr = ipHostInfo.AddressList[0];
                server = new TcpListener(localAddr, port);
                
                gNo = 1;
                button1.Enabled = false;
                button2.Enabled = true;
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
                gNo = 0;
                server.Stop();
                client.Close();
                client = null;
                button1.Enabled = true;
                button2.Enabled = false;
                button3.Enabled = false;
            }
    
            private void button3_Click(object sender, EventArgs e)
            {
                byte[] msg = System.Text.Encoding.ASCII.GetBytes(textBox2.Text + "\r\n");
                stream.Write(msg, 0, msg.Length);
                gNo = 3;  
            }
    
            void TimeP()
            {
                fOK = false;
                switch (gNo)
                {
                    case 1:
                        textBox3.AppendText("接続待ち\r\n");
                        textBox3.AppendText("接続待ちで強制終了する場合は、タスクマネージャーを使用してください!!\r\n");
                        server.Start();
                        client = server.AcceptTcpClient();
                        textBox3.AppendText("接続完了\r\n");
                        stream = client.GetStream();
                        gNo = 3;
                        button3.Enabled = true;
                        break;
                    case 3:
                        if (stream.DataAvailable)
                        {
                            int i = stream.Read(bytes, 0, bytes.Length);
                            if (i != 0)
                            {
                                data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
                                textBox3.AppendText(data);
                            }
                        }
                        break;
                    default:
                        break;
                }
                fOK = true;
            }
        }
    }
    


  5. 完成プログラムのダウンロード
     完成プログラムは以下からダウンロードできます。
    [7-1.zip]をダウンロードする。

    解凍するとMyTcpListenerフォルダーがあります。フォルダー内に
    (1)MyTcpListener.sln等のソースファイル群
    (2)MyTcpListener.exe:実行ファイル
    があります。



  6. 動作テスト環境
    (1)TCPサーバプログラム作成用
    Visual Studio Express 2012 for Windows Desktop

    (2)COMポート用プログラム
    まずは下記のCsharp Simple CDC Demo.exe:実行ファイルを使用します。
    [2-1.zip]をダウンロードする。

    解凍するとフォルダー内にMicrosoft Visual C#2012フォルダーがあります。フォルダー内に
    (1)*Basic Communicationフォルダー:ソースファイル群
    (2)Csharp Simple CDC Demo.exe:実行ファイル
    があります。

    (3)シリアル_USB変換プログラム
     シリアル-USB変換モジュールソースプログラム(送信側)

    と同一となります。

    [../f41/26-1.zip]をダウンロードする。

    解凍するとMy-CDC-Basic.Xフォルダーがあります。

    ボーレートの変更:UART_Init(9600);→UART_Init(115200);に変更します。


    (4)ブレークアウトボードのピン設定
     (1)ENピン:(Chip Enable.)→Highに設定します。
     (2)GPIO-15ピン:(Type I/O MTDO;HSPI_CS; UART0_RTS)→Lowに設定します。
     (3)GPIO-2ピン:(Type I/O UART Tx during flash programming)→Highに設定します。
     (4)GPIO-0ピン:(Type I/O SPI_CS2)→Highに設定します。
     (5)TXピン:(Type I/O GPIO-1)→通信相手のRXに接続
     (6)RXピン:(Type I/O GPIO-3)→通信相手のTXに接続
     (7)3V3ピン:→3.3V電源供給
     (8)GNDピン:→アース


  7. 評価回路外観
     評価回路外観を以下に示します。





  8. MyTcpListener.exeのテスト
     操作手順
    (1)AE-USBPIC44基板のUSBを接続します。
    (2)Csharp Simple CDC Demo.exeを起動します。
    (3)COMポートを選択して、「Connect」ボタンを押します。
    (4)ESP-WROOM-02に電源を供給しします。
    (5)ボーレート76800bpsで以下データを受信します。
    ets Jan 8 2013,rst cause:1, boot mode:(3,0)

    load 0x40100000, len 1396, room 16
    tail 4
    chksum 0x89
    load 0x3ffe8000, len 776, room 4
    tail 4
    chksum 0xe8
    load 0x3ffe8308, len 540, room 4
    tail 8
    chksum 0xc0
    csum 0xc0

    2nd boot version : 1.4(b1)
    SPI Speed : 40MHz
    SPI Mode : QIO
    SPI Flash Size & Map: 8Mbit(522KB+512KB)
    jump torrun user1 @ 1000
    (6)ボーレート115200bpsで以下データを受信します。
    ready
    WIFI CONNECTED
    WIFI GOTIIP


    (7)MyTcpListener.exeをダブルクリックで起動します。
    (8)接続ボタンを押します。(MyTcpListener.exeは接続完了までロック状態となります。)

    (9)Csharp Simple CDC Demo.exeの送信文字列に「AT+CWMODE=1」を入力して、「\r\n有り送信」ボタンを押します。
    (10)送信文字列に「AT+CIPSTART="TCP","192.168.11.2",13000」を入力して、「\r\n有り送信」ボタンを押します。
    (11)TCPプログラムは接続を完了して、接続完了を表示されます。(ロック状態解除となります。)
    (12)送信文字列に「AT+CIPMODE=1」を入力して、「\r\n有り送信」ボタンを押します。
    (13)送信文字列に「AT+CIPSEND」を入力して、「\r\n有り送信」ボタンを押します。
    (14)以上でトランスペアレントモードの初期設定が完了してATコマンドは使用できなくなります。
    (15)送信文字列に「AT+CIPSEND」を入力して、「\r\n有り送信」ボタンを2回押します。
    (16)MyTcpListener.exeの送信テキストボックスに「ABCDEFGHIJKLMNOPQRSTUVWXYZ」を入力して「\r\n送信」ボタンを2回押します。
    (17)以下のような画面となります。





  9. TCPサーバプログラム自作の検討(3)まとめ
    (1)TCPサーバプログラム自作は初めてで、うまく製作できるか?不安でしたが思いのほかうまくできました。
    (2)うまく製作できた理由は、TCPサーバサンプルプログラムが多数みつかったためです。
    (3)最初にサンプルプログラムを十分検討して、第1次の自作プログラムの方式を選択したのが良かったとおもいます。
    (4)採用した方式は、TcpListener クラスを使用し、メインスレッドのみでマルチスレッドを使用しない方式としました。
    (5)本格、実用プログラムは非同期なサーバーのソケットの例を適用し、マルチスレッド方式となるかもしれません。
    (6)しかし、個人用としては、TcpListener クラスを使用し、メインスレッド方式で十分と思います。
    (7)TcpListener クラスを使用したメインスレッド方式はコードの記述が簡潔でわかりやすく、動作も安定しています。
    (8)本TPCサーバプログラムの最大の欠点は接続待ち時のロック状態ですが、実用的にはあまり問題となりません。
    (9)サンプルプログラムはいずれも受信時に返信して、任意のタイミングでのTPCサーバからの送信をサポートしていませんでしたが、任意のタイミングでのTPCサーバからの送信を可能としました。
    (10)実用的には、任意のタイミングでのTPCサーバからの送信が重要です。




8章:TCPサーバ使用でAE-USBPIC44基板 からトランスペアレントモード起動に行く。

トップページに戻る。