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. ;
}
}
}