ab56a9bcf7
SVN-Revision: r240
334 lines
14 KiB
C#
334 lines
14 KiB
C#
/******************************
|
|
* 说明:异步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
|
|
{
|
|
/// <summary>
|
|
/// 异步Socket调用对象,所有的协议处理都从本类继承
|
|
/// </summary>
|
|
public class AsyncSocketInvokeElement
|
|
{
|
|
private bool _netByteOrder;
|
|
|
|
/// <summary>
|
|
/// 标识是否有发送异步事件
|
|
/// </summary>
|
|
protected bool _sendAsync;
|
|
/// <summary>
|
|
/// 连接时间
|
|
/// </summary>
|
|
protected DateTime _connectDT;
|
|
/// <summary>
|
|
/// The _active dt
|
|
/// </summary>
|
|
protected DateTime _activeDT;
|
|
/// <summary>
|
|
/// 服务对象
|
|
/// </summary>
|
|
protected AsyncSocketServer _asyncSocketServer;
|
|
/// <summary>
|
|
/// 连接对象
|
|
/// </summary>
|
|
protected AsyncSocketUserToken _asyncSocketUserToken;
|
|
/// <summary>
|
|
/// 协议解析器,用来解析客户端接收到的命令
|
|
/// </summary>
|
|
protected IncomingDataParser _incomingDataParser;
|
|
/// <summary>
|
|
/// 协议组装器,用来组织服务端返回的命令
|
|
/// </summary>
|
|
protected OutgoingDataAssembler _outgoingDataAssembler;
|
|
|
|
/// <summary>
|
|
/// 长度是否使用网络字节顺序
|
|
/// </summary>
|
|
/// <value><c>true</c> if [net byte order]; otherwise, <c>false</c>.</value>
|
|
public bool NetByteOrder
|
|
{
|
|
get { return _netByteOrder; }
|
|
set { _netByteOrder = value; }
|
|
}
|
|
/// <summary>
|
|
/// 连接时间
|
|
/// </summary>
|
|
/// <value>The connect dt.</value>
|
|
public DateTime ConnectDT { get { return _connectDT; } }
|
|
public DateTime ActiveDT { get { return _activeDT; } }
|
|
/// <summary>
|
|
/// 连接对象
|
|
/// </summary>
|
|
/// <value>The asynchronous socket user token.</value>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>说明:发送结果</para>
|
|
/// <para>创建人:龚宇超</para>
|
|
/// <para>创建日期:2018-01-24 </para>
|
|
/// <para>修改人:</para>
|
|
/// <para>修改日期:</para>
|
|
/// <para>修改备注:</para>
|
|
/// <para>版本:1.0</para>
|
|
/// </summary>
|
|
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
|
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;
|
|
}
|
|
/// <summary>
|
|
/// <para>说明:发送结果</para>
|
|
/// <para>创建人:龚宇超</para>
|
|
/// <para>创建日期:2018-01-24 </para>
|
|
/// <para>修改人:</para>
|
|
/// <para>修改日期:</para>
|
|
/// <para>修改备注:</para>
|
|
/// <para>版本:1.0</para>
|
|
/// </summary>
|
|
/// <param name="buffer">The buffer.</param>
|
|
/// <param name="offset">The offset.</param>
|
|
/// <param name="count">The count.</param>
|
|
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
|
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;
|
|
}
|
|
/// <summary>
|
|
/// <para>说明:不是按包格式下发一个内存块,用于日志这类下发协议</para>
|
|
/// <para>创建人:龚宇超</para>
|
|
/// <para>创建日期:2018-01-24 </para>
|
|
/// <para>修改人:</para>
|
|
/// <para>修改日期:</para>
|
|
/// <para>修改备注:</para>
|
|
/// <para>版本:1.0</para>
|
|
/// </summary>
|
|
/// <param name="buffer">The buffer.</param>
|
|
/// <param name="offset">The offset.</param>
|
|
/// <param name="count">The count.</param>
|
|
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
|
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()
|
|
{
|
|
}
|
|
/// <summary>
|
|
/// <para>说明:接收异步事件返回的数据,用于对数据进行缓存和分包</para>
|
|
/// <para>创建人:龚宇超</para>
|
|
/// <para>创建日期:2018-01-24 </para>
|
|
/// <para>修改人:</para>
|
|
/// <para>修改日期:</para>
|
|
/// <para>修改备注:</para>
|
|
/// <para>版本:1.0</para>
|
|
/// </summary>
|
|
/// <param name="buffer">The buffer.</param>
|
|
/// <param name="offset">The offset.</param>
|
|
/// <param name="count">The count.</param>
|
|
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
|
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;
|
|
}
|
|
/// <summary>
|
|
/// <para>说明:处理分完包后的数据,把命令和数据分开,并对命令进行解析</para>
|
|
/// <para>创建人:龚宇超</para>
|
|
/// <para>创建日期:2018-01-24 </para>
|
|
/// <para>修改人:</para>
|
|
/// <para>修改日期:</para>
|
|
/// <para>修改备注:</para>
|
|
/// <para>版本:1.0</para>
|
|
/// </summary>
|
|
/// <param name="buffer">The buffer.</param>
|
|
/// <param name="offset">The offset.</param>
|
|
/// <param name="count">The count.</param>
|
|
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
|
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); //处理命令
|
|
}
|
|
/// <summary>
|
|
/// <para>说明:处理具体命令,子类从这个方法继承,buffer是收到的数据</para>
|
|
/// <para>创建人:龚宇超</para>
|
|
/// <para>创建日期:2018-01-24 </para>
|
|
/// <para>修改人:</para>
|
|
/// <para>修改日期:</para>
|
|
/// <para>修改备注:</para>
|
|
/// <para>版本:1.0</para>
|
|
/// </summary>
|
|
/// <param name="buffer">The buffer.</param>
|
|
/// <param name="offset">The offset.</param>
|
|
/// <param name="count">The count.</param>
|
|
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
|
public virtual bool ProcessCommand(byte[] buffer, int offset, int count)
|
|
{
|
|
return true;
|
|
}
|
|
/// <summary>
|
|
/// <para>说明:发送完成命令</para>
|
|
/// <para>创建人:龚宇超</para>
|
|
/// <para>创建日期:2018-01-24 </para>
|
|
/// <para>修改人:</para>
|
|
/// <para>修改日期:</para>
|
|
/// <para>修改备注:</para>
|
|
/// <para>版本:1.0</para>
|
|
/// </summary>
|
|
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
|
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();
|
|
}
|
|
/// <summary>
|
|
/// <para>说明:发送回调函数,用于连续下发数据</para>
|
|
/// <para>创建人:龚宇超</para>
|
|
/// <para>创建日期:2018-01-24 </para>
|
|
/// <para>修改人:</para>
|
|
/// <para>修改日期:</para>
|
|
/// <para>修改备注:</para>
|
|
/// <para>版本:1.0</para>
|
|
/// </summary>
|
|
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
|
public virtual bool SendCallback()
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
} |