ningshuxia
10 天以前 018bfb9c78088d9cd7b9371edcd2102abd594b4d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
using InTheHand.Net;
using InTheHand.Net.Bluetooth;
using InTheHand.Net.Sockets;
using System.Text;
 
namespace IBox.WinFrmUI
{
    public class BluetoothHelper
    {
        #region 单例
 
        private static BluetoothHelper _Instance;
        private static readonly object locker = new object();
 
        public static BluetoothHelper GetInstance()
        {
            if (_Instance == null)
            {
                lock (locker)
                {
                    // 如果类的实例不存在则创建,否则直接返回
                    if (_Instance == null)
                    {
                        _Instance = new BluetoothHelper();
                    }
                }
            }
            return _Instance;
        }
 
        private int _length = 1;
 
        #endregion 单例
 
        #region 信息状态
 
        /// <summary>
        /// 信息状态
        /// </summary>
        /// <param name="srMessage"> 接收、发送信息、本地信息 </param>
        /// <param name="content"> 信息内容 </param>
        public delegate void ShowMessReturn(string content);
 
        public event ShowMessReturn SMR;
 
        public void OnSysMessage(string content)
        {
            if (SMR != null) SMR(content);
        }
 
        #endregion 信息状态
 
        #region 属性定义
 
        private const int BUFLEN = 1024; // 数据接收缓冲区大小
        private bool IsRun = false;
        private BluetoothAddress bthAddr = null;
        private BluetoothClient myClient = null;
        private List<BluetoothClient> LstClient = new List<BluetoothClient>();
        private BluetoothListener blthListener = null;
        private Thread listenThread = null;//监听线程
 
        private List<BluetoothDeviceInfo> LstBluetooth = null;
 
        #endregion 属性定义
 
        #region 处理方法
 
        public BluetoothHelper()
        {
            try
            {
                var radio = BluetoothRadio.Default;//获取当前PC的蓝牙适配器
                IsRun = (null != radio);
            }
            catch
            {
            }
            if (!IsRun) OnSysMessage("无可用蓝牙");
        }
 
        ~BluetoothHelper()
        {
            if (null != blthListener) blthListener.Stop();
            if (null != LstClient)
            {
                foreach (var itm in LstClient)
                {
                    if (null != itm)
                        itm.Close();
                }
            }
            IsRun = false;
        }
 
        /// <summary>
        /// 搜索蓝牙
        /// </summary>
        public List<BluetoothDeviceInfo> SearchBluetooth()
        {
            LstBluetooth = new List<BluetoothDeviceInfo>();        //搜索到的蓝牙的集合
            if (!IsRun) OnSysMessage("无可用蓝牙");
            else
            {
                BluetoothClient client = new BluetoothClient();
                BluetoothRadio radio = BluetoothRadio.Default; //获取蓝牙适配器
                radio.Mode = RadioMode.Connectable;
                var devices = client.DiscoverDevices();//搜索蓝牙 10秒钟
                LstBluetooth.AddRange(devices);
                //OnSysMessage("搜索蓝牙完成");
            }
 
            return LstBluetooth;
        }
 
        /// <summary>
        /// 连接蓝牙,蓝牙名称
        /// </summary>
        /// <param name="bluetoothName"></param>
        public void SetBluetoothByName(string bluetoothName)
        {
            try
            {
                if (null == LstBluetooth) return;
                var curBluetooth = LstBluetooth.Find(o => o.DeviceName == bluetoothName);
                if (null != curBluetooth) bthAddr = curBluetooth.DeviceAddress;
                NewConnect();
            }
            catch (Exception ex)
            {
                OnSysMessage("error:" + ex.ToString());
            }
        }
 
        /// <summary>
        /// 连接蓝牙,蓝牙地址(十六进制字符串)
        /// </summary>
        /// <param name="hexAddr"></param>
        public void SetBluetooth(string hexAddr)
        {
            try
            {
                var byTmp = HexToByte(hexAddr);
                Array.Reverse(byTmp);// 反转数组
                SetBluetooth(byTmp);
            }
            catch (Exception ex)
            {
                OnSysMessage("error:" + ex.ToString());
            }
        }
 
        /// <summary>
        /// 连接蓝牙,蓝牙地址
        /// </summary>
        /// <param name="addr"></param>
        public void SetBluetooth(byte[] addr)
        {
            try
            {
                bthAddr = new BluetoothAddress(addr);
                NewConnect();
            }
            catch (Exception ex)
            {
                OnSysMessage("error:" + ex.ToString());
            }
        }
 
        /// <summary>
        /// 连接蓝牙,蓝牙地址
        /// </summary>
        /// <param name="laddr"></param>
        public void SetBluetooth(long laddr)
        {
            try
            {
                bthAddr = new BluetoothAddress(laddr);
                NewConnect();
            }
            catch (Exception ex)
            {
                OnSysMessage("error:" + ex.ToString());
            }
        }
 
