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); } } }