项目需求
很多时候,我们想要通过上位机给我们的单片机下发命令,是我们能够控制单片机进行一些操作。而通常我们有几种方式,分别是串口传输、蓝牙传输、UDP和TCP这类WIFI传输等。 在本文就用C#编写上位机使用UDP给单片机发送Json格式数据,进行数据的传输。
编程环境
Visual Studio 2019
使用的技术
UDP
Internet 协议集支持一个无连接的传输协议,该协议称为用户数据报协议(UDP,User Datagram Protocol)。UDP 为应用程序提供了一种无需建立连接就可以发送封装的 IP 数据包的方法。 Internet 的传输层有两个主要协议,互为补充。无连接的是 UDP,它除了给应用程序发送数据包功能并允许它们在所需的层次上架构自己的协议之外,几乎没有做什么特别的事情。面向连接的是 TCP,该协议几乎做了所有的事情。 UDP协议与TCP协议一样用于处理数据包,在OSI模型中,两者都位于传输层,处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。UDP用来支持那些需要在计算机之间传输数据的网络应用。包括网络视频会议系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议。UDP协议从问世至今已经被使用了很多年,虽然其最初的光彩已经被一些类似协议所掩盖,但即使在今天UDP仍然不失为一项非常实用和可行的网络传输层协议。
方法 | 说明 |
---|---|
Close | 关闭 UDP 连接 |
Connect | 建立与远程主机的连接 |
DropMulticastGroup | 退出多路广播组 |
JoinMulticastGroup | 将 UdpClient 添加到多路广播组 |
Receive | 返回已由远程主机发送的 UDP 数据文报 |
Send | 将 UDP 数据文报发送到远程主机 |
创建监听举例:
代码语言:javascript复制UdpClient udpserver;
private void udpListen()
{
udpserver = new UdpClient(8888);//参数为要进行UDP监听的端口
}
接收数据举例:
代码语言:javascript复制private void getMsg()//开启一个异步线程去执行该方法
{
//定义一个IPEndPoint对象用来装载数据来源的IP和端口信息
IPEndPoint remoteIpAndPort = new IPEndPoint(IPAddress.Any, 0);
while (true)
{
//等待消息,注意,使用该方法在等待消息时会阻塞线程
byte[] msgBytes = udpserver.Receive(ref remoteIpAndPort)
string receivedStr = System.Text.Encoding.UTF8.GetString(msgBytes);
}
}
发送数据举例:
代码语言:javascript复制 private void buttonSend_Click(object sender, EventArgs e)
{
//将要发送的数据转化成byte数组
byte[] b = System.Text.Encoding.UTF8.GetBytes("Hello");
//创建目标IP端口信息
IPEndPoint sendTo = new IPEndPoint(IPAddress.Parse("192.168.1.233"),1234);
//发送数据
this.udpserver.Send(b, b.Length, sendTo);
}
JSON
JSON介绍
JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
JSON 语法规则
JSON是一个标记符的序列。这套标记符包含六个构造字符、字符串、数字和三个字面名。 JSON是一个序列化的对象或数组。
- 六个构造字符: begin-array = ws %x5B ws ; [ 左方括号 begin-object = ws %x7B ws ; { 左大括号 end-array = ws %x5D ws ; ] 右方括号 end-object = ws %x7D ws ; } 右大括号 name-separator = ws %x3A ws ; : 冒号 value-separator = ws %x2C ws ; , 逗号
- 在这六个构造字符的前或后允许存在无意义的空白符(ws): ws = *(%x20 /; 空间 %x09 /; 水平标签 %x0A /; 换行或换行 %x0D); 回程
- JSON的值 JSON的构成: ws 值 ws [1] 值可以是对象、数组、数字、字符串或者三个字面值(false、null、true)中的一个。值中的字面值中的英文必须使用小写。 对象由花括号括起来的逗号分割的成员构成,成员是字符串键和上文所述的值由逗号分割的键值对组成,如: 1
{“name”: “John Doe”, “age”: 18, “address”: {“country” : “china”, “zip-code”: “10000”}}
数组是由方括号括起来的一组值构成,如:
代码语言:javascript复制[3, 1, 4, 1, 5, 9, 2, 6]
字符串与C或者Java的字符串非常相似。字符串是由双引号包围的任意数量Unicode字符的集合,使用反斜线转义。一个字符(character)即一个单独的字符串(character string)。 数字也与C或者Java的数值非常相似。除去未曾使用的八进制与十六进制格式。除去一些编码细节。 一些合法的JSON的实例:
代码语言:javascript复制{"a": 1, "b": [1, 2, 3]}
代码语言:javascript复制[1, 2, "3", {"a": 4}]
代码语言:javascript复制3.14
代码语言:javascript复制"wulianwangzhishi"
C# 例程
代码语言:javascript复制 JavaScriptSerializer ser = new JavaScriptSerializer();
CtrlJson rcj = new CtrlJson() { cmd = "YELLOW" };
string outputJson = ser.Serialize(rcj);
byte[] sendByte = System.Text.Encoding.Default.GetBytes(outputJson);
整体设计关键程序
代码语言:javascript复制private void button1_Click(object sender, EventArgs e)
{
IPAddress Adrr;
if (string.IsNullOrEmpty(textBox1.Text))
{
Adrr = IPAddress.Parse("255.255.255.255");
}
else
{
Adrr = IPAddress.Parse(textBox1.Text);
}
IPEndPoint remoteIpep = new IPEndPoint(Adrr, 50001); ;
JavaScriptSerializer ser = new JavaScriptSerializer();
CtrlJson rcj = new CtrlJson() { cmd = "RED" };
string outputJson = ser.Serialize(rcj);
byte[] sendByte = System.Text.Encoding.Default.GetBytes(outputJson);
//发送
ctrludpcRecv.Send(sendByte, sendByte.Length, remoteIpep);
}
页面设计