        /// <summary>
        /// 连接蓝牙
        /// </summary>
        private void NewConnect()
        {
            if (!IsRun) OnSysMessage("无可用蓝牙");
            else if (null != bthAddr)
            {
                var mGUID = BluetoothService.Handsfree;
 
                if (null != myClient) myClient.Close();
                myClient = new BluetoothClient();
                //myClient.Connect(bthAddr,mGUID);
                var be = new BluetoothEndPoint(bthAddr, BluetoothService.SerialPort);
                myClient.Connect(be);
 
                ReceiveDataThread(myClient, false);
                //OnSysMessage("发起连接");
            }
        }
 
        /// <summary>
        /// 发送数据,文本
        /// </summary>
        /// <param name="sData"></param>
        public void SendData(string sData)
        {
            if (!string.IsNullOrEmpty(sData) && (sData.Contains("getbase") || sData.Contains("alarm")))
                _length = 1;
            else
                _length = 100;
            var byTmp = Encoding.UTF8.GetBytes(sData);
            SendData(byTmp);
        }
 
        /// <summary>
        /// 发送数据,byte
        /// </summary>
        /// <param name="sData"></param>
        public void SendData(byte[] sData)
        {
            try
            {
                if (!IsRun) OnSysMessage("无可用蓝牙");
                else if (null == sData || sData.Length < 1) OnSysMessage("发送数据不能为空");
                else
                {
                    var sendCnt = 0;
                    if (null != LstClient && LstClient.Count > 0)
                    {
                        foreach (var itm in LstClient)
                        {
                            if (null != itm && itm.Connected)
                            {
                                var bls = itm.GetStream();
                                bls.Write(sData, 0, sData.Length);
                                bls.Flush();
                                sendCnt++;
                            }
                        }
                    }
 
                    if (sendCnt < 1 && (null == myClient || !myClient.Connected)) NewConnect(); // 重连机制
                    if (null != myClient && myClient.Connected)
                    {
                        var bls = myClient.GetStream();
                        bls.Write(sData, 0, sData.Length);
                        bls.Flush();
                        sendCnt++;
                    }
 
                    //OnSysMessage(string.Format("连接{0}发送{1}个字节", sendCnt, sData.Length));
                }
            }
            catch (Exception ex)
            {
                OnSysMessage("error:" + ex.ToString());
            }
        }
 
        /// <summary>
        /// 监听蓝牙连接请求
        /// </summary>
        public void ListenerData()
        {
            //OnSysMessage("蓝牙启动监听:" + IsRun);
            if (null != listenThread) listenThread.Abort();
            listenThread = new Thread(new ThreadStart(() =>
            {
                if (IsRun)
                {
                    var mGUID = BluetoothService.Handsfree;
                    blthListener = new BluetoothListener(mGUID);
                    blthListener.Start();
 
                    while (IsRun)
                    {
                        var newClient = blthListener.AcceptBluetoothClient();
                        //OnSysMessage("蓝牙链接:" + newClient.RemoteMachineName);
                        ReceiveDataThread(newClient);
                    }
                }
            }));
            listenThread.IsBackground = true;
            listenThread.Start();
        }
 
        /// <summary>
        /// 蓝牙数据接收线程
        /// </summary>
        /// <param name="client"></param>
        /// <param name="isInList"></param>
        private void ReceiveDataThread(BluetoothClient client, bool isInList = true)
        {
            lock (LstClient) { if (isInList) LstClient.Add(client); }
            var th = new Thread(new ThreadStart(() =>
            {
                ReceiveData(client);
                lock (LstClient) LstClient.Remove(client);
            }));
            th.IsBackground = true;
            th.Start();
        }
 
        public void Close()
        {
            if (myClient != null && myClient.Connected)
            {
                myClient.Close();
                myClient.Dispose();
                myClient = null;
            }
        }
 
        /// <summary>
        /// 数据接收
        /// </summary>
        /// <param name="client"></param>
        private void ReceiveData(BluetoothClient client)
        {
            try
            {
                var sl = new List<string>();
                var st = new byte[0];
 
                while (client != null && client.Connected)
                {
                    var peerStream = client.GetStream();
                    byte[] buffer = new byte[1];
                    peerStream.Read(buffer, 0, 1);
                    st = st.Concat(buffer).ToArray();
                    var receive = Encoding.UTF8.GetString(st).ToString();
                    if (receive.Contains("[&end&]"))
                    {
                        var c = Encoding.UTF8.GetString(st).ToString();
                        st = new byte[0];
                        OnSysMessage(c);
                    }
                }
            }
            catch (Exception ex)
            {
                // OnSysMessage("error:" + ex.ToString());
            }
        }
 
        #endregion 处理方法
 
        #region 辅助方法
 
        /// <summary>
        /// 十六进制转byte[],无分割符
        /// </summary>
        public byte[] HexToByte(string strHex)
        {
            byte[] byTmp = new byte[0];
            if (string.IsNullOrEmpty(strHex) || (strHex.Length % 2) > 0) return byTmp;
 
            try
            {
                var len = strHex.Length / 2;
                byTmp = new byte[len];
                for (int i = 0; i < len; i++)
                {
                    var phex = strHex.Substring(2 * i, 2);
                    byTmp[i] = Convert.ToByte(phex, 16);
                }
            }
            catch (Exception ex)
            {
                byTmp = new byte[0];
                OnSysMessage("error:" + ex.ToString());
            }
            return byTmp;
        }
 
        #endregion 辅助方法
    }
}