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
{
///
/// UDP通信类
///
public class UDPCommunication:CommunicationBase
{
///
/// 本地IP
///
private string localIP;
///
/// 接收字节缓存
///
public List receiveBuffer = new List(2046);
///
/// 端口锁定对象
///
private static object portLock = new object();
///
/// 信息检效处理操作
///
///
///
public delegate void MatchedParityHandler(object sender, DataEventArgs e);
///
/// 信息检效事件
///
public event MatchedParityHandler MatchedParity;
///
/// 日志记录
///
internal static BlackBoxFile.CBlackBoxFile gs_blackBoxFile;
///
/// 接收IP列表
///
List recieveIPs = new List();
AutoResetEvent autoReset = new AutoResetEvent(false);
///
/// 本地IP获取
///
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;
///
/// 端口
///
public int Port
{
get
{
if (port <= 0)
return 10000;
return port;
}
set { port = value; }
}
private int scanTime;
///
/// 扫描时间
///
public int ScanTime
{
get
{
if (scanTime <= 0)
return 10;
return scanTime;
}
set { scanTime = value; }
}
///
/// 对象标识
///
///
public override object GetTag()
{
return this;
}
private UdpClient udpServer;
private Thread thread;
private Thread thread1;
///
/// UDP通信
///
///
///
///
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);
///
/// 字符数据转十六进制字符串
///
///
///
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();
}
///
/// 接收线程
///
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();
}
}
}
///
/// 第二接收线程
///
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);
}
}
///
/// 读取数据
///
public event EventHandler ReadingData;
///
/// 写入数据
///
public event EventHandler WritingData;
void OnReadingData(EventArgs e)
{
if (ReadingData != null)
{
ReadingData(this, e);
}
}
void OnWritingData(EventArgs e)
{
if (WritingData != null)
{
WritingData(this, e);
}
}
///
/// 事件监听处理
///
///
///
public void OnMatchedParity(object sender, DataEventArgs e)
{
if (MatchedParity != null)
{
MatchedParity(sender, e);
}
}
///
/// 事件监听处理
///
///
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;
}
///
/// 异或操作
///
///
///
///
///
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;
}
///
/// 整理数据缓存表
///
/// 数据缓存表
/// 目标字节
private static void ArrangeBuffer(List 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;
}
}
///
/// 数据操作
///
///
///
private byte[] DataHander(out int type)
{
type = -1;
int framelength = 10; // 帧长度
byte frameHead = 0x10; // 帧头
byte frameTaig = 0x03;
List frameFuncList = new List { 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 };
}
///
/// 发送数据
///
///
///
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);
}
}
}
///
/// 关闭联接
///
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;
}
///
/// 释放联接
///
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();
}
///
/// 打开联接
///
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;
}
}
}