//go:build windows package yu_hpsocket import ( yu_proxy "gogs.qqck.cn/s/tools/proxy" yu_sys "gogs.qqck.cn/s/tools/sys" ) // Client // // @Description: Client 系列组件底层实现 type Client[T any] struct { hListener uintptr hClient uintptr SSL bool Extra any // 附加数据 // exdata---------------------------------- socket uintptr // 事件---------------------------------- onPrepareConnect func(t *T, Sender, ConnID, socket uintptr) HR onConnect func(t *T, Sender, ConnID uintptr) HR onHandShake func(t *T, Sender, ConnID uintptr) HR onSend func(t *T, Sender, ConnID, Data uintptr, Length uintptr) HR onReceive func(t *T, Sender, ConnID, Data uintptr, Length uintptr) HR onClose func(t *T, Sender, ConnID uintptr, Operation SO, ErrorCode int) HR // 扩展---------------------------------------------------------------- _RemoteAddress string _Port int proxy_info *yu_proxy.Info proxy_connect bool } // isValid // // @Description: 对象是否有效 func (t *Client[T]) isValid() bool { return t.hListener != 0 && t.hClient != 0 } // Start // // @Description: 启动通信组件(并指定【可选】绑定地址) // @param RemoteAddress 服务端地址 // @param Port 服务端端口 // @param AsyncConnect 是否采用异步 Connect // @param BindAddress 绑定地址(默认:nullptr,TcpClient/UdpClient -> 不执行绑定操作,UdpCast 绑定 -> 0.0.0.0) // @param LocalPort 本地端口(默认:0) // @return bool 是否启动成功 func (t *Client[T]) Start(RemoteAddress string, Port int, AsyncConnect bool, BindAddress string, LocalPort int) bool { if !t.isValid() { return false } // -------------------------------------------------------------------------------关联必要事件 if t.onPrepareConnect == nil { t.OnPrepareConnect(func(t *T, Sender, ConnID, socket uintptr) HR { return HR_IGNORE }) } // -------------------------------------------------------------------------------关联必要事件------end if t.proxy_info.Host == "" { return HP_Client_StartWithBindAddressAndLocalPort.CallBool(t.hClient, yu_sys.S{yu_sys.Gbk, RemoteAddress}, Port, AsyncConnect, yu_sys.S{yu_sys.Gbk, BindAddress}, LocalPort, ) } // -------------------------------------------------------------------------------判断代理是否有效 if !t.proxy_info.IsValid() || t.proxy_info.IsTimeout() { return false } // -------------------------------------------------------------------------------关联必要事件 if t.onConnect == nil { t.OnConnect(func(t *T, Sender, ConnID uintptr) HR { return HR_IGNORE }) } // -------------------------------------------------------------------------------关联必要事件------end t._RemoteAddress, t._Port = RemoteAddress, Port return HP_Client_StartWithBindAddressAndLocalPort.CallBool(t.hClient, yu_sys.S{yu_sys.Gbk, t.proxy_info.Host}, t.proxy_info.Port, AsyncConnect, yu_sys.S{yu_sys.Gbk, BindAddress}, LocalPort, ) } // Stop // // @Description: 关闭客户端通信组件,关闭完成后断开与服务端的连接并释放所有资源 // @return bool 是否成功关闭 func (t *Client[T]) Stop() bool { if !t.isValid() { return false } return HP_Client_Stop.CallBool(t.hClient) } // Wait // // @Description: 等待通信组件停止运行 // @param Milliseconds 超时时间(毫秒,默认:-1,永不超时) // @return bool 超时返回 false func (t *Client[T]) Wait(Milliseconds int) bool { if !t.isValid() { return false } return HP_Client_Wait.CallBool(t.hClient, Milliseconds) } // Send // // @Description: 向服务端发送数据 // @param buf 欲发送的数据 // @return bool 是否发送成功 func (t *Client[T]) Send(buf []byte) bool { if !t.isValid() { return false } if len(buf) == 0 { return true } return HP_Client_Send.CallBool(t.hClient, buf, len(buf)) } // SendS // // @Description: 向服务端发送数据 // @param buf 欲发送的数据 // @return bool 是否发送成功 func (t *Client[T]) SendS(buf string) bool { if !t.isValid() { return false } if len(buf) == 0 { return true } return HP_Client_Send.CallBool(t.hClient, buf, len(buf)) } // IsSecure // // @Description: 检测是否为安全连接(SSL/HTTPS) func (t *Client[T]) IsSecure() bool { if !t.isValid() { return false } return HP_Client_IsSecure.CallBool(t.hClient) } // SetExtra // // @Description: 设置连接的附加数据 func (t *Client[T]) SetExtra(extra uintptr) *Client[T] { if !t.isValid() { return t } HP_Client_SetExtra.Call(t.hClient, extra) return t } // GetExtra // // @Description: 获取连接的附加数据 func (t *Client[T]) GetExtra() uintptr { if !t.isValid() { return 0 } return HP_Client_GetExtra.CallUintptr(t.hClient) } // HasStarted // // @Description: 检查通信组件是否已启动 func (t *Client[T]) HasStarted() bool { if !t.isValid() { return false } return HP_Client_HasStarted.CallBool(t.hClient) } // GetState // // @Description: 查看通信组件当前状态,SS_ 开头常量 func (t *Client[T]) GetState() SS { if !t.isValid() { return SS_STOPPED } return SS(HP_Client_GetState.CallUintptr(t.hClient)) } // GetLastError // // @Description: 获取最近一次失败操作的错误代码 func (t *Client[T]) GetLastError() int { if !t.isValid() { return 0 } return HP_Client_GetLastError.CallInt(t.hClient) } // GetLastErrorDesc // // @Description: 获取最近一次失败操作的错误描述 func (t *Client[T]) GetLastErrorDesc() string { if !t.isValid() { return "Not Object" } return HP_Client_GetLastErrorDesc.CallGbkToUtf8(t.hClient) } // GetConnectionID // // @Description: 获取该组件对象的连接 ID func (t *Client[T]) GetConnectionID() uintptr { if !t.isValid() { return 0 } return HP_Client_GetConnectionID.CallUintptr(t.hClient) } // GetLocalAddress // // @Description: 获取连接的本地绑定信息 func (t *Client[T]) GetLocalAddress() (address string, port int) { if !t.isValid() { return } j_address_len := 128 j_address := make([]byte, 64) if !HP_Client_GetLocalAddress.CallBool(t.hClient, j_address, &j_address_len, &port) { return } j_address_len -= 1 // 有结束符 {0} j_unicode_len := j_address_len * 2 j_unicode := make([]byte, j_unicode_len) yu_sys.MultiByteToWideChar.Call(936, 0, j_address, j_address_len, j_unicode, j_unicode_len) j_utf8_size := j_unicode_len * 2 j_utf8 := make([]byte, j_utf8_size) address = string(j_utf8[:yu_sys.WideCharToMultiByte.CallInt(65001, 0, j_unicode, j_address_len, j_utf8, j_utf8_size, 0, 0)]) return } // GetRemoteHost // // @Description: 获取连接的远程主机信息 func (t *Client[T]) GetRemoteHost() (address string, port int) { if !t.isValid() { return } j_address_len := 128 j_address := make([]byte, 64) if !HP_Client_GetRemoteHost.CallBool(t.hClient, j_address, &j_address_len, &port) { return } j_address_len -= 1 // 有结束符 {0} j_unicode_len := j_address_len * 2 j_unicode := make([]byte, j_unicode_len) yu_sys.MultiByteToWideChar.Call(936, 0, j_address, j_address_len, j_unicode, j_unicode_len) j_utf8_size := j_unicode_len * 2 j_utf8 := make([]byte, j_utf8_size) address = string(j_utf8[:yu_sys.WideCharToMultiByte.CallInt(65001, 0, j_unicode, j_address_len, j_utf8, j_utf8_size, 0, 0)]) return } // GetPendingDataLength // // @Description: 获取连接中未发出数据的长度 func (t *Client[T]) GetPendingDataLength() (length int) { if !t.isValid() { return } HP_Client_GetPendingDataLength.Call(t.hClient, &length) return } // SetFreeBufferPoolSize // // @Description: 设置内存块缓存池大小(通常设置为 -> PUSH 模型:5 - 10;PULL 模型:10 - 20 ) func (t *Client[T]) SetFreeBufferPoolSize(FreeBufferPoolSize int) *Client[T] { if !t.isValid() { return t } HP_Client_SetFreeBufferPoolSize.Call(t.hClient, FreeBufferPoolSize) return t } // SetFreeBufferPoolHold // // @Description: 设置内存块缓存池回收阀值(通常设置为内存块缓存池大小的 3 倍) func (t *Client[T]) SetFreeBufferPoolHold(FreeBufferPoolHold int) *Client[T] { if !t.isValid() { return t } HP_Client_SetFreeBufferPoolHold.Call(t.hClient, FreeBufferPoolHold) return t } // GetFreeBufferPoolSize // // @Description: 获取内存块缓存池大小 func (t *Client[T]) GetFreeBufferPoolSize() int { if !t.isValid() { return 0 } return HP_Client_GetFreeBufferPoolSize.CallInt(t.hClient) } // GetFreeBufferPoolHold // // @Description: 获取内存块缓存池回收阀值 func (t *Client[T]) GetFreeBufferPoolHold() int { if !t.isValid() { return 0 } return HP_Client_GetFreeBufferPoolHold.CallInt(t.hClient) } // SetupSSLContext // // @Description: 初始化通信组件 SSL环境参数,SSL环境参数必须在 SSL通信组件启动前完成初始化,否则启动失败 // @param VerifyMode SSL_VM_ 开头常量,SSL验证模式 // @param PemCertFile 证书文件 // @param PemKeyFile 私钥文件 // @param KeyPasswod 私钥密码(没有密码则为空) // @param CAPemCertFileOrPath CA 证书文件或目录(单向验证或客户端可选) func (t *Client[T]) SetupSSLContext(VerifyMode SSL_VM, PemCertFile, PemKeyFile, KeyPasswod, CAPemCertFileOrPath string) bool { if !t.isValid() { return false } return HP_SSLClient_SetupSSLContext.CallBool(t.hClient, uintptr(VerifyMode), yu_sys.S{yu_sys.Gbk, PemCertFile}, yu_sys.S{yu_sys.Gbk, PemKeyFile}, yu_sys.S{yu_sys.Gbk, KeyPasswod}, yu_sys.S{yu_sys.Gbk, CAPemCertFileOrPath}, ) } // SetupSSLContextByMemory // // @Description: 初始化通信组件 SSL环境参数,SSL环境参数必须在 SSL通信组件启动前完成初始化,否则启动失败 // @param VerifyMode SSL_VM_ 开头常量,SSL验证模式 // @param PemCert 证书内容 // @param PemKey 私钥内容 // @param KeyPasswod 私钥密码(没有密码则为空) // @param CAPemCert CA 证书内容(单向验证可选) func (t *Client[T]) SetupSSLContextByMemory(VerifyMode SSL_VM, PemCert, PemKey, KeyPasswod, CAPemCert string) bool { if !t.isValid() { return false } return HP_SSLClient_SetupSSLContextByMemory.CallBool(t.hClient, uintptr(VerifyMode), yu_sys.S{yu_sys.Gbk, PemCert}, yu_sys.S{yu_sys.Gbk, PemKey}, yu_sys.S{yu_sys.Gbk, KeyPasswod}, yu_sys.S{yu_sys.Gbk, CAPemCert}, ) } // CleanupSSLContext // // @Description: 清理通信组件 SSL运行环境,回收 SSL相关内存 func (t *Client[T]) CleanupSSLContext() *Client[T] { if !t.isValid() { return t } HP_SSLClient_CleanupSSLContext.Call(t.hClient) return t } // StartSSLHandShake // // @Description: 启动 SSL握手,当通信组件设置为非自动握手时,需要调用本方法启动 SSL握手 func (t *Client[T]) StartSSLHandShake() bool { if !t.isValid() { return false } return HP_SSLClient_StartSSLHandShake.CallBool(t.hClient) } // SetSSLAutoHandShake // // @Description: 设置通信组件握手方式(默认:true,自动握手) func (t *Client[T]) SetSSLAutoHandShake(AutoHandShake bool) *Client[T] { if !t.isValid() { return t } HP_SSLClient_SetSSLAutoHandShake.Call(t.hClient, AutoHandShake) return t } // IsSSLAutoHandShake // // @Description: 获取通信组件握手方式 func (t *Client[T]) IsSSLAutoHandShake() bool { if !t.isValid() { return false } return HP_SSLClient_IsSSLAutoHandShake.CallBool(t.hClient) } // SetSSLCipherList // // @Description: 设置 SSL加密算法列表 func (t *Client[T]) SetSSLCipherList(CipherList string) *Client[T] { if !t.isValid() { return t } HP_SSLClient_SetSSLCipherList.Call(t.hClient, yu_sys.S{yu_sys.Gbk, CipherList}) return t } // GetSSLCipherList // // @Description: 获取 SSL加密算法列表 func (t *Client[T]) GetSSLCipherList() string { if !t.isValid() { return "" } return HP_SSLClient_GetSSLCipherList.CallGbkToUtf8(t.hClient) } // GetSSLSessionInfo // // @Description: 获取指定类型的 SSLSession 信息(输出类型参考:SSL_SSI_) // @param enInfo SSL_SSI_ 开头常量 func (t *Client[T]) GetSSLSessionInfo(enInfo SSL_SSI) (Info uintptr) { if !t.isValid() { return } HP_SSLClient_GetSSLSessionInfo.Call(t.hClient, uintptr(enInfo), &Info) return } // IsPauseReceive // // @Description: 获取连接的数据接收状态 func (t *Client[T]) IsPauseReceive() (Paused bool) { if !t.isValid() { return } HP_Client_IsPauseReceive.Call(t.hClient, &Paused) return } // IsConnected // // @Description: 检测是否有效连接 func (t *Client[T]) IsConnected() bool { if !t.isValid() { return false } return HP_Client_IsConnected.CallBool(t.hClient) } // SetReuseAddressPolicy // // @Description: 设置地址重用选项 // @param enReusePolicy RAP_ 开头常量 func (t *Client[T]) SetReuseAddressPolicy(ReusePolicy RAP) *Client[T] { if !t.isValid() { return t } HP_Client_SetReuseAddressPolicy.Call(t.hClient, uintptr(ReusePolicy)) return t } // GetReuseAddressPolicy // // @Description: 获取地址重用选项 RAP_ 开头常量 func (t *Client[T]) GetReuseAddressPolicy() RAP { if !t.isValid() { return RAP_NONE } return RAP(HP_Client_GetReuseAddressPolicy.CallUintptr(t.hClient)) } // PauseReceive // // @Description: 暂停/恢复某个连接的数据接收工作 func (t *Client[T]) PauseReceive(Paused bool) bool { if !t.isValid() { return false } return HP_Client_PauseReceive.CallBool(t.hClient, Paused) } // OnPrepareConnect // // @Description: 【可选】绑定准备连接事件 // @param call->return HR_ 开头常量 func (t *Client[T]) OnPrepareConnect(call func(t *T, Sender, ConnID, socket uintptr) HR) *Client[T] { if !t.isValid() { return t } if call == nil { HP_Set_FN_Client_OnPrepareConnect.Call(t.hListener, 0) } else { t.onPrepareConnect = call HP_Set_FN_Client_OnPrepareConnect.Call(t.hListener, client_callback_OnPrepareConnect_ptr) } return t } // OnConnect // // @Description: 【可选】绑定连接事件 // @param call->return HR_ 开头常量 func (t *Client[T]) OnConnect(call func(t *T, Sender, ConnID uintptr) HR) *Client[T] { if !t.isValid() { return t } if call == nil { HP_Set_FN_Client_OnConnect.Call(t.hListener, 0) } else { t.onConnect = call HP_Set_FN_Client_OnConnect.Call(t.hListener, client_callback_OnConnect_ptr) } return t } // OnHandShake // // @Description: 【可选】绑定握手事件 // @param call->return HR_ 开头常量 func (t *Client[T]) OnHandShake(call func(t *T, Sender, ConnID uintptr) HR) *Client[T] { if !t.isValid() { return t } if call == nil { HP_Set_FN_Client_OnHandShake.Call(t.hListener, 0) } else { t.onHandShake = call HP_Set_FN_Client_OnHandShake.Call(t.hListener, client_callback_OnHandShake_ptr) } return t } // OnSend // // @Description: 【可选】绑定发送事件 // @param call->return HR_ 开头常量 func (t *Client[T]) OnSend(call func(t *T, Sender, ConnID, Data uintptr, Length uintptr) HR) *Client[T] { if !t.isValid() { return t } if call == nil { HP_Set_FN_Client_OnSend.Call(t.hListener, 0) } else { t.onSend = call HP_Set_FN_Client_OnSend.Call(t.hListener, client_callback_OnSend_ptr) } return t } // OnReceive // // @Description: 【必选】绑定数据接收事件 // @param call->return HR_ 开头常量 func (t *Client[T]) OnReceive(call func(t *T, Sender, ConnID, Data uintptr, Length uintptr) HR) *Client[T] { if !t.isValid() { return t } if call == nil { HP_Set_FN_Client_OnReceive.Call(t.hListener, 0) } else { t.onReceive = call HP_Set_FN_Client_OnReceive.Call(t.hListener, client_callback_OnReceive_ptr) } return t } // OnClose // // @Description: 【必选】绑定断开事件 // @param call->Operation 通过该参数标识是哪种操作导致的错误 SO_ 开头常量 // @param call->return HR_ 开头常量 func (t *Client[T]) OnClose(call func(t *T, Sender, ConnID uintptr, Operation SO, ErrorCode int) HR) *Client[T] { if !t.isValid() { return t } if call == nil { HP_Set_FN_Client_OnClose.Call(t.hListener, 0) } else { t.onClose = call HP_Set_FN_Client_OnClose.Call(t.hListener, client_callback_OnClose_ptr) } return t } // OnDefault // // @Description: 【可选】绑定所有【必选】事件 func (t *Client[T]) OnDefault() *Client[T] { if !t.isValid() { return t } if t.onReceive == nil { t.OnReceive(func(t *T, Sender, ConnID, Data uintptr, Length uintptr) HR { return HR_OK }) } if t.onClose == nil { t.OnClose(func(t *T, Sender, ConnID uintptr, Operation SO, ErrorCode int) HR { return HR_OK }) } return t }