UDPCommunication.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Dispatch;
  6. using System.Net;
  7. using System.Text.RegularExpressions;
  8. using System.Net.Sockets;
  9. using System.Threading;
  10. namespace Dispatch
  11. {
  12. /// <summary>
  13. /// UDP通信类
  14. /// </summary>
  15. public class UDPCommunication:CommunicationBase
  16. {
  17. /// <summary>
  18. /// 本地IP
  19. /// </summary>
  20. private string localIP;
  21. /// <summary>
  22. /// 接收字节缓存
  23. /// </summary>
  24. public List<byte> receiveBuffer = new List<byte>(2046);
  25. /// <summary>
  26. /// 端口锁定对象
  27. /// </summary>
  28. private static object portLock = new object();
  29. /// <summary>
  30. /// 信息检效处理操作
  31. /// </summary>
  32. /// <param name="sender"></param>
  33. /// <param name="e"></param>
  34. public delegate void MatchedParityHandler(object sender, DataEventArgs e);
  35. /// <summary>
  36. /// 信息检效事件
  37. /// </summary>
  38. public event MatchedParityHandler MatchedParity;
  39. /// <summary>
  40. /// 日志记录
  41. /// </summary>
  42. internal static BlackBoxFile.CBlackBoxFile gs_blackBoxFile;
  43. /// <summary>
  44. /// 接收IP列表
  45. /// </summary>
  46. List<IPAddress> recieveIPs = new List<IPAddress>();
  47. AutoResetEvent autoReset = new AutoResetEvent(false);
  48. /// <summary>
  49. /// 本地IP获取
  50. /// </summary>
  51. public string LocalIP
  52. {
  53. get
  54. {
  55. if (string.IsNullOrEmpty(localIP))
  56. {
  57. return Dns.GetHostAddresses(Dns.GetHostName())[0].ToString();
  58. }
  59. return localIP;
  60. }
  61. set
  62. {
  63. string str = @"^\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}$";
  64. if (Regex.IsMatch(value, str))
  65. {
  66. localIP = value;
  67. }
  68. else
  69. {
  70. throw new Exception("IP地址格式错误");
  71. }
  72. }
  73. }
  74. private int port;
  75. /// <summary>
  76. /// 端口
  77. /// </summary>
  78. public int Port
  79. {
  80. get
  81. {
  82. if (port <= 0)
  83. return 10000;
  84. return port;
  85. }
  86. set { port = value; }
  87. }
  88. private int scanTime;
  89. /// <summary>
  90. /// 扫描时间
  91. /// </summary>
  92. public int ScanTime
  93. {
  94. get
  95. {
  96. if (scanTime <= 0)
  97. return 10;
  98. return scanTime;
  99. }
  100. set { scanTime = value; }
  101. }
  102. /// <summary>
  103. /// 对象标识
  104. /// </summary>
  105. /// <returns></returns>
  106. public override object GetTag()
  107. {
  108. return this;
  109. }
  110. private UdpClient udpServer;
  111. private Thread thread;
  112. private Thread thread1;
  113. /// <summary>
  114. /// UDP通信
  115. /// </summary>
  116. /// <param name="ip"></param>
  117. /// <param name="port"></param>
  118. /// <param name="scanTime"></param>
  119. public UDPCommunication(string ip, int port, int scanTime = 0)
  120. {
  121. LocalIP = ip;
  122. Port = port;
  123. ScanTime = scanTime;
  124. IsOpen = false;
  125. gs_blackBoxFile = new BlackBoxFile.CBlackBoxFile();
  126. }
  127. AutoResetEvent done = new AutoResetEvent(true);
  128. /// <summary>
  129. /// 字符数据转十六进制字符串
  130. /// </summary>
  131. /// <param name="buffer"></param>
  132. /// <returns></returns>
  133. public static string ByteToHexString(byte[] buffer)
  134. {
  135. StringBuilder builder = new StringBuilder(buffer.Length * 3);
  136. foreach (byte data in buffer)
  137. {
  138. builder.Append(Convert.ToString(data, 16).PadLeft(2, '0').PadRight(3, ' '));
  139. }
  140. return builder.ToString().ToUpper();
  141. }
  142. /// <summary>
  143. /// 接收线程
  144. /// </summary>
  145. private void ReceiveThread()
  146. {
  147. IPEndPoint remotePoint = new IPEndPoint(IPAddress.Any,0);
  148. while (true)
  149. {
  150. if(IsOpen && udpServer != null)
  151. {
  152. ReceivedEventArgs e1 = new ReceivedEventArgs();
  153. try
  154. {
  155. e1.buffer = udpServer.Receive(ref remotePoint);
  156. if (remotePoint.Address != IPAddress.Parse(LocalIP) && !recieveIPs.Contains(remotePoint.Address))
  157. {
  158. recieveIPs.Add(remotePoint.Address);
  159. }
  160. receiveBuffer.AddRange(e1.buffer);
  161. }
  162. catch (System.Exception ex)
  163. {
  164. Console.WriteLine(ex.Message);
  165. }
  166. Thread.Sleep(ScanTime);
  167. done.Set();
  168. }
  169. }
  170. }
  171. /// <summary>
  172. /// 第二接收线程
  173. /// </summary>
  174. private void ReceiveThread2()
  175. {
  176. IPEndPoint remotePoint = new IPEndPoint(IPAddress.Any, 0);
  177. while (true)
  178. {
  179. if (receiveBuffer.Count > 0)
  180. {
  181. done.Reset();
  182. byte[] buffer;
  183. int type;
  184. buffer = DataHander(out type);
  185. DataEventArgs e = new DataEventArgs();
  186. e.type = type;
  187. e.data = buffer;
  188. if (type != -1)
  189. {
  190. MyData data = new MyData();
  191. data.sender = this;
  192. data.e = e;
  193. Thread t = new Thread(OnMatchParity);
  194. t.Start(data);
  195. }
  196. }
  197. Thread.Sleep(100);
  198. }
  199. }
  200. /// <summary>
  201. /// 读取数据
  202. /// </summary>
  203. public event EventHandler ReadingData;
  204. /// <summary>
  205. /// 写入数据
  206. /// </summary>
  207. public event EventHandler WritingData;
  208. void OnReadingData(EventArgs e)
  209. {
  210. if (ReadingData != null)
  211. {
  212. ReadingData(this, e);
  213. }
  214. }
  215. void OnWritingData(EventArgs e)
  216. {
  217. if (WritingData != null)
  218. {
  219. WritingData(this, e);
  220. }
  221. }
  222. /// <summary>
  223. /// 事件监听处理
  224. /// </summary>
  225. /// <param name="sender"></param>
  226. /// <param name="e"></param>
  227. public void OnMatchedParity(object sender, DataEventArgs e)
  228. {
  229. if (MatchedParity != null)
  230. {
  231. MatchedParity(sender, e);
  232. }
  233. }
  234. /// <summary>
  235. /// 事件监听处理
  236. /// </summary>
  237. /// <param name="o"></param>
  238. public void OnMatchParity(object o)
  239. {
  240. MyData data = o as MyData;
  241. Console.ForegroundColor = ConsoleColor.Yellow;
  242. //Console.WriteLine("所在线程ID:" + Thread.CurrentThread.ManagedThreadId.ToString() + "类型:" + data.e.type + " " + Byte2HexString(data.e.data));
  243. Console.ResetColor();
  244. OnMatchedParity(data.sender, data.e);
  245. Thread.Sleep(500);//加延时是为了避免解析后有过长的操作占用系统资源
  246. }
  247. private class MyData
  248. {
  249. public object sender;
  250. public DataEventArgs e;
  251. }
  252. /// <summary>
  253. /// 异或操作
  254. /// </summary>
  255. /// <param name="buffer"></param>
  256. /// <param name="count"></param>
  257. /// <param name="index"></param>
  258. /// <returns></returns>
  259. public static byte XOR_Check(byte[] buffer, int count, int index = 0)
  260. {
  261. byte b = 0;
  262. for (int i = 0; i < count; i++)
  263. {
  264. b ^= buffer[index + i];
  265. }
  266. return b;
  267. }
  268. /// <summary>
  269. /// 整理数据缓存表
  270. /// </summary>
  271. /// <param name="bufferList">数据缓存表</param>
  272. /// <param name="targetByte">目标字节</param>
  273. private static void ArrangeBuffer(List<byte> bufferList, byte targetByte)
  274. {
  275. int delBytes = 1;
  276. for (int i = 1; i < bufferList.Count; i++)
  277. {
  278. if (bufferList[i] == targetByte)
  279. {
  280. break;
  281. }
  282. else
  283. {
  284. delBytes++;
  285. }
  286. }
  287. try
  288. {
  289. lock (portLock)
  290. {
  291. bufferList.RemoveRange(0, delBytes);
  292. }
  293. }
  294. catch (Exception ex)
  295. {
  296. throw ex;
  297. }
  298. }
  299. /// <summary>
  300. /// 数据操作
  301. /// </summary>
  302. /// <param name="type"></param>
  303. /// <returns></returns>
  304. private byte[] DataHander(out int type)
  305. {
  306. type = -1;
  307. int framelength = 10; // 帧长度
  308. byte frameHead = 0x10; // 帧头
  309. byte frameTaig = 0x03;
  310. List<byte> frameFuncList = new List<byte> { 0x41, 0x42, 0x46, 0x32, 0x33, 0x35, 0x38 };
  311. if (receiveBuffer.Count >= framelength)
  312. {
  313. #region MyRegion
  314. if ((receiveBuffer[0] == frameHead) && (receiveBuffer.Count >= 14) && frameFuncList.Contains(receiveBuffer[1]))
  315. {
  316. // 二代协议
  317. byte checkSum = 0x00;
  318. for (int i = 0; i < 12; i++)
  319. {
  320. checkSum ^= receiveBuffer[i];
  321. }
  322. if (checkSum == receiveBuffer[12] && frameTaig == receiveBuffer[13])
  323. {
  324. byte[] data = new byte[14];
  325. for (int i = 0; i < 14; i++)
  326. {
  327. data[i] = receiveBuffer[i];
  328. }
  329. lock (portLock)
  330. {
  331. receiveBuffer.RemoveRange(0, 14);
  332. }
  333. type = 3;
  334. return data;
  335. }
  336. else
  337. {
  338. ArrangeBuffer(receiveBuffer, frameHead);
  339. }
  340. }
  341. else if ((receiveBuffer[0] == frameHead) && (receiveBuffer.Count >= 10) && receiveBuffer[1] == 0x62)
  342. {
  343. byte checkSum = 0x00;
  344. for (int i = 0; i < 8; i++)
  345. {
  346. checkSum ^= receiveBuffer[i];
  347. }
  348. if (checkSum == receiveBuffer[8] && frameTaig == receiveBuffer[9])
  349. {
  350. byte[] data = new byte[10];
  351. for (int i = 0; i < 10; i++)
  352. {
  353. data[i] = receiveBuffer[i];
  354. }
  355. lock (portLock)
  356. {
  357. receiveBuffer.RemoveRange(0, 10);
  358. }
  359. type = 3;
  360. return data;
  361. }
  362. else
  363. {
  364. ArrangeBuffer(receiveBuffer, frameHead);
  365. }
  366. }
  367. else
  368. {
  369. ArrangeBuffer(receiveBuffer, frameHead);
  370. }
  371. #endregion
  372. }
  373. return new byte[1] { 0 };
  374. }
  375. /// <summary>
  376. /// 发送数据
  377. /// </summary>
  378. /// <param name="buffer"></param>
  379. /// <param name="o"></param>
  380. public override void SendData(byte[] buffer,object o)
  381. {
  382. IPEndPoint ip = o as IPEndPoint;
  383. if (ip == null)
  384. {
  385. string ipStr = LocalIP.Substring(0, LocalIP.LastIndexOf('.') + 1);
  386. try
  387. {
  388. if (IsOpen)
  389. {
  390. Console.WriteLine(string.Format("[{0,-15}:{1} {2}]发送:{3}", LocalIP,Port,DateTime.Now.ToString("HH:mm:ss"), ByteToHexString(buffer)));
  391. if (recieveIPs.Count < 0)
  392. {
  393. udpServer.Send(buffer, buffer.Length, new IPEndPoint(IPAddress.Parse("255.255.255.255"), Port));
  394. }
  395. else
  396. {
  397. foreach (IPAddress ipa in recieveIPs)
  398. {
  399. udpServer.Send(buffer, buffer.Length, new IPEndPoint(ipa, Port));
  400. }
  401. }
  402. }
  403. }
  404. catch (System.Exception ex)
  405. {
  406. throw new Exception(ex.Message);
  407. }
  408. }
  409. else
  410. {
  411. try
  412. {
  413. if (IsOpen)
  414. {
  415. Console.WriteLine(string.Format("[{0,-15}:{1} {2}]发送:{3}", LocalIP, Port, DateTime.Now.ToString("HH:mm:ss"), ByteToHexString(buffer)));
  416. udpServer.Send(buffer, buffer.Length, new IPEndPoint(ip.Address,Port));
  417. }
  418. }
  419. catch (System.Exception ex)
  420. {
  421. throw new Exception(ex.Message);
  422. }
  423. }
  424. }
  425. /// <summary>
  426. /// 关闭联接
  427. /// </summary>
  428. public override void Close()
  429. {
  430. if(udpServer != null)
  431. {
  432. udpServer.Close();
  433. udpServer = null;
  434. }
  435. if (thread != null && thread.ThreadState != ThreadState.Stopped)
  436. {
  437. if (done.WaitOne(500))
  438. {
  439. thread.Abort();
  440. }
  441. thread = null;
  442. }
  443. IsOpen = false;
  444. }
  445. /// <summary>
  446. /// 释放联接
  447. /// </summary>
  448. public override void Dispose()
  449. {
  450. if(udpServer != null)
  451. udpServer.Close();
  452. if(thread != null && thread.ThreadState != ThreadState.Stopped)
  453. {
  454. if (done.WaitOne(500))
  455. {
  456. thread.Abort();
  457. }
  458. thread.Abort();
  459. thread = null;
  460. }
  461. base.Dispose();
  462. }
  463. /// <summary>
  464. /// 打开联接
  465. /// </summary>
  466. public override void Open()
  467. {
  468. if (thread != null&&udpServer!=null)
  469. {
  470. if (thread.ThreadState == ThreadState.Suspended)
  471. {
  472. autoReset.Set();//thread.Resume();
  473. }
  474. else if (thread.ThreadState == ThreadState.Unstarted)
  475. {
  476. thread.Start();
  477. }
  478. }
  479. else
  480. {
  481. IPAddress[] address = Dns.GetHostAddresses(Dns.GetHostName());
  482. for (int i = 0; i < address.Count(); i++)
  483. {
  484. if (address[i].AddressFamily.ToString().ToLower() == "internetwork" && address[i].ToString() == LocalIP)
  485. {
  486. udpServer = new UdpClient(new IPEndPoint(IPAddress.Any, Port));
  487. thread = new Thread(ReceiveThread);
  488. thread.Start();
  489. thread1 = new Thread(ReceiveThread2);
  490. thread1.Start();
  491. break;
  492. }
  493. else if (i == address.Count() - 1)
  494. {
  495. Console.WriteLine("UDP中IP地址不存在");
  496. return;
  497. }
  498. }
  499. }
  500. IsOpen = true;
  501. }
  502. }
  503. }