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

    作成2015.10.10
     TCPサーバプログラムを自作した経験がなかったため、まずはサンプルプログラムを検討してみました。

  1. TCPサーバサンプルプログラム
     以下のサンプルプログラムをテストしてみました。
    (1)同期サーバーのソケットの例
    https://msdn.microsoft.com/ja-jp/library/6y0e13d3(v=vs.110).aspx

    (2)非同期なサーバーのソケットの例
    https://msdn.microsoft.com/ja-jp/library/fx6588te(v=vs.110).aspx

    (3)TcpListener クラス
    https://msdn.microsoft.com/ja-jp/library/system.net.sockets.tcplistener(v=vs.110).aspx

    (4)C# で ソケット通信の基礎的サーバー作成(TcpListener + TcpClient)
    http://note.chiebukuro.yahoo.co.jp/detail/n1657


  2. 動作テスト環境
    (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ピン:→アース


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





  4. 同期サーバーのソケットの例のテスト
    https://msdn.microsoft.com/ja-jp/library/6y0e13d3(v=vs.110).aspx

    (1)Visual Studio Express 2012 for Windows Desktopを管理者として実行します。
    (2)メニューの「ファイル」_「新しいプロジェクト」を選択します。
    (3)「テンプレート」_「Visual C#」_「コンソールアプリケーション」を選択します。
    (4)デフォルトの名前「ConsoleApplication1」のまま「OK」ボタンを押します。
    (5)Program.cs の内容を消去し、サンプルプログラムをペーストします。
    (6)if (data.IndexOf("") > -1)をif (data.IndexOf("\n") > -1)に変更します。
    (7)メニューの「デバッグ」_「デバッグ開始」を選択します。
    (8)コンソールに以下が表示されます。
    Waiting for a connection…
    (9)メニューの「デバッグ」_「全て中断」を選択します。
    (10)Socket handler = listener.Accept();で停止していることが確認できます。
    (11)AE-USBPIC44基板のUSBを接続します。
    (12)Csharp Simple CDC Demo.exeを起動します。
    (13)COMポートを選択して、「Connect」ボタンを押します。
    (14)ESP-WROOM-02に電源を供給しします。
    (15)ボーレート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
    (16)ボーレート115200bpsで以下データを受信します。
    ready
    WIFI CONNECTED
    WIFI GOTIIP
    (17)送信文字列に「AT+CWMODE=1」を入力して、「\r\n有り送信」ボタンを押します。
    (18)送信文字列に「AT+CIPSTART="TCP","192.168.11.2",11000」を入力して、「\r\n有り送信」ボタンを押します。
    (19)TCPプログラムは接続を完了して、int bytesRec = handler.Receive(bytes);まで進行します。
    (20)送信文字列に「AT+CIPMODE=1」を入力して、「\r\n有り送信」ボタンを押します。
    (21)送信文字列に「AT+CIPSEND」を入力して、「\r\n有り送信」ボタンを押します。
    (22)以上でトランスペアレントモードの初期設定が完了してATコマンドは使用できなくなります。
    (23)送信文字列に「AT+CIPSEND」を入力して、「\r\n有り送信」ボタンを2回押します。
    (24)以下のような画面となります。





  5. 同期サーバーのソケットの例の分析
    (1)Socket handler = listener.Accept();を実行すると、Socketの接続待ちとなる。接続待ちの間は、実行が完了しないため、サーバー アプリケーションの実行が中止されロック状態となる。
    (2)int bytesRec = handler.Receive(bytes);を実行すると、Socketのデータ受信待ちとなる。データ受信待ちの間は、実行が完了しないため、サーバー アプリケーションの実行が中止されロック状態となる。
    (3)本サンプルでは、データ受信のタイミングでデータ返信を行っている。
    (4)本サンプルでは、データ受信のタイミングでデータ返信を行った後、接続を切断している。
    (5)接続の切断を行わない場合は、任意のタイミングでサーバ側からクライアント側に送信が可能である。
    (6)以下のコードに変更するとデータ受信待ちのロック状態を防止できる。
     if (handler.Available > 0)					
     {					
          int bytesRec = handler.Receive(bytes);				
          data += Encoding.ASCII.GetString(bytes, 0, bytesRec);			
          if (data.IndexOf("\n") > -1)				
          {				
                break;			
          }				
     }					
    System.Threading.Thread.Sleep(10);
    

    長所:
    (1)コード記述が簡潔でわかりやすい。
    (2)データ受信後の接続の切断をやめることにより、任意のタイミングでサーバ側からクライアント側に送信が可能である。
    短所:
    (1)Socketの接続待ちの状態で接続が完了するまでの間、サーバー アプリケーションがロック状態となる。
    (2)データ受信待ちも同様にロック状態となるが、Socket.Available プロパティ を使用することによりロック状態を防止できる。
    (3)ロック状態から終了する場合は、Windowsタスクマネージャーを使用して強制終了が必要となる。


  6. 非同期なサーバーのソケットの例のテスト
    https://msdn.microsoft.com/ja-jp/library/fx6588te(v=vs.110).aspx

    操作手順は同期サーバーのソケットの例のテストと同様となります。
     全く同じ操作を行うと以下の結果となります。





  7. 非同期なサーバーのソケットの例の分析
    (1)listener.BeginAccept( new AsyncCallback(AcceptCallback),listener);を実行すると接続待ちとなる。
    (2)public static void AcceptCallback(IAsyncResult ar)が呼び出させるまでは、allDone.WaitOne();で待機状態となる。
    (3)allDone.WaitOne();は時間設定できる。
    (4)接続すると handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);が実行され、データ受信待ちとなる。
    (5)public static void ReadCallback(IAsyncResult ar)が呼び出させるまでは、allDone.WaitOne();で待機状態となる。
    (6)public static void ReadCallback(IAsyncResult ar)の引数arにSocketの実体情報が含まれており、Socketの実体から受信データを読み出せる。
    (7)受信後Socketの実体を引数として、Send(handler, content);を実行する。
    (8)Send(handler, content);では、handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);を実行する。
    (9)private static void SendCallback(IAsyncResult ar)が実行されるとint bytesSent = handler.EndSend(ar);で送信が実行される。
    (10)送信が実行された後、接続が切断される。
    (11)接続の切断を行わない場合は、任意のタイミングでサーバ側からクライアント側に送信が可能である。

    長所:
    (1)Socketの接続待ちの状態で接続が完了するまでの間、サーバー アプリケーションがロック状態とならない。
    (2)データ受信待ちも同様にロック状態とならない。
    (3)データ受信後の接続の切断をやめることにより、任意のタイミングでサーバ側からクライアント側に送信が可能である。
    短所:
    (1)コードの記述が複雑で難解である。
    (2)接続。受信、送信はメインスレッドとは異なる独立したスレッドで実行される。このため、ツールボックスの関数を使用する際は難解なデリケート機能を使用しなければならない。
    (3)このため、ソースプログラムは複雑な構成となる。


  8. TCPサーバプログラム自作の検討(1)まとめ
    (1)TCPサーバサンプルプログラムは多数みつかったのですが、その中から4種を抜粋して検討してみました。
    (2)同期サーバーのソケットの例はコードの記述は簡潔でわかりやすい特徴があります。
    (3)反面、接続待ちの状態で接続されないとサーバー アプリケーションがロック状態となる問題があるます。
    (4)しかし、データ受信待ちのロック状態は防止可能です。
    (5)非同期なサーバーのソケットの例は接続待ちもデータ受信待ちもロック状態となりません。
    (6)反面、プログラムコードは複雑で難解です。
    (7)同期サーバーのソケットも非同期なサーバーのソケットもデータ受信後の接続の切断をやめることにより、任意のタイミングでサーバ側からクライアント側に送信が可能である。
    (8)簡易的には、同期サーバーのソケットの例で問題ないような気がします。ただし、接続待ちの状態でのアプリケーションロックの問題は残ります。
    (9)本格、実用プログラムは非同期なサーバーのソケットの例の適用が必要となるかもしれません。
    (10)残り2個のサンプルプログラムを評価した上で、第1次の自作プログラムを作成したいと思います。




6章:TCPサーバプログラム自作の検討(2)に行く。

トップページに戻る。