") > -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)以下のような画面となります。
同期サーバーのソケットの例の分析
(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タスクマネージャーを使用して強制終了が必要となる。
非同期なサーバーのソケットの例のテスト
https://msdn.microsoft.com/ja-jp/library/fx6588te(v=vs.110).aspx
操作手順は同期サーバーのソケットの例のテストと同様となります。
全く同じ操作を行うと以下の結果となります。
非同期なサーバーのソケットの例の分析
(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)このため、ソースプログラムは複雑な構成となる。
TCPサーバプログラム自作の検討(1)まとめ
(1)TCPサーバサンプルプログラムは多数みつかったのですが、その中から4種を抜粋して検討してみました。
(2)同期サーバーのソケットの例はコードの記述は簡潔でわかりやすい特徴があります。
(3)反面、接続待ちの状態で接続されないとサーバー アプリケーションがロック状態となる問題があるます。
(4)しかし、データ受信待ちのロック状態は防止可能です。
(5)非同期なサーバーのソケットの例は接続待ちもデータ受信待ちもロック状態となりません。
(6)反面、プログラムコードは複雑で難解です。
(7)同期サーバーのソケットも非同期なサーバーのソケットもデータ受信後の接続の切断をやめることにより、任意のタイミングでサーバ側からクライアント側に送信が可能である。
(8)簡易的には、同期サーバーのソケットの例で問題ないような気がします。ただし、接続待ちの状態でのアプリケーションロックの問題は残ります。
(9)本格、実用プログラムは非同期なサーバーのソケットの例の適用が必要となるかもしれません。
(10)残り2個のサンプルプログラムを評価した上で、第1次の自作プログラムを作成したいと思います。