/******************************
* 说明:异步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;
}
}
}