C#与ESP8266之间的WiFi通信

WiFi communication between C# and ESP8266

我现在正在做学校项目,我正在寻找连接 C# 和 ESP8266 的最简单方法,不是通过串行端口 (COM4),而是通过 ESP8266 上的 WiFi 模块(我必须使用这种方法)。我必须构建简单的项目,将测量数据从 ESP 发送到 C#,并从 C# 接收我自己定义的控制命令(字符串,如 "LEDON" "LEDOFF" 等)到 ESP,就像测量项目的远程控制一样。我对 C# 的了解很少,与 servers/internet 的基础知识一样。我在 Arduino IDE 代码中完成了所有工作,但我仍然坚持使用 C#,因为我以前从未在那里编程过。我希望你能理解我糟糕的英语和我的问题的概念。 :)

编辑:

嗯,所以我在我的学校项目中做了一些更改,现在我在这个阶段,我需要解决这部分代码。我希望这是完成我的项目的最后一步。我所要做的就是解决 Writing data from C# to ESP using unfilled method named "Writing" in following code:

using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace ESP8266
{
    public class Projekt
    {
        public event MessageEventHandler Message;
        public delegate void MessageEventHandler(Projekt sender, string Data);

        public TcpListener server;
        public Thread W_Thread;
        public Thread R_Thread;
        public bool IsLiserning = true;

        public TcpClient client;
        public StreamReader clientdata;
        public StreamWriter serverdata;
        public Projekt()
        {
            server = new TcpListener(IPAddress.Parse(Dns.GetHostEntry(Dns.GetHostName().ToString()).AddressList[1].ToString()), 5000);
            server.Start();

            W_Thread = new Thread(new ThreadStart(Writing));
            W_Thread.Start();

            R_Thread = new Thread(new ThreadStart(Reading));
            R_Thread.Start();
        }

        public void Reading()
        {
            while (IsLiserning == true)
            {
                if (server.Pending() == true)
                {
                    client = server.AcceptTcpClient();
                    clientdata = new StreamReader(client.GetStream());
                }
                try
                {
                    Message?.Invoke(this, clientdata.ReadLine());
                }
                catch (Exception){}
            }
        }

        public void Writing()
        {
            while (IsLiserning == true)
            {
                if (server.Pending() == true)
                {
                    client = server.AcceptTcpClient();
                    serverdata = new StreamWriter(client.GetStream());
                }
                try
                {
                    //NEED_TO_SOLVE_THIS_PART
                }
                catch (Exception){}
            }
        }
    }
}

也许除了那部分代码还缺少一些东西,我希望你们能帮助我 :) 顺便感谢所有的回答 :)

你可以看看这个 project,基本上你想通过 TCP/IP 在 arduino 和 C# 之间进行通信。将 C# 视为服务器,将 arduino 视为客户端。然后他们只需要向对方发送消息即可进行通信。

我提供的 link 比需要的要多得多,所以如果您迷路了,也许可以从一些非常基础的东西开始,然后查看 here 并检查 links 最后谈论 c# 服务器。与我的第一个 link.

相比,它们会更容易理解

[编辑] 好吧,只有 link 的答案是危险的而且不是最好的,所以这是我在第一个 link 中给出的一个非常简单的版本:

您的服务器将有一个接收者列表,每个接收者只处理一个客户端。这是我的一个项目的一个很大的简化,我希望通过删除很多东西我没有破坏任何东西:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Windows.Data;

namespace DemoServer.Models
{
    public class Server
    {
        public TcpListener Listener { get; set; }
        public int Port { get; set; }
        public bool IsStarted { get; private set; }
        public List<Receiver> Receivers = new List<Receiver>();

        public Server(int port)
        {
            Receivers.Clear();
            BindingOperations.EnableCollectionSynchronization(Receivers, Receivers);
            Port = port;
            IsStarted = false;
        }

        public void Start()
        {
            if (!IsStarted)
            {
                try
                {
                    Listener = new TcpListener(System.Net.IPAddress.Any, 0);
                    Listener.Start();
                    IsStarted = true;
                    IPAddress address = ((IPEndPoint)Listener.LocalEndpoint).Address;
                    int port = ((IPEndPoint) Listener.LocalEndpoint).Port;
                    Console.WriteLine("Server Started");
                    //Start Async pattern for accepting new connections
                    WaitForConnection();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    IsStarted = false;
                }
            }
        }

