引用的第三方Nuget庫
- 32feet.NET 3.5.0
- MaterialDesignColors
- MaterialDesignThemes
- Newtonsoft.Json
使用到的技術:
XAML C#
本實例中使用的藍牙是作為服務器端等待連接.
主要流程如下:
第1步
初始化相關內容:
public static void InitSDK()
{
Guid mGUID = Guid.Parse("00001101-0000-1000-8000-00805F9B34FB");
bluetoothListener = new BluetoothListener(mGUID);
}
其中00001101-0000-1000-8000-00805F9B34FB是藍牙串口服務的uuid,其他類型的服務uuid各有不同,可以查閱相關資料
第2步
聲明藍牙監聽對象:
BluetoothListener bluetoothListener;
第3步
等待藍夜客戶端進行連接:
client = bluetoothListener.AcceptBluetoothClient();
獲取客戶端連接對象的信息(類似於TCP連接):
bluetoothModel.blueAddress = client.RemoteEndPoint.Address;
bluetoothModel.blueName = client.RemoteMachineName;
通知調用,通知注冊的事件已經有藍牙連接成功:
public static void Notify(object message)
{
NotifyMessage?.Invoke(message);
}
Notify(bluetoothModel);
接收數據並解析:
while (true)
{
try
{
if (peerStream.DataAvailable)
{
peerStream.ReadAsync(buffer, 0, 1024);
//peerStream.Read(buffer, 0, 200);
string data = Encoding.UTF8.GetString(buffer).ToString().Replace("\0", "");//去掉后面的\0字節
Console.WriteLine("Receiving data: " + data);
//if (peerStream.Length > 0)
//{
//}
}
}
catch (Exception ex)
{
client.Close();
Notify("鏈接關閉");
MessageBox.Show(ex.Message);
return;
}
}
作為服務器要一直監聽客戶端發送的消息,所以進行死循環接收(這種方案比較簡單,可以使用異步委托重復調用進行優化)
緩沖區大小設置為1024的長度,沒有做按照標准進行處理,此項目中不接受數據,所以沒有展開寫.
發送
發送數據
public static void Send(string str)
{
if (peerStream != null)
{
if (peerStream.CanWrite)
{
List<byte> list = new List<byte>();
byte header = 0x01;
list.Add(header);
byte[] dataBuffer = Encoding.UTF8.GetBytes(str);
foreach (var item in dataBuffer)
{
list.Add(item);
}
try
{
// Output data to stream
peerStream.Write(list.ToArray(), 0, list.Count);
peerStream.Flush();
}
catch (Exception ex)
{
client.Close();
Notify("鏈接關閉");
MessageBox.Show(ex.Message);
}
}
else
{
client.Close();
Notify("鏈接關閉");
MessageBox.Show("配對失敗內側");
}
}
else
{
MessageBox.Show("配對失敗外側");
}
}
發送數據遵從一定的協議,超過1024即1K字節長度則分包發送
其中0x01代表發送字符串,0x02代表發送文件
發送文件:
//1 文件類型
//1 文件子類型
//4 文件大小
//4 總包數
//4 第幾包
//4 本包大小
public static void SendFile(int type, string filePath)
{
if (peerStream != null)
{
int packCount = 512 - 17;
byte btype = (byte)type;
byte[] img = File.ReadAllBytes(filePath);
int imgLength = img.Length;
Console.WriteLine("圖像長度:" + imgLength);
byte[] blen = intToBytes(imgLength);
List<byte> original = new List<byte>(img.ToArray());
List<List<byte>> targetList = new List<List<byte>>();
int totalCount = img.Length / packCount + 1;
byte[] btotalCount = intToBytes(totalCount);
for (int i = 0; i < totalCount - 1; i++)
{
List<byte> curList = new List<byte>();
curList.Add(0x02);
curList.Add(btype);
//總文件長度
curList.AddRange(blen);
//總包數
curList.AddRange(btotalCount);
byte[] bForNoCount = intToBytes(i);
//第幾包
curList.AddRange(bForNoCount);
//本包大小
byte[] curCount = intToBytes(packCount);
curList.AddRange(curCount);
//包內容
curList.AddRange(original.GetRange(i * packCount, packCount));
targetList.Add(curList);
}
List<byte> lastList = new List<byte>();
lastList.Add(0x02);
lastList.Add(btype);
lastList.AddRange(blen);
//總包數
lastList.AddRange(btotalCount);
byte[] bNoCount = intToBytes(totalCount - 1);
//第幾包
lastList.AddRange(bNoCount);
//包大小
byte[] lastCount = intToBytes(imgLength - (totalCount - 1) * packCount);
lastList.AddRange(lastCount);
lastList.AddRange(original.GetRange((totalCount - 1) * packCount, imgLength - (totalCount - 1) * packCount));
//lastList.Add((Byte)('\n'));
targetList.Add(lastList);
if (peerStream.CanWrite)
{
foreach (var item in targetList)
{
try
{
Console.WriteLine("包長:" + item.Count);
peerStream.Write(item.ToArray(), 0, item.Count);
peerStream.Flush();
}
catch (Exception ex)
{
//Console.WriteLine(ex);
MessageBox.Show(ex.Message);
return;
}
}
}
}
}
文件一般大於1K,所以分包發送.基本協議見方法注釋.
代碼比較粗糙,畢竟只是一次性項目,沒有花很多信息分層,優化,寫注釋等,看客們請諒解,學習到精髓就可以了
詳細代碼見github鏈接
[鏈接](https://github.com/KleinPan/WpfAppBluetooth)