お世話になります。
行いたいこと
サーバー: ESP32
クライアント: C#プログラム
上記のような構成でTCP通信したいと考えています。
それぞれは同一のルーターに接続さてています。
問題点
クライアントであるC#プログラムのTcpClientのインスタンスを生成するところで下記のようなエラーが出力されることがあります。
エラーが出力されない場合は、問題なく通信できています。
出力されるタイミングはまちまちです。電源投入後10分ほどでエラーが出力されることもあれば、1時間以上大丈夫なこともあります。
▼エラー文
System.Net.Sockets.SocketException: '接続済みの呼び出し先が一定の時間を過ぎても正しく応答しなかったため、接続できませんでした。
または接続済みのホストが応答しなかったため、確立された接続は失敗しました。'
質問
プログラムを記載します。原因・解決策などご存知の方は教示いただければ幸です。
ESP32の電源に関しては、PCのUSB、乾電池(直列3V)、直流安定化電源(3.3V)を試しました。
プログラム
Arduino
1// サーバー 2#include <WiFi.h> 3 4const char* ssid = "*****"; 5const char* password = "*****"; 6IPAddress ip(192, 168, 11, 100); 7IPAddress gateway(192, 168, 2, 1); 8IPAddress subnet(255, 255, 255, 0); 9 10WiFiServer server(80); 11 12void setup(void) { 13 Serial.begin(9600); 14 15 WiFi.mode(WIFI_STA); 16 WiFi.config(ip, gateway, subnet); 17 WiFi.begin(ssid, password); 18 Serial.println(""); 19 20 // Wait for connection 21 while (WiFi.status() != WL_CONNECTED) { 22 delay(500); 23 Serial.print("."); 24 } 25 Serial.println(""); 26 Serial.print("Connected to "); 27 Serial.println(ssid); 28 Serial.print("IP address: "); 29 Serial.println(WiFi.localIP()); 30 31 server.begin(); 32 Serial.println("HTTP server started"); 33} 34 35void loop(void) { 36 String cmd; 37 cmd = rcvCommand(); 38 39 if (cmd != "") { 40 Serial.print("cmd: "); 41 Serial.println(cmd); 42 } 43 44 delay(100); 45} 46 47String rcvCommand() { 48 WiFiClient client = server.available(); 49 50 String rstr; 51 if (client.connected()) { 52 Serial.println("Connected to client"); 53 54 //コマンド文字列受信(文字列が来なければタイムアウトする) 55 rstr = client.readStringUntil('\r'); 56 Serial.print("["); 57 Serial.print(rstr); 58 Serial.println("]"); 59 60 //応答送信 61 client.print("OK\r"); 62 63 //接続をクローズ 64 client.stop(); 65 Serial.println("Closed"); 66 } 67 68 return rstr; 69}
C#
1// クライアント 2 string sendMsg = "hoge"; 3 string ipOrHost = "192.168.11.100"; 4 //string ipOrHost = "localhost"; 5 int port = 80; 6 7 //TcpClientを作成し、サーバーと接続する 8 // 【ここでエラーが出力されることがあります】 9 System.Net.Sockets.TcpClient tcp = 10 new System.Net.Sockets.TcpClient(ipOrHost, port); 11 Console.WriteLine("サーバー({0}:{1})と接続しました({2}:{3})。", 12 ((System.Net.IPEndPoint)tcp.Client.RemoteEndPoint).Address, 13 ((System.Net.IPEndPoint)tcp.Client.RemoteEndPoint).Port, 14 ((System.Net.IPEndPoint)tcp.Client.LocalEndPoint).Address, 15 ((System.Net.IPEndPoint)tcp.Client.LocalEndPoint).Port); 16 17 //NetworkStreamを取得する 18 System.Net.Sockets.NetworkStream ns = tcp.GetStream(); 19 20 //読み取り、書き込みのタイムアウトを10秒にする 21 //デフォルトはInfiniteで、タイムアウトしない 22 //(.NET Framework 2.0以上が必要) 23 ns.ReadTimeout = 10000; 24 ns.WriteTimeout = 10000; 25 26 //サーバーにデータを送信する 27 //文字列をByte型配列に変換 28 System.Text.Encoding enc = System.Text.Encoding.UTF8; 29 byte[] sendBytes = enc.GetBytes(sendMsg); 30 //データを送信する 31 ns.Write(sendBytes, 0, sendBytes.Length); 32 Console.WriteLine(sendMsg); 33 34 System.IO.MemoryStream ms = new System.IO.MemoryStream(); 35 byte[] resBytes = new byte[256]; 36 int resSize = 0; 37 do 38 { 39 //データの一部を受信する 40 resSize = ns.Read(resBytes, 0, resBytes.Length); 41 //Readが0を返した時はサーバーが切断したと判断 42 if (resSize == 0) 43 { 44 Console.WriteLine("サーバーが切断しました。"); 45 break; 46 } 47 //受信したデータを蓄積する 48 ms.Write(resBytes, 0, resSize); 49 //まだ読み取れるデータがあるか、データの最後が\nでない時は、 50 // 受信を続ける 51 } while (ns.DataAvailable || resBytes[resSize - 1] != '\n'); 52 //受信したデータを文字列に変換 53 string resMsg = enc.GetString(ms.GetBuffer(), 0, (int)ms.Length); 54 ms.Close(); 55 //末尾の\nを削除 56 resMsg = resMsg.TrimEnd('\n'); 57 Console.WriteLine(resMsg); 58 }

下記のような回答は推奨されていません。
このような回答には修正を依頼しましょう。
また依頼した内容が修正された場合は、修正依頼を取り消すようにしましょう。
2019/06/12 07:12