using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
namespace HPSocketCS
{
public class UdpClient : ConnectionExtra, IClient
{
///
/// 准备连接了事件
///
public event ClientEvent.OnPrepareConnectEventHandler OnPrepareConnect;
///
/// 连接事件
///
public event ClientEvent.OnConnectEventHandler OnConnect;
///
/// 数据发送事件
///
public event ClientEvent.OnSendEventHandler OnSend;
///
/// 数据到达事件
///
public event ClientEvent.OnReceiveEventHandler OnReceive;
///
/// 数据到达事件(指针数据)
///
public event ClientEvent.OnPointerDataReceiveEventHandler OnPointerDataReceive;
///
/// 连接关闭事件
///
public event ClientEvent.OnCloseEventHandler OnClose;
///
/// 握手事件
///
public event ClientEvent.OnHandShakeEventHandler OnHandShake;
protected IntPtr pClient = IntPtr.Zero;
protected IntPtr pListener = IntPtr.Zero;
protected bool IsCreate = false;
ConnectionExtra ExtraData = new ConnectionExtra();
public UdpClient()
{
CreateListener();
}
~UdpClient()
{
Destroy();
}
///
/// 创建socket监听&服务组件
///
///
protected virtual bool CreateListener()
{
if (IsCreate == true || pListener != IntPtr.Zero || pClient != IntPtr.Zero)
{
return false;
}
pListener = Sdk.Create_HP_UdpClientListener();
if (pListener == IntPtr.Zero)
{
return false;
}
pClient = Sdk.Create_HP_UdpClient(pListener);
if (pClient == IntPtr.Zero)
{
return false;
}
IsCreate = true;
return true;
}
///
/// 终止服务并释放资源
///
public virtual void Destroy()
{
Stop();
if (pClient != IntPtr.Zero)
{
Sdk.Destroy_HP_UdpClient(pClient);
pClient = IntPtr.Zero;
}
if (pListener != IntPtr.Zero)
{
Sdk.Destroy_HP_UdpClientListener(pListener);
pListener = IntPtr.Zero;
}
IsCreate = false;
}
///
/// 启动通讯组件并连接到服务器
///
/// 远程地址
/// 远程端口
/// 是否异步
///
public bool Connect(string address, ushort port, bool async = true)
{
if (string.IsNullOrEmpty(address) == true)
{
throw new Exception("address is null");
}
else if (port == 0)
{
throw new Exception("port is zero");
}
if (pClient == IntPtr.Zero)
{
return false;
}
this.SetCallback();
return Sdk.HP_Client_Start(pClient, address, port, async);
}
///
/// 启动通讯组件并连接到服务器
///
/// 远程地址
/// 远程端口
/// 本地绑定到哪个ip?,多ip下可以选择绑定到指定ip
/// 是否异步
///
public bool Connect(string address, ushort port, string bindAddress, bool async = true)
{
if (string.IsNullOrEmpty(address) == true)
{
throw new Exception("address is null");
}
else if (port == 0)
{
throw new Exception("port is zero");
}
if (pClient == IntPtr.Zero)
{
return false;
}
this.SetCallback();
return Sdk.HP_Client_StartWithBindAddress(pClient, address, port, async, bindAddress);
}
///
/// 启动通讯组件并连接到服务器
///
/// 远程地址
/// 远程端口
/// 本地绑定到哪个ip?,多ip下可以选择绑定到指定ip
/// 本地端口
/// 是否异步
///
public bool Connect(string address, ushort port, string bindAddress, ushort usLocalPort, bool async = true)
{
if (string.IsNullOrEmpty(address) == true)
{
throw new Exception("address is null");
}
else if (port == 0)
{
throw new Exception("port is zero");
}
if (pClient == IntPtr.Zero)
{
return false;
}
this.SetCallback();
return Sdk.HP_Client_StartWithBindAddressAndLocalPort(pClient, address, port, async, bindAddress, usLocalPort);
}
///
/// 停止通讯组件
///
///
public bool Stop()
{
if (pClient == IntPtr.Zero)
{
return false;
}
return Sdk.HP_Client_Stop(pClient);
}
///
/// 发送数据
///
///
///
///
public bool Send(byte[] bytes, int size)
{
return Sdk.HP_Client_Send(pClient, bytes, size);
}
///
/// 发送数据
///
///
///
///
public bool Send(IntPtr bufferPtr, int size)
{
return Sdk.HP_Client_Send(pClient, bufferPtr, size);
}
///
/// 发送数据
///
///
/// 针对bytes的偏移
/// 发多大
///
public bool Send(byte[] bytes, int offset, int size)
{
return Sdk.HP_Client_SendPart(pClient, bytes, size, offset);
}
///
/// 发送数据
///
///
/// 针对bufferPtr的偏移
/// 发多大
///
public bool Send(IntPtr bufferPtr, int offset, int size)
{
return Sdk.HP_Client_SendPart(pClient, bufferPtr, size, offset);
}
///
/// 发送多组数据
/// 向指定连接发送多组数据
/// TCP - 顺序发送所有数据包
///
/// 发送缓冲区数组
/// 发送缓冲区数目
/// TRUE.成功,FALSE.失败,可通过 SYSGetLastError() 获取 Windows 错误代码
public bool SendPackets(WSABUF[] buffers, int count)
{
return Sdk.HP_Client_SendPackets(pClient, buffers, count);
}
///
/// 发送多组数据
/// 向指定连接发送多组数据
/// TCP - 顺序发送所有数据包
///
/// 发送缓冲区数组
/// TRUE.成功,FALSE.失败,可通过 SYSGetLastError() 获取 Windows 错误代码
public bool SendPackets(T[] objects)
{
bool ret = false;
WSABUF[] buffer = new WSABUF[objects.Length];
IntPtr[] ptrs = new IntPtr[buffer.Length];
try
{
for (int i = 0; i < objects.Length; i++)
{
buffer[i].Length = Marshal.SizeOf(typeof(T));
ptrs[i] = Marshal.AllocHGlobal(buffer[i].Length);
Marshal.StructureToPtr(objects[i], ptrs[i], true);
buffer[i].Buffer = ptrs[i];
}
ret = SendPackets(buffer, buffer.Length);
}
catch (Exception ex)
{
throw ex;
}
finally
{
foreach (var ptr in ptrs)
{
if (ptr != IntPtr.Zero)
{
Marshal.FreeHGlobal(ptr);
}
}
}
return ret;
}
///
/// 获取错误码
///
public SocketError ErrorCode
{
get
{
return Sdk.HP_Client_GetLastError(pClient);
}
}
///
/// 版本号
///
public string Version
{
get
{
return Sdk.GetHPSocketVersion();
}
}
///
/// 获取错误信息
///
public string ErrorMessage
{
get
{
IntPtr ptr = Sdk.HP_Client_GetLastErrorDesc(pClient);
string desc = Marshal.PtrToStringAnsi(ptr);
return desc;
}
}
///
/// 获取或设置接收状态
///
public ReceiveState ReceiveState
{
get
{
int state = -1;
if (Sdk.HP_Client_IsPauseReceive(pClient, ref state))
{
return (ReceiveState)state;
}
return ReceiveState.Unknown;
}
set
{
Sdk.HP_Client_PauseReceive(pClient, (int)value);
}
}
///
///
///
///
public bool GetPendingDataLength(ref int length)
{
return Sdk.HP_Client_GetPendingDataLength(pClient, ref length);
}
///
/// 获取附加数据
///
///
public T GetExtra()
{
return (T)ExtraData.GetExtra(pClient);
}
///
/// 设置附加数据
///
///
///
///
public bool SetExtra(object newValue)
{
return ExtraData.SetExtra(pClient, newValue);
}
///
/// 删除附加数据
///
///
///
public bool RemoveExtra()
{
return ExtraData.RemoveExtra(pClient);
}
///
/// 获取监听socket的地址信息
///
///
///
///
public bool GetListenAddress(ref string ip, ref ushort port)
{
int ipLength = 40;
StringBuilder sb = new StringBuilder(ipLength);
bool ret = Sdk.HP_Client_GetLocalAddress(pClient, sb, ref ipLength, ref port);
if (ret == true)
{
ip = sb.ToString();
}
return ret;
}
///
/// 获取连接的远程主机信息
///
///
///
///
public bool GetRemoteHost(ref string host, ref ushort port)
{
int ipLength = 40;
StringBuilder sb = new StringBuilder(ipLength);
bool ret = Sdk.HP_Client_GetRemoteHost(pClient, sb, ref ipLength, ref port);
if (ret == true)
{
host = sb.ToString();
}
return ret;
}
///
/// 是否启动
///
public bool IsStarted
{
get
{
if (pClient == IntPtr.Zero)
{
return false;
}
return Sdk.HP_Client_HasStarted(pClient);
}
}
///
/// 状态
///
public ServiceState State
{
get
{
return Sdk.HP_Client_GetState(pClient);
}
}
///
/// 获取该组件对象的连接Id
///
public IntPtr ConnectionId
{
get
{
return Sdk.HP_Client_GetConnectionID(pClient);
}
}
///
/// 检测是否为安全连接(SSL/HTTPS)
///
public bool IsSecure
{
get
{
return Sdk.HP_Client_IsSecure(pClient);
}
}
///////////////////////////////////////////////////////////////////////////////////////
///
/// 读取或设置内存块缓存池大小(通常设置为 -> PUSH 模型:5 - 10;PULL 模型:10 - 20 )
///
public uint FreeBufferPoolSize
{
get
{
return Sdk.HP_Client_GetFreeBufferPoolSize(pClient);
}
set
{
Sdk.HP_Client_SetFreeBufferPoolSize(pClient, value);
}
}
///
/// 读取或设置内存块缓存池回收阀值(通常设置为内存块缓存池大小的 3 倍)
///
public uint FreeBufferPoolHold
{
get
{
return Sdk.HP_Client_GetFreeBufferPoolHold(pClient);
}
set
{
Sdk.HP_Client_SetFreeBufferPoolHold(pClient, value);
}
}
///////////////////////////////////////////////////////////////////////////////////////
///
/// 根据错误码返回错误信息
///
///
///
public string GetSocketErrorDesc(SocketError code)
{
IntPtr ptr = Sdk.HP_GetSocketErrorDesc(code);
string desc = Marshal.PtrToStringAnsi(ptr);
return desc;
}
///////////////////////////////////////////////////////////////////////////////////////
protected Sdk.OnPrepareConnect _OnPrepareConnect = null;
protected Sdk.OnConnect _OnConnect = null;
protected Sdk.OnReceive _OnReceive = null;
protected Sdk.OnSend _OnSend = null;
protected Sdk.OnClose _OnClose = null;
protected Sdk.OnHandShake _OnHandShake = null;
///
/// 设置回调函数
///
protected virtual void SetCallback()
{
// 设置 Socket 监听器回调函数
_OnPrepareConnect = new Sdk.OnPrepareConnect(SDK_OnPrepareConnect);
_OnConnect = new Sdk.OnConnect(SDK_OnConnect);
_OnSend = new Sdk.OnSend(SDK_OnSend);
_OnReceive = new Sdk.OnReceive(SDK_OnReceive);
_OnClose = new Sdk.OnClose(SDK_OnClose);
_OnHandShake = new Sdk.OnHandShake(SDK_OnHandShake);
Sdk.HP_Set_FN_Client_OnPrepareConnect(pListener, _OnPrepareConnect);
Sdk.HP_Set_FN_Client_OnConnect(pListener, _OnConnect);
Sdk.HP_Set_FN_Client_OnSend(pListener, _OnSend);
Sdk.HP_Set_FN_Client_OnReceive(pListener, _OnReceive);
Sdk.HP_Set_FN_Client_OnClose(pListener, _OnClose);
Sdk.HP_Set_FN_Client_OnHandShake(pListener, _OnHandShake);
}
protected HandleResult SDK_OnPrepareConnect(IntPtr pSender, IntPtr connId, IntPtr socket)
{
if (OnPrepareConnect != null)
{
return OnPrepareConnect(this, socket);
}
return HandleResult.Ignore;
}
protected HandleResult SDK_OnConnect(IntPtr pSender, IntPtr connId)
{
if (OnConnect != null)
{
return OnConnect(this);
}
return HandleResult.Ignore;
}
protected HandleResult SDK_OnSend(IntPtr pSender, IntPtr connId, IntPtr pData, int length)
{
if (OnSend != null)
{
byte[] bytes = new byte[length];
Marshal.Copy(pData, bytes, 0, length);
return OnSend(this, bytes);
}
return HandleResult.Ignore;
}
protected HandleResult SDK_OnReceive(IntPtr pSender, IntPtr connId, IntPtr pData, int length)
{
if (OnPointerDataReceive != null)
{
return OnPointerDataReceive(this, pData, length);
}
else if (OnReceive != null)
{
byte[] bytes = new byte[length];
Marshal.Copy(pData, bytes, 0, length);
return OnReceive(this, bytes);
}
return HandleResult.Ignore;
}
protected HandleResult SDK_OnClose(IntPtr pSender, IntPtr connId, SocketOperation enOperation, int errorCode)
{
if (OnClose != null)
{
return OnClose(this, enOperation, errorCode);
}
return HandleResult.Ignore;
}
protected HandleResult SDK_OnHandShake(IntPtr pSender, IntPtr connId)
{
if (OnHandShake != null)
{
return OnHandShake(this);
}
return HandleResult.Ignore;
}
///////////////////////////////////////////////////////////////////////////
///
/// 获取系统返回的错误码
///
public int SYSGetLastError()
{
return Sdk.SYS_GetLastError();
}
///
/// 调用系统的 ::WSAGetLastError() 方法获取通信错误代码
///
public int SYSWSAGetLastError()
{
return Sdk.SYS_WSAGetLastError();
}
///
/// 调用系统的 setsockopt()
///
///
///
///
///
///
///
public int SYS_SetSocketOption(IntPtr sock, int level, int name, IntPtr val, int len)
{
return Sdk.SYS_SetSocketOption(sock, level, name, val, len);
}
///
/// 调用系统的 getsockopt()
///
///
///
///
///
///
///
public int SYSGetSocketOption(IntPtr sock, int level, int name, IntPtr val, ref int len)
{
return Sdk.SYS_GetSocketOption(sock, level, name, val, ref len);
}
///
/// 调用系统的 ioctlsocket()
///
///
///
///
///
public int SYSIoctlSocket(IntPtr sock, long cmd, IntPtr arg)
{
return Sdk.SYS_IoctlSocket(sock, cmd, arg);
}
///
/// 调用系统的 ::WSAIoctl()
///
///
///
///
///
///
///
///
///
public int SYS_WSAIoctl(IntPtr sock, uint dwIoControlCode, IntPtr lpvInBuffer, uint cbInBuffer,
IntPtr lpvOutBuffer, uint cbOutBuffer, uint lpcbBytesReturned)
{
return Sdk.SYS_WSAIoctl(sock, dwIoControlCode, lpvInBuffer, cbInBuffer,
lpvOutBuffer, cbOutBuffer, lpcbBytesReturned);
}
}
}