最終更新: llysfactoryll 2020年09月22日(火) 15:55:12履歴
(ESP32のWiFi機能で別のファイルシステムの状態を監視する-4)
監視される側の、別のファイルシステムは、今回はパソコンのアプリケーションとして疑似的に実装した。
今後パソコン上のどこかのフォルダーを、実際に監視できるようにすると面白いと思う。
パソコン側はC#で、一応Formアプリケーションで組んだが、現段階ではGUIをほとんど使用していない。
BeginRead、EndReadを使って非同期的にやりたかったがうまくいかなかった。
この作りならコンソールアプリでもよかった。
幸いこのようなやり方でもウィンドウを閉じるだけできれいに終了してくれるので、.NET Frameworkの素晴らしいところである。
Form1
namespace FileWatchClient { public partial class Form1 : Form { //サーバーのIPアドレス(または、ホスト名)とポート番号 private string m_host = "192.168.3.9"; private int m_port = 49999; private TcpClient m_client = new TcpClient(); private NetworkStream m_stream; private const int COMMAND_BUFFER_SIZE = 128; private byte[] m_command_buffer = new byte[COMMAND_BUFFER_SIZE]; private FileWatchCommand m_fw_command; public Form1() { InitializeComponent(); } private void Connect() { try { m_client.Connect(m_host, m_port); m_stream = m_client.GetStream(); m_fw_command = new FileWatchCommand(m_stream); for (;;) { int numberOfBytesRead; numberOfBytesRead = m_stream.Read(m_command_buffer, 0, m_command_buffer.Length); m_fw_command.OnReceiveBlock(m_command_buffer, numberOfBytesRead); } } catch (Exception ex) { MessageBox.Show(ex.Message); } } private void Form1_Load(object sender, EventArgs e) { try { Task.Run(() => Connect()); } catch (Exception ex) { MessageBox.Show(ex.Message); } } } }
FileWatchCommand
namespace FileWatchClient { class FileWatchCommand { private NetworkStream m_stream; private List<byte> m_command = new List<byte>(); private enum STATE { IDLE, IN_COMMAND } private STATE m_state = STATE.IDLE; private int m_file_size = 0; public FileWatchCommand(NetworkStream stream) { m_stream = stream; } public void OnCommand() { string[] token = Encoding.ASCII.GetString(m_command.ToArray()).Split(','); switch(token[0]) { case "#fw:list": byte[] response = Encoding.ASCII.GetBytes( string.Format("file_1.txt 100, file_2.txt {0}\r", m_file_size)); m_file_size += 111; m_stream.Write(response, 0, response.Length); break; } } public void OnReceiveByte(byte c) { if (c == '#') { m_command.Clear(); m_state = STATE.IN_COMMAND; } switch (m_state) { case STATE.IN_COMMAND: if (c == '\r') { OnCommand(); m_state = STATE.IDLE; break; } m_command.Add(c); break; } } public void OnReceiveBlock(byte[] block, int length) { for (int i = 0; i < length; ++i) { OnReceiveByte(block[i]); } } } }
コメントをかく