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.
我现在正在做学校项目,我正在寻找连接 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.