/****************************** * 说明:异步Socket调用对象,所有的协议处理都从本类继承 * 创建人:龚宇超 * 创建日期:2018-01-23 * 修改人: * 修改日期: * 修改备注: * 版本:1.0.0.0 ******************************/ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Sockets; using System.Threading; namespace Lskj.SocketService { /// /// 异步Socket调用对象,所有的协议处理都从本类继承 /// public class AsyncSocketInvokeElement { private bool _netByteOrder; /// /// 标识是否有发送异步事件 /// protected bool _sendAsync; /// /// 连接时间 /// protected DateTime _connectDT; /// /// The _active dt /// protected DateTime _activeDT; /// /// 服务对象 /// protected AsyncSocketServer _asyncSocketServer; /// /// 连接对象 /// protected AsyncSocketUserToken _asyncSocketUserToken; /// /// 协议解析器,用来解析客户端接收到的命令 /// protected IncomingDataParser _incomingDataParser; /// /// 协议组装器,用来组织服务端返回的命令 /// protected OutgoingDataAssembler _outgoingDataAssembler; /// /// 长度是否使用网络字节顺序 /// /// true if [net byte order]; otherwise, false. public bool NetByteOrder { get { return _netByteOrder; } set { _netByteOrder = value; } } /// /// 连接时间 /// /// The connect dt. public DateTime ConnectDT { get { return _connectDT; } } public DateTime ActiveDT { get { return _activeDT; } } /// /// 连接对象 /// /// The asynchronous socket user token. public AsyncSocketUserToken AsyncSocketUserToken { get { return _asyncSocketUserToken; } } public AsyncSocketInvokeElement(AsyncSocketServer asyncSocketServer, AsyncSocketUserToken asyncSocketUserToken) { _asyncSocketServer = asyncSocketServer; _asyncSocketUserToken = asyncSocketUserToken; _netByteOrder = false; _sendAsync = false; _incomingDataParser = new IncomingDataParser(); _outgoingDataAssembler = new OutgoingDataAssembler(); _connectDT = DateTime.UtcNow; _activeDT = DateTime.UtcNow; } /// /// 说明:发送结果 /// 创建人:龚宇超 /// 创建日期:2018-01-24 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// true if XXXX, false otherwise. public bool DoSendResult() { string commandText = _outgoingDataAssembler.GetProtocolText(); byte[] bufferUTF8 = Encoding.UTF8.GetBytes(commandText); int totalLength = sizeof(int) + bufferUTF8.Length; //获取总大小 AsyncSendBufferManager asyncSendBufferManager = _asyncSocketUserToken.SendBuffer; asyncSendBufferManager.StartPacket(); asyncSendBufferManager.DynamicBufferManager.WriteInt(totalLength, false); //写入总大小 asyncSendBufferManager.DynamicBufferManager.WriteInt(bufferUTF8.Length, false); //写入命令大小 asyncSendBufferManager.DynamicBufferManager.WriteBuffer(bufferUTF8); //写入命令内容 asyncSendBufferManager.EndPacket(); bool result = true; if (!_sendAsync) { int packetOffset = 0; int packetCount = 0; if (asyncSendBufferManager.GetFirstPacket(ref packetOffset, ref packetCount)) { _sendAsync = true; result = _asyncSocketServer.SendAsyncEvent(_asyncSocketUserToken.ConnectSocket, _asyncSocketUserToken.SendEventArgs, asyncSendBufferManager.DynamicBufferManager.Buffer, packetOffset, packetCount); } } return result; } /// /// 说明:发送结果 /// 创建人:龚宇超 /// 创建日期:2018-01-24 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// The buffer. /// The offset. /// The count. /// true if XXXX, false otherwise. public bool DoSendResult(byte[] buffer, int offset, int count) { string commandText = _outgoingDataAssembler.GetProtocolText(); byte[] bufferUTF8 = Encoding.UTF8.GetBytes(commandText); int totalLength = sizeof(int) + bufferUTF8.Length + count; //获取总大小 AsyncSendBufferManager asyncSendBufferManager = _asyncSocketUserToken.SendBuffer; asyncSendBufferManager.StartPacket(); asyncSendBufferManager.DynamicBufferManager.WriteInt(totalLength, false); //写入总大小 asyncSendBufferManager.DynamicBufferManager.WriteInt(bufferUTF8.Length, false); //写入命令大小 asyncSendBufferManager.DynamicBufferManager.WriteBuffer(bufferUTF8); //写入命令内容 asyncSendBufferManager.DynamicBufferManager.WriteBuffer(buffer, offset, count); //写入二进制数据 asyncSendBufferManager.EndPacket(); bool result = true; if (!_sendAsync) { int packetOffset = 0; int packetCount = 0; if (asyncSendBufferManager.GetFirstPacket(ref packetOffset, ref packetCount)) { _sendAsync = true; result = _asyncSocketServer.SendAsyncEvent(_asyncSocketUserToken.ConnectSocket, _asyncSocketUserToken.SendEventArgs, asyncSendBufferManager.DynamicBufferManager.Buffer, packetOffset, packetCount); } } return result; } /// /// 说明:不是按包格式下发一个内存块,用于日志这类下发协议 /// 创建人:龚宇超 /// 创建日期:2018-01-24 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// The buffer. /// The offset. /// The count. /// true if XXXX, false otherwise. public bool DoSendBuffer(byte[] buffer, int offset, int count) { AsyncSendBufferManager asyncSendBufferManager = _asyncSocketUserToken.SendBuffer; asyncSendBufferManager.StartPacket(); asyncSendBufferManager.DynamicBufferManager.WriteBuffer(buffer, offset, count); asyncSendBufferManager.EndPacket(); bool result = true; if (!_sendAsync) { int packetOffset = 0; int packetCount = 0; if (asyncSendBufferManager.GetFirstPacket(ref packetOffset, ref packetCount)) { _sendAsync = true; result = _asyncSocketServer.SendAsyncEvent(_asyncSocketUserToken.ConnectSocket, _asyncSocketUserToken.SendEventArgs, asyncSendBufferManager.DynamicBufferManager.Buffer, packetOffset, packetCount); } } return result; } public virtual void Close() { } /// /// 说明:接收异步事件返回的数据,用于对数据进行缓存和分包 /// 创建人:龚宇超 /// 创建日期:2018-01-24 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// The buffer. /// The offset. /// The count. /// true if XXXX, false otherwise. public virtual bool ProcessReceive(byte[] buffer, int offset, int count) { _activeDT = DateTime.UtcNow; DynamicBufferManager receiveBuffer = _asyncSocketUserToken.ReceiveBuffer; receiveBuffer.WriteBuffer(buffer, offset, count); bool result = true; while (receiveBuffer.DataCount > sizeof(int)) { // 按照长度分包 int packetLength = BitConverter.ToInt32(receiveBuffer.Buffer, 0); //获取包长度 if (NetByteOrder) packetLength = System.Net.IPAddress.NetworkToHostOrder(packetLength); //把网络字节顺序转为本地字节顺序 if ((packetLength > 10 * 1024 * 1024) | (receiveBuffer.DataCount > 10 * 1024 * 1024)) //最大Buffer异常保护 return false; if ((receiveBuffer.DataCount - sizeof(int)) >= packetLength) //收到的数据达到包长度 { result = ProcessPacket(receiveBuffer.Buffer, sizeof(int), packetLength); if (result) receiveBuffer.Clear(packetLength + sizeof(int)); //从缓存中清理 else return result; } else { return true; } } return true; } /// /// 说明:处理分完包后的数据,把命令和数据分开,并对命令进行解析 /// 创建人:龚宇超 /// 创建日期:2018-01-24 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// The buffer. /// The offset. /// The count. /// true if XXXX, false otherwise. public virtual bool ProcessPacket(byte[] buffer, int offset, int count) { if (count < sizeof(int)) return false; int commandLen = BitConverter.ToInt32(buffer, offset); //取出命令长度 string tmpStr = Encoding.UTF8.GetString(buffer, offset + sizeof(int), commandLen); if (!_incomingDataParser.DecodeProtocolText(tmpStr)) //解析命令 return false; return ProcessCommand(buffer, offset + sizeof(int) + commandLen, count - sizeof(int) - commandLen); //处理命令 } /// /// 说明:处理具体命令,子类从这个方法继承,buffer是收到的数据 /// 创建人:龚宇超 /// 创建日期:2018-01-24 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// The buffer. /// The offset. /// The count. /// true if XXXX, false otherwise. public virtual bool ProcessCommand(byte[] buffer, int offset, int count) { return true; } /// /// 说明:发送完成命令 /// 创建人:龚宇超 /// 创建日期:2018-01-24 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// true if XXXX, false otherwise. public virtual bool SendCompleted() { _activeDT = DateTime.UtcNow; _sendAsync = false; AsyncSendBufferManager asyncSendBufferManager = _asyncSocketUserToken.SendBuffer; asyncSendBufferManager.ClearFirstPacket(); //清除已发送的包 int offset = 0; int count = 0; if (asyncSendBufferManager.GetFirstPacket(ref offset, ref count)) { _sendAsync = true; return _asyncSocketServer.SendAsyncEvent(_asyncSocketUserToken.ConnectSocket, _asyncSocketUserToken.SendEventArgs, asyncSendBufferManager.DynamicBufferManager.Buffer, offset, count); } else return SendCallback(); } /// /// 说明:发送回调函数,用于连续下发数据 /// 创建人:龚宇超 /// 创建日期:2018-01-24 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// true if XXXX, false otherwise. public virtual bool SendCallback() { return true; } } }