ab56a9bcf7
SVN-Revision: r240
242 lines
9.8 KiB
C#
242 lines
9.8 KiB
C#
/******************************
|
|
* 说明:Socket传输基类
|
|
* 创建人:龚宇超
|
|
* 创建日期:2018-01-23
|
|
* 修改人:
|
|
* 修改日期:
|
|
* 修改备注:
|
|
* 版本:1.0.0.0
|
|
******************************/
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Net.Sockets;
|
|
using Lskj.SocketService;
|
|
|
|
namespace Lskj.SocketClient
|
|
{
|
|
/// <summary>
|
|
/// 异步Socket调用对象,所有的协议处理都从本类继承
|
|
/// </summary>
|
|
public class SyncSocketInvokeElement
|
|
{
|
|
private bool _netByteOrder;
|
|
/// <summary>
|
|
/// TCP客户端
|
|
/// </summary>
|
|
protected TcpClient _tcpClient;
|
|
/// <summary>
|
|
/// 服务器地址
|
|
/// </summary>
|
|
protected string _host;
|
|
/// <summary>
|
|
/// 端口
|
|
/// </summary>
|
|
protected int _port;
|
|
/// <summary>
|
|
/// 传输标识
|
|
/// </summary>
|
|
protected ProtocolFlag _protocolFlag;
|
|
/// <summary>
|
|
/// 传输时间设置
|
|
/// </summary>
|
|
/// <value>The socket time out ms.</value>
|
|
protected int SocketTimeOutMS
|
|
{
|
|
get
|
|
{
|
|
return _tcpClient.SendTimeout;
|
|
}
|
|
set
|
|
{
|
|
_tcpClient.SendTimeout = value;
|
|
_tcpClient.ReceiveTimeout = value;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 协议组装器,用来组装往外发送的命令
|
|
/// </summary>
|
|
protected OutgoingDataAssembler _outgoingDataAssembler;
|
|
/// <summary>
|
|
/// 接收数据的缓存
|
|
/// </summary>
|
|
protected DynamicBufferManager _recvBuffer;
|
|
/// <summary>
|
|
/// 收到数据的解析器,用于解析返回的内容
|
|
/// </summary>
|
|
protected IncomingDataParser _incomingDataParser;
|
|
/// <summary>
|
|
/// 发送数据的缓存,统一写到内存中,调用一次发送
|
|
/// </summary>
|
|
protected DynamicBufferManager _sendBuffer;
|
|
/// <summary>
|
|
/// 长度是否使用网络字节顺序
|
|
/// </summary>
|
|
/// <value><c>true</c> if [net byte order]; otherwise, <c>false</c>.</value>
|
|
public bool NetByteOrder
|
|
{
|
|
get { return _netByteOrder; }
|
|
set { _netByteOrder = value; }
|
|
}
|
|
|
|
public SyncSocketInvokeElement()
|
|
{
|
|
_tcpClient = new TcpClient();
|
|
_tcpClient.Client.Blocking = true; //使用阻塞模式,即同步模式
|
|
_protocolFlag = ProtocolFlag.None;
|
|
SocketTimeOutMS = ProtocolConst.SocketTimeOutMS;
|
|
_outgoingDataAssembler = new OutgoingDataAssembler();
|
|
_recvBuffer = new DynamicBufferManager(ProtocolConst.ReceiveBufferSize);
|
|
_incomingDataParser = new IncomingDataParser();
|
|
_sendBuffer = new DynamicBufferManager(ProtocolConst.ReceiveBufferSize);
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>说明:连接Socket服务器</para>
|
|
/// <para>创建人:龚宇超</para>
|
|
/// <para>创建日期:2018-01-24 </para>
|
|
/// <para>修改人:</para>
|
|
/// <para>修改日期:</para>
|
|
/// <para>修改备注:</para>
|
|
/// <para>版本:1.0</para>
|
|
/// </summary>
|
|
/// <param name="host">The host.</param>
|
|
/// <param name="port">The port.</param>
|
|
public void Connect(string host, int port)
|
|
{
|
|
_tcpClient.Connect(host, port);
|
|
byte[] socketFlag = new byte[1];
|
|
socketFlag[0] = (byte)_protocolFlag;
|
|
_tcpClient.Client.Send(socketFlag, SocketFlags.None); //发送标识
|
|
_host = host;
|
|
_port = port;
|
|
}
|
|
/// <summary>
|
|
/// <para>说明:关闭Socket连接</para>
|
|
/// <para>创建人:龚宇超</para>
|
|
/// <para>创建日期:2018-01-24 </para>
|
|
/// <para>修改人:</para>
|
|
/// <para>修改日期:</para>
|
|
/// <para>修改备注:</para>
|
|
/// <para>版本:1.0</para>
|
|
/// </summary>
|
|
public void Disconnect()
|
|
{
|
|
_tcpClient.Close();
|
|
_tcpClient = new TcpClient();
|
|
//_tcpClient.Client.
|
|
}
|
|
/// <summary>
|
|
/// <para>说明:发送命令</para>
|
|
/// <para>创建人:龚宇超</para>
|
|
/// <para>创建日期:2018-01-24 </para>
|
|
/// <para>修改人:</para>
|
|
/// <para>修改日期:</para>
|
|
/// <para>修改备注:</para>
|
|
/// <para>版本:1.0</para>
|
|
/// </summary>
|
|
public void SendCommand()
|
|
{
|
|
string commandText = _outgoingDataAssembler.GetProtocolText();
|
|
byte[] bufferUTF8 = Encoding.UTF8.GetBytes(commandText);
|
|
int totalLength = sizeof(int) + bufferUTF8.Length; //获取总大小
|
|
_sendBuffer.Clear();
|
|
_sendBuffer.WriteInt(totalLength, false); //写入总大小
|
|
_sendBuffer.WriteInt(bufferUTF8.Length, false); //写入命令大小
|
|
_sendBuffer.WriteBuffer(bufferUTF8); //写入命令内容
|
|
_tcpClient.Client.Send(_sendBuffer.Buffer, 0, _sendBuffer.DataCount, SocketFlags.None); //使用阻塞模式,Socket会一次发送完所有数据后才返回
|
|
}
|
|
/// <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>
|
|
public void SendCommand(byte[] buffer, int offset, int count)
|
|
{
|
|
string commandText = _outgoingDataAssembler.GetProtocolText();
|
|
byte[] bufferUTF8 = Encoding.UTF8.GetBytes(commandText);
|
|
int totalLength = sizeof(int) + bufferUTF8.Length + count; //获取总大小
|
|
_sendBuffer.Clear();
|
|
_sendBuffer.WriteInt(totalLength, false); //写入总大小
|
|
_sendBuffer.WriteInt(bufferUTF8.Length, false); //写入命令大小
|
|
_sendBuffer.WriteBuffer(bufferUTF8); //写入命令内容
|
|
_sendBuffer.WriteBuffer(buffer, offset, count); //写入二进制数据
|
|
_tcpClient.Client.Send(_sendBuffer.Buffer, 0, _sendBuffer.DataCount, SocketFlags.None);
|
|
}
|
|
/// <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 RecvCommand()
|
|
{
|
|
_recvBuffer.Clear();
|
|
_tcpClient.Client.Receive(_recvBuffer.Buffer, sizeof(int), SocketFlags.None);
|
|
int packetLength = BitConverter.ToInt32(_recvBuffer.Buffer, 0); //获取包长度
|
|
if (NetByteOrder)
|
|
packetLength = System.Net.IPAddress.NetworkToHostOrder(packetLength); //把网络字节顺序转为本地字节顺序
|
|
_recvBuffer.SetBufferSize(sizeof(int) + packetLength); //保证接收有足够的空间
|
|
_tcpClient.Client.Receive(_recvBuffer.Buffer, sizeof(int), packetLength, SocketFlags.None);
|
|
int commandLen = BitConverter.ToInt32(_recvBuffer.Buffer, sizeof(int)); //取出命令长度
|
|
string tmpStr = Encoding.UTF8.GetString(_recvBuffer.Buffer, sizeof(int) + sizeof(int), commandLen);
|
|
if (!_incomingDataParser.DecodeProtocolText(tmpStr)) //解析命令
|
|
return false;
|
|
else
|
|
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="size">The size.</param>
|
|
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
|
public bool RecvCommand(out byte[] buffer, out int offset, out int size)
|
|
{
|
|
_recvBuffer.Clear();
|
|
_tcpClient.Client.Receive(_recvBuffer.Buffer, sizeof(int), SocketFlags.None);
|
|
int packetLength = BitConverter.ToInt32(_recvBuffer.Buffer, 0); //获取包长度
|
|
if (NetByteOrder)
|
|
packetLength = System.Net.IPAddress.NetworkToHostOrder(packetLength); //把网络字节顺序转为本地字节顺序
|
|
_recvBuffer.SetBufferSize(sizeof(int) + packetLength); //保证接收有足够的空间
|
|
_tcpClient.Client.Receive(_recvBuffer.Buffer, sizeof(int), packetLength, SocketFlags.None);
|
|
int commandLen = BitConverter.ToInt32(_recvBuffer.Buffer, sizeof(int)); //取出命令长度
|
|
string tmpStr = Encoding.UTF8.GetString(_recvBuffer.Buffer, sizeof(int) + sizeof(int), commandLen);
|
|
if (!_incomingDataParser.DecodeProtocolText(tmpStr)) //解析命令
|
|
{
|
|
buffer = null;
|
|
offset = 0;
|
|
size = 0;
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
buffer = _recvBuffer.Buffer;
|
|
offset = commandLen + sizeof(int) + sizeof(int);
|
|
size = packetLength - offset;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|