using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Threading; using System.Net.Sockets; using BlackBoxFile; namespace Dispatch { /// /// 网络通信类 /// public class CSNetComm { private static Thread gs_netThread; // 网络线程 private static bool gs_startFlag; // 启动标志位 private static bool gs_pauseFlag; // 暂停标志位 private static IPAddress gs_ipAddr; // IP地址 private static int gs_listenPort; // 监听端口 private static CSNetServer gs_server; private static List gs_nctList; private static ManualResetEvent gs_resumeEvent; private static List gs_netBuffer; private static object netLock = new object(); private static Thread threadNet; /// /// /// /// /// public delegate void MatchedParityHandler(object sender, DataEventArgs e); /// /// /// public static event MatchedParityHandler MatchedParity; private static void OnMatchedParity(object sender, DataEventArgs e) { if (MatchedParity != null) { MatchedParity(sender, e); } } /// /// /// /// public static void OnMatchParity(object o) { MyNetData data = o as MyNetData; Console.ForegroundColor = ConsoleColor.Yellow; //Console.WriteLine("所在线程ID:" + Thread.CurrentThread.ManagedThreadId.ToString() + "类型:" + data.e.type + " " + CHex2String.Byte2HexString(data.e.data, data.e.data.Length)); Console.ResetColor(); OnMatchedParity(data.sender, data.e); Thread.Sleep(500);//加延时是为了避免解析后有过长的操作占用系统资源 } private class MyNetData { /// /// 对象 /// public object sender; /// /// 事务 /// public DataEventArgs e; } /// /// /// public CSNetComm() { gs_startFlag = false; gs_pauseFlag = false; gs_ipAddr = IPAddress.Parse("127.0.0.1"); gs_listenPort = 8899; gs_nctList = new List(); gs_resumeEvent = new ManualResetEvent(false); gs_netBuffer = new List(); threadNet = new Thread(ThreadHandler); threadNet.Start(); } /// /// 初始化 /// /// /// public static void Init(IPAddress ipAddr, int listenPort) { gs_ipAddr = ipAddr; gs_listenPort = listenPort; gs_server = new CSNetServer(gs_ipAddr, gs_listenPort); } /// /// 发送字节数据 /// /// 连接线程ID /// 数据缓冲区 /// 数据长度 public static void SendBytes(int n, byte[] buffer, int length) { //foreach (CSNetConThread nct in gs_nctList) for (int i = 0; i < gs_nctList.Count; i++) { CSNetConThread nct = gs_nctList[i]; nct.SendBytes(buffer, length); } } /// /// 获取线程挂起状态 /// /// public static bool GetPauseStatus() { return gs_pauseFlag; } /// /// 获取服务器开启状态 /// /// public static bool GetStartStatus() { return gs_startFlag; } /// /// 线程暂停 /// public static void Pause() { gs_resumeEvent.Reset(); gs_pauseFlag = true; } /// /// 线程恢复 /// public static void Resume() { gs_resumeEvent.Set(); gs_pauseFlag = true; } /// /// 启动 /// public static void Start(string ipAddr, int listenPort) { gs_ipAddr = IPAddress.Parse(ipAddr); gs_listenPort = listenPort; // 开启网络监听线程 gs_netThread = new Thread(new ThreadStart(ThreadProc)); gs_netThread.Start(); } /// /// 停止 /// public static void Stop() { if (!gs_startFlag) { return; } gs_startFlag = false; while (CSNetConThread.GetConnectedNum() != 0) { Thread.Sleep(10); } gs_server.Stop(); gs_netThread.Abort(); } /// /// 添加网络连接线程实例 /// /// 网络连接线程实例 public static void AddNetConThread(CSNetConThread nct) { gs_nctList.Add(nct); } /// /// 删除网络连接线程实例 /// /// 网络连接线程实例 public static void RemoveNetConThread(CSNetConThread nct) { gs_nctList.Remove(nct); } /// /// /// /// public void RemoveNetThread(int n) { bool flag = false; CSNetConThread delnct = new CSNetConThread(); foreach (CSNetConThread nct in gs_nctList) { if (n == nct.GetID()) { flag = true; delnct = nct; break; } } if (flag) { CSNetConThread.gs_connectedNum--; delnct.CloseClient(); RemoveNetConThread(delnct); } } /// /// 线程过程 /// private static void ThreadProc() { gs_server = new CSNetServer(gs_ipAddr, gs_listenPort); gs_startFlag = gs_server.Start(); if (!gs_startFlag) { return; } while (true) { // 如果线程已被挂起 if (gs_pauseFlag) { //gs_resumeEvent.WaitOne(); } while (!gs_server.Pending()) { Thread.Sleep(1000); // 延时1秒 } /************************************************************************/ /* 利用线程池技术开启新连接 */ /************************************************************************/ CSNetConThread newConThread = new CSNetConThread(); newConThread.SetListener(gs_server.GetListener()); //ThreadPool.QueueUserWorkItem(new WaitCallback(newConThread.ThreadProc)); Thread thread = new Thread(new ThreadStart(newConThread.ThreadProc)); thread.Start(); Pause(); } } /// /// 批量追加网络数据缓存 /// /// 数据缓存 /// 数据长度 public static void AddNetBufferRange(byte[] buffer, int length) { for (int i = 0; i < length; i++) { gs_netBuffer.Add(buffer[i]); } } private static byte[] DataHander(out int type) { type = -1; int framelength = 14; // 帧长度 byte frameHead = 0x10; // 帧头 byte frameTaig = 0x03; byte frameFunc1 = 0x41; byte frameFunc2 = 0x42; byte frameFunc3 = 0x53; byte frameFunc4 = 0x54; if (gs_netBuffer.Count >= framelength) { #region MyRegion if ((gs_netBuffer[0] == frameHead) && (gs_netBuffer[2] == frameFunc1 || gs_netBuffer[2] == frameFunc2 || gs_netBuffer[2] == frameFunc3 || gs_netBuffer[2] == frameFunc4) && (gs_netBuffer[13] == frameTaig)) { byte checkSum = 0x00; for (int i = 0; i < 12; i++) { checkSum ^= gs_netBuffer[i]; } if (checkSum == gs_netBuffer[12]) { byte[] data = new byte[14]; for (int i = 0; i < 14; i++) { data[i] = gs_netBuffer[i]; } lock (netLock) { gs_netBuffer.RemoveRange(0, 14); } type = 2; return data; } else { ArrangeBuffer(gs_netBuffer, frameHead); } } else if ((gs_netBuffer[0] == frameHead) && (gs_netBuffer.Count >= 10) && gs_netBuffer[1] == 0x62)//轮询的解析 { byte checkSum = 0x00; for (int i = 0; i < 8; i++) { checkSum ^= gs_netBuffer[i]; } if (checkSum == gs_netBuffer[8] && frameTaig == gs_netBuffer[9]) { byte[] data = new byte[10]; for (int i = 0; i < 10; i++) { data[i] = gs_netBuffer[i]; } lock (netLock) { gs_netBuffer.RemoveRange(0, 10); } type = 2; return data; } else { ArrangeBuffer(gs_netBuffer, frameHead); } } else { ArrangeBuffer(gs_netBuffer, frameHead); } #endregion } return new byte[1] { 0 }; } static AutoResetEvent done = new AutoResetEvent(true);//在处理数据的时候不允许被打断(只有在线程正常挂起时有效) /// /// /// public void ThreadHandler() { while (true) { //Console.WriteLine("分析线程运行中..."); if (gs_netBuffer.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) { MyNetData data = new MyNetData(); data.sender = this; data.e = e; Thread t = new Thread(OnMatchParity); t.Start(data); } } Thread.Sleep(20); done.Set(); } } /// /// 整理数据缓存表 /// /// 数据缓存表 /// 目标字节 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 (netLock) { bufferList.RemoveRange(0, delBytes); } } catch (Exception ex) { throw ex; } } /// /// 网路连接线程类 /// public class CSNetConThread { /// /// 已建立连接数 /// public static int gs_connectedNum = 0; // private const int gc_bufferSize = 1024; // 缓冲区的大小 private static List gs_netBuffer; // 网络数据缓存 /// /// TCP联接 /// public TcpClient tcpclient; private TcpListener listener; private int id; private int rxBytes; private int txBytes; private byte[] rxBuffer; private byte[] txBuffer; //private bool readFlag; private bool writeFlag; /// /// 默认构造 /// public CSNetConThread() { id = 0; rxBytes = 0; txBytes = 0; //readFlag = false; writeFlag = false; rxBuffer = new byte[gc_bufferSize]; txBuffer = new byte[gc_bufferSize]; gs_netBuffer = new List(); tcpclient = new TcpClient(); } /// /// 获取连接线程ID /// /// 连接线程ID public int GetID() { return this.id; } private int GenerateID() { int id = 0; id = gs_connectedNum; return id; } /// /// 关闭所有联接 /// public void CloseClient() { IPEndPoint iep = (IPEndPoint)tcpclient.Client.RemoteEndPoint; tcpclient.Close(); } /// /// 获取联接数量 /// /// public static int GetConnectedNum() { return gs_connectedNum; } /// /// 设置监听器 /// /// TCP监听器 public void SetListener(TcpListener tl) { this.listener = tl; } /// /// 发送字节数组 /// /// /// public void SendBytes(byte[] buffer, int length) { while (writeFlag) { Thread.Sleep(10); } txBuffer = buffer; txBytes = length; writeFlag = true; } /// /// 线程执行过程 /// public void ThreadProc()//object state { bool acceptFlag = true; TcpClient client = new TcpClient(); try { client = listener.AcceptTcpClient(); } catch (SocketException ex) { string str = ""; string strDateInfo = "出现的异常:" + DateTime.Now.ToString() + "\r\n"; if (ex != null) { str = string.Format(strDateInfo + "异常类型:{0}\r\n异常消息:{1}\r\n异常信息:{2}\r\n", ex.GetType().Name, ex.Message, ex.StackTrace); } else { str = string.Format("应用程序线程错误:{0}", ex); } Dispatch.Dispatcher.gs_blackBoxFile.WriteFile(900, str); //Program.writeLog(str); // 此处需要发送异常消息 acceptFlag = false; } tcpclient = client; IPEndPoint iep1 = (IPEndPoint)tcpclient.Client.RemoteEndPoint; ////////////////////////////////////////////////// gs_connectedNum++; //////////////////////////////////////////////////// //this.id = GenerateID(); CSNetComm.AddNetConThread(this); // 等待网络通信监听线程挂起,然后恢复该线程运行 //while (!CSNetComm.GetPauseStatus()) //{} CSNetComm.Resume(); #region 连接成功 if (acceptFlag) { NetworkStream ns = client.GetStream(); // 发送已连接事件 IPEndPoint iep = (IPEndPoint)client.Client.RemoteEndPoint; string ipStr = iep.Address.ToString(); string portStr = "[" + iep.Port.ToString() + "]"; string msgText = "Client" + this.id.ToString() + "\t\t" + ipStr + "\t" + portStr; //SendMessage(MessgeType.EVENT_CLIENT_CONNECTED, msgText, 0, 0); //发送欢迎语 //string welcomeStr = "Welcome to CASUN CMS Server!"; //rxBuffer = Encoding.ASCII.GetBytes(welcomeStr); //ns.Write(rxBuffer, 0, rxBuffer.Length); /************************************************************************/ /* 数据发送操作 */ /************************************************************************/ #region while (true) { // 查询通信监听服务器是否打开 if (!CSNetComm.GetStartStatus()) { break; } if (client.Connected == false) { break; } // 检测当前套接字1ms是否为可读 if (client.Client.Poll(1000, SelectMode.SelectRead)) { try { rxBytes = ns.Read(rxBuffer, 0, rxBuffer.Length); } catch (System.Exception ex) { Dispatch.Dispatcher.gs_blackBoxFile.WriteFile(900, ex.Message); } if (rxBytes > 0) { this.id = rxBuffer[2]; } //如果连接已关闭 if (rxBytes == 0) { msgText = "Client" + this.id.ToString() + "\t\t" + ipStr + "\t" + portStr; //SendMessage(MessgeType.EVENT_CLIENT_DISCONNECTED, msgText, 0, 0); break; } else { string str = null; for (int i = 0; i < rxBytes; i++) str += Convert.ToString(rxBuffer[i], 16).ToString() + " "; //writeLog1(DateTime.Now.ToString() + str); CSNetComm.AddNetBufferRange(rxBuffer, rxBytes); //发送工作数据接收消息 //SendMessage(MessgeType.EVENT_WORK_DATA_RECEIVED, "", recvNum, this.id); } } if (client.Connected == false) { break; } // 检测当前套接字1ms内是否为可写 if (client.Client.Poll(1000, SelectMode.SelectWrite)) { if (writeFlag) { try { ns.Write(txBuffer, 0, txBytes); } catch (Exception ex) { Dispatch.Dispatcher.gs_blackBoxFile.WriteFile(900, ex.Message); } writeFlag = false; Encoding e = Encoding.GetEncoding(936); msgText = e.GetString(txBuffer, 0, txBytes); //SendMessage(MessgeType.EVENT_DATA_SENDED, msgText, sendNum, this.id); } } }// end of while #endregion ns.Close(); }// end of if ( acceptFlag ) #endregion // 接入线程执行完毕需要的相关操作 client.Close(); gs_connectedNum--; CSNetComm.RemoveNetConThread(this); } } } /// /// 网络服务器类 /// internal class CSNetServer { // 成员变量 private TcpListener listener; // 成员函数 /// /// 默认构造 /// public CSNetServer() { string ipStr = "127.0.0.1"; int port = 9808; this.listener = new TcpListener(IPAddress.Parse(ipStr), port); } /// /// 重载构造 /// /// 地址 /// 端口 public CSNetServer(IPAddress addr, int port) { this.listener = new TcpListener(addr, port); } public bool Pending() { try { return listener.Pending(); } catch (System.Exception ex) { //需要向控制线程传递ex.Message Dispatch.Dispatcher.gs_blackBoxFile.WriteFile(900, ex.Message); return false; } } public bool Start() { try { listener.Start(); } catch (System.Exception ex) { //需要向控制线程传递ex.Message Dispatch.Dispatcher.gs_blackBoxFile.WriteFile(900, ex.Message); return false; } return true; } public bool Stop() { try { listener.Stop(); } catch (System.Exception ex) { //需要向控制线程传递ex.Message Dispatch.Dispatcher.gs_blackBoxFile.WriteFile(900, ex.Message); return false; } return true; } public TcpListener GetListener() { return (this.listener); } public void SetListener(IPAddress addr, int port) { //this.listener. ; } } }