C#和ESP8266之间的WiFi通信

时间:2018-11-15 16:07:19

标签: c# .net client-server windows-forms-designer esp8266

我现在正在研究学校项目,我正在寻找最简单的方法来通过ESP8266上的WiFi模块而不是通过SerialPort(COM4)连接C#与ESP8266(我必须使用此方法)。我必须构建一个简单的项目,以便将测量数据从ESP发送到C#,还需要接收我自己定义的控制命令(诸如“ LEDON”,“ LEDOFF”等字符串)从C#到ESP,就像测量项目的远程控制一样。我对C#的了解不高,与服务器/互联网的基本知识一样。我已经用Arduino IDE代码完成了所有工作,但由于使用C#,所以我一直受不了,因为我从来没有在那里编程过。希望您能理解我的英语不好和问题的概念。 :)

编辑:

好吧,所以我在学校项目中做了一些更改,现在我处于这个阶段,需要解决这部分代码。我希望这是完成我的项目的最后一步。我要做的就是解决在以下代码中使用名为“ Writing”的未填充方法将数据从C#写入ESP的问题:

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){}
            }
        }
    }
}

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

2 个答案:

答案 0 :(得分:0)

您可能会看到此project,基本上,您想在arduino和C#之间通过TCP / IP进行通信。将C#视为服务器,将arduino视为客户端。然后他们只需要互相发送消息进行交流即可。

我提供的链接的作用远远超出了需要,因此,如果您迷路了,也许可以从一些非常基本的内容开始,然后看一下here并检查有关c#服务器的链接。与我的第一个链接相比,它们将更易于理解。

[EDIT]好吧,只有链接答案是危险的,而不是最好的,所以这是我通过第一个链接给出的内容的一个非常简短的版本:

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

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,Web上有很多教程,但如果可能的话,我仍然认为WPF / MVVM比winforms更易于学习。

答案 1 :(得分:0)

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

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