123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using Dispatch;
- using System.Net;
- using System.Text.RegularExpressions;
- using System.Net.Sockets;
- using System.Threading;
- namespace Dispatch
- {
- /// <summary>
- /// UDP通信类
- /// </summary>
- public class UDPCommunication:CommunicationBase
- {
- /// <summary>
- /// 本地IP
- /// </summary>
- private string localIP;
- /// <summary>
- /// 接收字节缓存
- /// </summary>
- public List<byte> receiveBuffer = new List<byte>(2046);
- /// <summary>
- /// 端口锁定对象
- /// </summary>
- private static object portLock = new object();
- /// <summary>
- /// 信息检效处理操作
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- public delegate void MatchedParityHandler(object sender, DataEventArgs e);
- /// <summary>
- /// 信息检效事件
- /// </summary>
- public event MatchedParityHandler MatchedParity;
- /// <summary>
- /// 日志记录
- /// </summary>
- internal static BlackBoxFile.CBlackBoxFile gs_blackBoxFile;
- /// <summary>
- /// 接收IP列表
- /// </summary>
- List<IPAddress> recieveIPs = new List<IPAddress>();
- AutoResetEvent autoReset = new AutoResetEvent(false);
- /// <summary>
- /// 本地IP获取
- /// </summary>
- public string LocalIP
- {
- get
- {
- if (string.IsNullOrEmpty(localIP))
- {
- return Dns.GetHostAddresses(Dns.GetHostName())[0].ToString();
- }
- return localIP;
- }
- set
- {
- string str = @"^\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}$";
- if (Regex.IsMatch(value, str))
- {
- localIP = value;
- }
- else
- {
- throw new Exception("IP地址格式错误");
- }
- }
- }
- private int port;
- /// <summary>
- /// 端口
- /// </summary>
- public int Port
- {
- get
- {
- if (port <= 0)
- return 10000;
- return port;
- }
- set { port = value; }
- }
- private int scanTime;
- /// <summary>
- /// 扫描时间
- /// </summary>
- public int ScanTime
- {
- get
- {
- if (scanTime <= 0)
- return 10;
- return scanTime;
- }
- set { scanTime = value; }
- }
- /// <summary>
- /// 对象标识
- /// </summary>
- /// <returns></returns>
- public override object GetTag()
- {
- return this;
- }
- private UdpClient udpServer;
- private Thread thread;
- private Thread thread1;
- /// <summary>
- /// UDP通信
- /// </summary>
- /// <param name="ip"></param>
- /// <param name="port"></param>
- /// <param name="scanTime"></param>
- public UDPCommunication(string ip, int port, int scanTime = 0)
- {
- LocalIP = ip;
- Port = port;
- ScanTime = scanTime;
- IsOpen = false;
- gs_blackBoxFile = new BlackBoxFile.CBlackBoxFile();
- }
- AutoResetEvent done = new AutoResetEvent(true);
- /// <summary>
- /// 字符数据转十六进制字符串
- /// </summary>
- /// <param name="buffer"></param>
- /// <returns></returns>
- public static string ByteToHexString(byte[] buffer)
- {
- StringBuilder builder = new StringBuilder(buffer.Length * 3);
- foreach (byte data in buffer)
- {
- builder.Append(Convert.ToString(data, 16).PadLeft(2, '0').PadRight(3, ' '));
- }
- return builder.ToString().ToUpper();
- }
- /// <summary>
- /// 接收线程
- /// </summary>
- private void ReceiveThread()
- {
- IPEndPoint remotePoint = new IPEndPoint(IPAddress.Any,0);
- while (true)
- {
- if(IsOpen && udpServer != null)
- {
- ReceivedEventArgs e1 = new ReceivedEventArgs();
- try
- {
- e1.buffer = udpServer.Receive(ref remotePoint);
-
- if (remotePoint.Address != IPAddress.Parse(LocalIP) && !recieveIPs.Contains(remotePoint.Address))
- {
- recieveIPs.Add(remotePoint.Address);
- }
- receiveBuffer.AddRange(e1.buffer);
- }
- catch (System.Exception ex)
- {
- Console.WriteLine(ex.Message);
-
- }
-
- Thread.Sleep(ScanTime);
- done.Set();
- }
- }
- }
- /// <summary>
- /// 第二接收线程
- /// </summary>
- private void ReceiveThread2()
- {
- IPEndPoint remotePoint = new IPEndPoint(IPAddress.Any, 0);
- while (true)
- {
- if (receiveBuffer.Count > 0)
- {
- done.Reset();
- byte[] buffer;
- int type;
- buffer = DataHander(out type);
- DataEventArgs e = new DataEventArgs();
- e.type = type;
- e.data = buffer;
- if (type != -1)
- {
- MyData data = new MyData();
- data.sender = this;
- data.e = e;
- Thread t = new Thread(OnMatchParity);
- t.Start(data);
- }
- }
- Thread.Sleep(100);
- }
- }
- /// <summary>
- /// 读取数据
- /// </summary>
- public event EventHandler ReadingData;
- /// <summary>
- /// 写入数据
- /// </summary>
- public event EventHandler WritingData;
- void OnReadingData(EventArgs e)
- {
- if (ReadingData != null)
- {
- ReadingData(this, e);
- }
- }
- void OnWritingData(EventArgs e)
- {
- if (WritingData != null)
- {
- WritingData(this, e);
- }
- }
- /// <summary>
- /// 事件监听处理
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- public void OnMatchedParity(object sender, DataEventArgs e)
- {
- if (MatchedParity != null)
- {
- MatchedParity(sender, e);
- }
- }
- /// <summary>
- /// 事件监听处理
- /// </summary>
- /// <param name="o"></param>
- public void OnMatchParity(object o)
- {
- MyData data = o as MyData;
- Console.ForegroundColor = ConsoleColor.Yellow;
- //Console.WriteLine("所在线程ID:" + Thread.CurrentThread.ManagedThreadId.ToString() + "类型:" + data.e.type + " " + Byte2HexString(data.e.data));
- Console.ResetColor();
- OnMatchedParity(data.sender, data.e);
- Thread.Sleep(500);//加延时是为了避免解析后有过长的操作占用系统资源
- }
- private class MyData
- {
- public object sender;
- public DataEventArgs e;
- }
- /// <summary>
- /// 异或操作
- /// </summary>
- /// <param name="buffer"></param>
- /// <param name="count"></param>
- /// <param name="index"></param>
- /// <returns></returns>
- public static byte XOR_Check(byte[] buffer, int count, int index = 0)
- {
- byte b = 0;
- for (int i = 0; i < count; i++)
- {
- b ^= buffer[index + i];
- }
- return b;
- }
- /// <summary>
- /// 整理数据缓存表
- /// </summary>
- /// <param name="bufferList">数据缓存表</param>
- /// <param name="targetByte">目标字节</param>
- private static void ArrangeBuffer(List<byte> bufferList, byte targetByte)
- {
- int delBytes = 1;
- for (int i = 1; i < bufferList.Count; i++)
- {
- if (bufferList[i] == targetByte)
- {
- break;
- }
- else
- {
- delBytes++;
- }
- }
- try
- {
- lock (portLock)
- {
- bufferList.RemoveRange(0, delBytes);
- }
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- /// <summary>
- /// 数据操作
- /// </summary>
- /// <param name="type"></param>
- /// <returns></returns>
- private byte[] DataHander(out int type)
- {
- type = -1;
- int framelength = 10; // 帧长度
- byte frameHead = 0x10; // 帧头
- byte frameTaig = 0x03;
- List<byte> frameFuncList = new List<byte> { 0x41, 0x42, 0x46, 0x32, 0x33, 0x35, 0x38 };
- if (receiveBuffer.Count >= framelength)
- {
- #region MyRegion
- if ((receiveBuffer[0] == frameHead) && (receiveBuffer.Count >= 14) && frameFuncList.Contains(receiveBuffer[1]))
- {
- // 二代协议
- byte checkSum = 0x00;
- for (int i = 0; i < 12; i++)
- {
- checkSum ^= receiveBuffer[i];
- }
- if (checkSum == receiveBuffer[12] && frameTaig == receiveBuffer[13])
- {
- byte[] data = new byte[14];
- for (int i = 0; i < 14; i++)
- {
- data[i] = receiveBuffer[i];
- }
- lock (portLock)
- {
- receiveBuffer.RemoveRange(0, 14);
- }
- type = 3;
- return data;
- }
- else
- {
- ArrangeBuffer(receiveBuffer, frameHead);
- }
- }
- else if ((receiveBuffer[0] == frameHead) && (receiveBuffer.Count >= 10) && receiveBuffer[1] == 0x62)
- {
- byte checkSum = 0x00;
- for (int i = 0; i < 8; i++)
- {
- checkSum ^= receiveBuffer[i];
- }
- if (checkSum == receiveBuffer[8] && frameTaig == receiveBuffer[9])
- {
- byte[] data = new byte[10];
- for (int i = 0; i < 10; i++)
- {
- data[i] = receiveBuffer[i];
- }
- lock (portLock)
- {
- receiveBuffer.RemoveRange(0, 10);
- }
- type = 3;
- return data;
- }
- else
- {
- ArrangeBuffer(receiveBuffer, frameHead);
- }
- }
- else
- {
- ArrangeBuffer(receiveBuffer, frameHead);
- }
- #endregion
- }
- return new byte[1] { 0 };
- }
- /// <summary>
- /// 发送数据
- /// </summary>
- /// <param name="buffer"></param>
- /// <param name="o"></param>
- public override void SendData(byte[] buffer,object o)
- {
- IPEndPoint ip = o as IPEndPoint;
- if (ip == null)
- {
- string ipStr = LocalIP.Substring(0, LocalIP.LastIndexOf('.') + 1);
- try
- {
- if (IsOpen)
- {
- Console.WriteLine(string.Format("[{0,-15}:{1} {2}]发送:{3}", LocalIP,Port,DateTime.Now.ToString("HH:mm:ss"), ByteToHexString(buffer)));
-
- if (recieveIPs.Count < 0)
- {
- udpServer.Send(buffer, buffer.Length, new IPEndPoint(IPAddress.Parse("255.255.255.255"), Port));
- }
- else
- {
- foreach (IPAddress ipa in recieveIPs)
- {
- udpServer.Send(buffer, buffer.Length, new IPEndPoint(ipa, Port));
- }
- }
-
- }
- }
- catch (System.Exception ex)
- {
- throw new Exception(ex.Message);
- }
-
- }
- else
- {
- try
- {
- if (IsOpen)
- {
- Console.WriteLine(string.Format("[{0,-15}:{1} {2}]发送:{3}", LocalIP, Port, DateTime.Now.ToString("HH:mm:ss"), ByteToHexString(buffer)));
- udpServer.Send(buffer, buffer.Length, new IPEndPoint(ip.Address,Port));
- }
-
- }
- catch (System.Exception ex)
- {
- throw new Exception(ex.Message);
- }
- }
- }
- /// <summary>
- /// 关闭联接
- /// </summary>
- public override void Close()
- {
- if(udpServer != null)
- {
- udpServer.Close();
- udpServer = null;
- }
- if (thread != null && thread.ThreadState != ThreadState.Stopped)
- {
- if (done.WaitOne(500))
- {
- thread.Abort();
- }
- thread = null;
- }
-
- IsOpen = false;
- }
- /// <summary>
- /// 释放联接
- /// </summary>
- public override void Dispose()
- {
- if(udpServer != null)
- udpServer.Close();
- if(thread != null && thread.ThreadState != ThreadState.Stopped)
- {
- if (done.WaitOne(500))
- {
- thread.Abort();
- }
- thread.Abort();
- thread = null;
- }
- base.Dispose();
-
- }
- /// <summary>
- /// 打开联接
- /// </summary>
- public override void Open()
- {
- if (thread != null&&udpServer!=null)
- {
- if (thread.ThreadState == ThreadState.Suspended)
- {
- autoReset.Set();//thread.Resume();
- }
- else if (thread.ThreadState == ThreadState.Unstarted)
- {
- thread.Start();
- }
- }
- else
- {
- IPAddress[] address = Dns.GetHostAddresses(Dns.GetHostName());
- for (int i = 0; i < address.Count(); i++)
- {
- if (address[i].AddressFamily.ToString().ToLower() == "internetwork" && address[i].ToString() == LocalIP)
- {
- udpServer = new UdpClient(new IPEndPoint(IPAddress.Any, Port));
- thread = new Thread(ReceiveThread);
- thread.Start();
- thread1 = new Thread(ReceiveThread2);
- thread1.Start();
- break;
- }
- else if (i == address.Count() - 1)
- {
- Console.WriteLine("UDP中IP地址不存在");
- return;
- }
- }
-
- }
- IsOpen = true;
- }
- }
- }
|