        public void Stop()
        {
            if (IsStarted)
            {
                Listener.Stop();
                IsStarted = false;
                Receivers.Clear();
                Console.WriteLine("Server Stopped");
            }
        }

        private void WaitForConnection()
        {
            Listener.BeginAcceptTcpClient(new AsyncCallback(ConnectionHandler), null);
        }

        private void ConnectionHandler(IAsyncResult ar)
        {
            if (IsStarted)
            {
                Receiver newClient = new Receiver(Listener.EndAcceptTcpClient(ar), this);
                newClient.Start();
                Receivers.Add(newClient);
                WaitForConnection();
            }
        }

        public void SomeInteractionBetweenClients()
        {
            Console.WriteLine("Interaction!");
        }
    }
}

然后是 Receiver 代码,您真正处理与客户端的通信:

using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Sockets;
using System.Threading;

namespace DemoServer.Models
{
    public class Receiver : ModelBase
    {
        bool ConnectionStatus = false;

        private uint m_Id = 0;
        public uint Id
        {
            get { return m_Id; }
            set => SetAndRaisePropertyChanged(ref m_Id, value);
        }

        private Thread receivingThread;
        private Thread sendingThread;
        public Server Server { get; set; }
        public TcpClient Client { get; set; }
        public List<String> MessageQueue { get; private set; }


        public Receiver(TcpClient client, Server server)
        {
            MessageQueue = new List<String>();
            Server = server;
            Client = client;
            Client.ReceiveBufferSize = 1024;
            Client.SendBufferSize = 1024;
            ConnectionStatus = true;
        }

        public void Start()
        {
            receivingThread = new Thread(ReceivingMethod);
            receivingThread.IsBackground = true;
            receivingThread.Start();

            sendingThread = new Thread(SendingMethod);
            sendingThread.IsBackground = true;
            sendingThread.Start();
        }

        private void Disconnect()
        {
            if (!ConnectionStatus) return;
            ConnectionStatus = false;
            Client.Client.Disconnect(false);
            Client.Close();
        }


        private void SendingMethod()
        {
            while (ConnectionStatus)
            {
                if (MessageQueue.Count > 0)
                {
                    var message = MessageQueue[0];
                    try
                    {
                        NetworkStream clientStream = Client.GetStream();
                        StreamWriter streamWriter = new StreamWriter(clientStream);
                        streamWriter.Write(message);
                        streamWriter.Flush();
                        Console.WriteLine($"We are sending '{message}' to the client");
                    }
                    catch
                    {
                        Disconnect();
                    }
                    finally
                    {
                        MessageQueue.RemoveAt(0);
                    }
                }
                Thread.Sleep(30);
            }
        }

        private void ReceivingMethod()
        {
            while (ConnectionStatus)
            {
                if (Client.Available > 0)
                {
                    try
                    {
                        NetworkStream clientStream = Client.GetStream();
                        StreamReader streamReader = new StreamReader(clientStream);
                        char[] puchBuffer = new char[Client.Available];
                        int iQtt = streamReader.Read(puchBuffer, 0, Client.Available);
                        string msg = String.Empty;
                        for (int i = 0; i < puchBuffer.Length; i++)
                        {
                            msg = $"{msg}{Convert.ToString(puchBuffer[i])}";
                        }
                        OnMessageReceived(msg);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                    }
                }
                Thread.Sleep(30);
            }
        }

        private void OnMessageReceived(String msg)
        {
            // Here you can parse the messages coming ffrom the client and do whatever is needed
            // If needed, you can even call some public methods from the server to forward some info to an other client for example or just the server:
            // eg: Server.SomeInteractionBetweenClients();
        }
    }
}

我希望这对交流部分有所帮助。对于 GUI,网上有很多教程,但如果可能的话,我仍然认为 WPF/MVVM 比 winforms 更好学。

据我了解,您的项目需要 2 种沟通方式。将 C# 作为服务器并不理想,因为没有简单的方法将命令从 C# 发送到 esp8266。我假设您的项目正在使用 esp8266 作为 arduino 平台(没有将 esp8266 作为 wifi 模块附加到 arduino),请查看 MQTT,它是发布和订阅消息的代理。这样 esp8266 和 C# 代码都可以通过 MQTT 进行通信,从而达到双向通信的目的。

对于 esp8266,您可以在此处查看 esp8266 的 arduino MQTT 库:https://github.com/knolleary/pubsubclient.