使用 C# 在带有 Windows 10 IoT 的 Raspberry Pi 2 和 PC 之间建立简单连接






4.14/5 (5投票s)
本项目将展示如何使用 C# 通过 TCP/IP 网络在 Raspberry Pi 2 (Windows 10 IoT) 和 PC 之间发送一个简单的字符串,其中 Raspberry Pi 作为服务器,PC 作为客户端。
引言
本项目将向您展示如何使用 C# 和 UWP (通用 Windows 平台) 通过 TCP/IP 网络在 Raspberry Pi 2 (Windows 10 IoT) 和 Windows 10 PC 之间发送一个简单的 string
,其中 Raspberry Pi 作为服务器,PC 作为客户端,PC 向 Raspberry Pi 发送消息。
背景
UWP - 通用 Windows 平台
UWP 是微软推出的一种新型项目,它允许应用程序在任何 Windows 平台上运行(例如 Windows 8 或更高版本、Xbox、Windows Phone 等),而无需任何修改。现在您还有一个“清单”,如果您没有在清单中授予权限,您的应用程序将无法工作。有关更多信息,请访问此链接
Windows 10 IoT Core
Windows 10 IoT Core 是 Windows 10 的一个版本,针对具有或不具有显示器的小型设备进行了优化。在撰写本文时,Windows 10 IoT Core 支持以下设备
- Raspberry Pi 2
- Arrow DragonBoard 410c
- MinnowBoard MAX。
您可以使用 UWP 为 Windows 10 IoT Core 开发应用程序。有关更多信息,请访问此链接
项目
对于本项目,创建了一个“解决方案”,其中包含两个项目,一个使用 UWP (客户端),另一个使用 Background IoT (服务器)。要访问整个项目,请访问此链接
图表
接收字符串 (服务器)
在这里,我将展示如何绑定某个端口并等待连接。为此,创建了一个 SocketServer
类。
变量
private readonly int _port;
public int Port { get { return _port; } }
private StreamSocketListener listener;
public delegate void DataRecived(string data);
public event DataRecived OnDataRecived;
public delegate void Error(string message);
public event Error OnError;
绑定端口
public async void Star()
{
listener = new StreamSocketListener();
listener.ConnectionReceived += Listener_ConnectionReceived;
await listener.BindServiceNameAsync(Port.ToString());
}
等待接收消息
private async void Listener_ConnectionReceived
(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
{
var reader = new DataReader(args.Socket.InputStream);
try
{
while (true)
{
uint sizeFieldCount = await reader.LoadAsync(sizeof(uint));
//if disconnected
if (sizeFieldCount != sizeof(uint))
return;
uint stringLenght = reader.ReadUInt32();
uint actualStringLength = await reader.LoadAsync(stringLenght);
//if disconnected
if (stringLenght != actualStringLength)
return;
if (OnDataRecived != null)
OnDataRecived(reader.ReadString(actualStringLength));
}
}
catch (Exception ex)
{
if (OnError != null)
OnError(ex.Message);
}
}
启动应用程序
public void Run(IBackgroundTaskInstance taskInstance)
{
...
taskInstance.GetDeferral();
var socket = new SocketServer(9000);
ThreadPool.RunAsync(x => {
socket.Star();
socket.OnError += socket_OnError;
socket.OnDataRecived += Socket_OnDataRecived;
});
}
别忘了赋予应用程序客户端和服务器的能力,请参见下图
发送字符串 (客户端)
客户端在 Windows 10 上使用 UWP 进行测试。为了发送 string
,它创建了一个 SocketClient
类
变量
private readonly string _ip;
private readonly int _port;
private StreamSocket _socket;
private DataWriter _writer;
private DataReader _reader;
public delegate void Error(string message);
public event Error OnError;
public delegate void DataRecived(string data);
public event DataRecived OnDataRecived;
public string Ip { get { return _ip; } }
public int Port { get { return _port; } }
连接
为了创建连接,您需要以下代码
public async void Connect()
{
try
{
var hostName = new HostName(Ip);
_socket = new StreamSocket();
await _socket.ConnectAsync(hostName, Port.ToString());
_writer = new DataWriter(_socket.OutputStream);
Read();
}
catch (Exception ex)
{
..
}
}
发送字符串
public async void Send(string message)
{
_writer.WriteUInt32(_writer.MeasureString(message));
_writer.WriteString(message);
try
{
await _writer.StoreAsync();
await _writer.FlushAsync();
}
catch (Exception ex)
{
...
}
}
读取
要读取内容,代码与 ServerSocket
类中使用的代码相同。
Close
public void Close()
{
_writer.DetachStream();
_writer.Dispose();
_reader.DetachStream();
_reader.Dispose();
_socket.Dispose();
}
结论
要建立一个简单的连接来发送 string
,您不需要复杂的或大量的代码,并且使用 C# 和 UWP 很容易。现在可以扩展一些应用程序并创建更复杂的东西。UWP 很好,但您有很多东西需要学习,因为它是一个新的框架,它引入了关于设计和开发的新概念,因为大多数方法将是 async
的。
致谢
我谨向我的两位朋友 Guilherme Effenberger 和 Ricardo Petrére 致谢,感谢他们帮助我撰写和翻译本文。