123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749 |
- 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
- {
- /// <summary>
- /// 网络通信类
- /// </summary>
- 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<CSNetConThread> gs_nctList;
- private static ManualResetEvent gs_resumeEvent;
- private static List<byte> gs_netBuffer;
- private static object netLock = new object();
- private static Thread threadNet;
- /// <summary>
- ///
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- public delegate void MatchedParityHandler(object sender, DataEventArgs e);
- /// <summary>
- ///
- /// </summary>
- public static event MatchedParityHandler MatchedParity;
- private static void OnMatchedParity(object sender, DataEventArgs e)
- {
- if (MatchedParity != null)
- {
- MatchedParity(sender, e);
- }
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="o"></param>
- 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
- {
- /// <summary>
- /// 对象
- /// </summary>
- public object sender;
- /// <summary>
- /// 事务
- /// </summary>
- public DataEventArgs e;
- }
- /// <summary>
- ///
- /// </summary>
- public CSNetComm()
- {
- gs_startFlag = false;
- gs_pauseFlag = false;
- gs_ipAddr = IPAddress.Parse("127.0.0.1");
- gs_listenPort = 8899;
- gs_nctList = new List<CSNetConThread>();
- gs_resumeEvent = new ManualResetEvent(false);
- gs_netBuffer = new List<byte>();
- threadNet = new Thread(ThreadHandler);
- threadNet.Start();
- }
- /// <summary>
- /// 初始化
- /// </summary>
- /// <param name="ipAddr"></param>
- /// <param name="listenPort"></param>
- public static void Init(IPAddress ipAddr, int listenPort)
- {
- gs_ipAddr = ipAddr;
- gs_listenPort = listenPort;
- gs_server = new CSNetServer(gs_ipAddr, gs_listenPort);
- }
- /// <summary>
- /// 发送字节数据
- /// </summary>
- /// <param name="n">连接线程ID</param>
- /// <param name="buffer">数据缓冲区</param>
- /// <param name="length">数据长度</param>
- 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);
- }
- }
- /// <summary>
- /// 获取线程挂起状态
- /// </summary>
- /// <returns></returns>
- public static bool GetPauseStatus()
- {
- return gs_pauseFlag;
- }
- /// <summary>
- /// 获取服务器开启状态
- /// </summary>
- /// <returns></returns>
- public static bool GetStartStatus()
- {
- return gs_startFlag;
- }
- /// <summary>
- /// 线程暂停
- /// </summary>
- public static void Pause()
- {
- gs_resumeEvent.Reset();
- gs_pauseFlag = true;
- }
- /// <summary>
- /// 线程恢复
- /// </summary>
- public static void Resume()
- {
- gs_resumeEvent.Set();
- gs_pauseFlag = true;
- }
- /// <summary>
- /// 启动
- /// </summary>
- 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();
- }
- /// <summary>
- /// 停止
- /// </summary>
- public static void Stop()
- {
- if (!gs_startFlag)
- {
- return;
- }
- gs_startFlag = false;
- while (CSNetConThread.GetConnectedNum() != 0)
- {
- Thread.Sleep(10);
- }
- gs_server.Stop();
- gs_netThread.Abort();
- }
- /// <summary>
- /// 添加网络连接线程实例
- /// </summary>
- /// <param name="nct">网络连接线程实例</param>
- public static void AddNetConThread(CSNetConThread nct)
- {
- gs_nctList.Add(nct);
- }
- /// <summary>
- /// 删除网络连接线程实例
- /// </summary>
- /// <param name="nct">网络连接线程实例</param>
- public static void RemoveNetConThread(CSNetConThread nct)
- {
- gs_nctList.Remove(nct);
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="n"></param>
- 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);
- }
- }
- /// <summary>
- /// 线程过程
- /// </summary>
- 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();
- }
- }
- /// <summary>
- /// 批量追加网络数据缓存
- /// </summary>
- /// <param name="buffer">数据缓存</param>
- /// <param name="length">数据长度</param>
- 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);//在处理数据的时候不允许被打断(只有在线程正常挂起时有效)
- /// <summary>
- ///
- /// </summary>
- 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();
- }
- }
- /// <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 (netLock)
- {
- bufferList.RemoveRange(0, delBytes);
- }
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- /// <summary>
- /// 网路连接线程类
- /// </summary>
- public class CSNetConThread
- {
- /// <summary>
- /// 已建立连接数
- /// </summary>
- public static int gs_connectedNum = 0; //
- private const int gc_bufferSize = 1024; // 缓冲区的大小
- private static List<byte> gs_netBuffer; // 网络数据缓存
- /// <summary>
- /// TCP联接
- /// </summary>
- 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;
- /// <summary>
- /// 默认构造
- /// </summary>
- 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<byte>();
- tcpclient = new TcpClient();
- }
- /// <summary>
- /// 获取连接线程ID
- /// </summary>
- /// <returns>连接线程ID</returns>
- public int GetID()
- {
- return this.id;
- }
- private int GenerateID()
- {
- int id = 0;
- id = gs_connectedNum;
- return id;
- }
- /// <summary>
- /// 关闭所有联接
- /// </summary>
- public void CloseClient()
- {
- IPEndPoint iep = (IPEndPoint)tcpclient.Client.RemoteEndPoint;
- tcpclient.Close();
- }
- /// <summary>
- /// 获取联接数量
- /// </summary>
- /// <returns></returns>
- public static int GetConnectedNum()
- {
- return gs_connectedNum;
- }
- /// <summary>
- /// 设置监听器
- /// </summary>
- /// <param name="tl">TCP监听器</param>
- public void SetListener(TcpListener tl)
- {
- this.listener = tl;
- }
- /// <summary>
- /// 发送字节数组
- /// </summary>
- /// <param name="buffer"></param>
- /// <param name="length"></param>
- public void SendBytes(byte[] buffer, int length)
- {
- while (writeFlag)
- {
- Thread.Sleep(10);
- }
- txBuffer = buffer;
- txBytes = length;
- writeFlag = true;
- }
- /// <summary>
- /// 线程执行过程
- /// </summary>
- 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);
- }
- }
- }
- /// <summary>
- /// 网络服务器类
- /// </summary>
- internal class CSNetServer
- {
- // 成员变量
- private TcpListener listener;
- // 成员函数
- /// <summary>
- /// 默认构造
- /// </summary>
- public CSNetServer()
- {
- string ipStr = "127.0.0.1";
- int port = 9808;
- this.listener = new TcpListener(IPAddress.Parse(ipStr), port);
- }
- /// <summary>
- /// 重载构造
- /// </summary>
- /// <param name="addr">地址</param>
- /// <param name="port">端口</param>
- 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. ;
- }
- }
- }
|