TcpAgent.cs 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Runtime.InteropServices;
  4. using System.Runtime.Serialization;
  5. using System.Runtime.Serialization.Formatters.Binary;
  6. using System.Linq;
  7. using System.Text;
  8. using System.IO;
  9. namespace HPSocketCS
  10. {
  11. public class TcpAgentEvent
  12. {
  13. public delegate HandleResult OnConnectEventHandler(IntPtr connId /* IntPtr pClient */);
  14. public delegate HandleResult OnSendEventHandler(IntPtr connId, byte[] bytes);
  15. public delegate HandleResult OnReceiveEventHandler(IntPtr connId, byte[] bytes);
  16. public delegate HandleResult OnPointerDataReceiveEventHandler(IntPtr connId, IntPtr pData, int length);
  17. public delegate HandleResult OnCloseEventHandler(IntPtr connId, SocketOperation enOperation, int errorCode);
  18. public delegate HandleResult OnShutdownEventHandler();
  19. public delegate HandleResult OnPrepareConnectEventHandler(IntPtr connId /* IntPtr pClient */, uint socket);
  20. }
  21. public class TcpAgent : ConnectionExtra
  22. {
  23. protected IntPtr _pAgent = IntPtr.Zero;
  24. protected IntPtr pAgent
  25. {
  26. get
  27. {
  28. //if (_pClient == IntPtr.Zero)
  29. //{
  30. // throw new Exception("pClient == 0");
  31. //}
  32. return _pAgent;
  33. }
  34. set
  35. {
  36. _pAgent = value;
  37. }
  38. }
  39. protected IntPtr pListener = IntPtr.Zero;
  40. /// <summary>
  41. /// 连接事件
  42. /// </summary>
  43. public TcpAgentEvent.OnConnectEventHandler OnConnect;
  44. /// <summary>
  45. /// 数据发送事件
  46. /// </summary>
  47. public TcpAgentEvent.OnSendEventHandler OnSend;
  48. /// <summary>
  49. /// 准备连接事件
  50. /// </summary>
  51. public TcpAgentEvent.OnPrepareConnectEventHandler OnPrepareConnect;
  52. /// <summary>
  53. /// 数据到达事件
  54. /// </summary>
  55. public TcpAgentEvent.OnReceiveEventHandler OnReceive;
  56. /// <summary>
  57. /// 数据到达事件(指针数据)
  58. /// </summary>
  59. public event TcpAgentEvent.OnPointerDataReceiveEventHandler OnPointerDataReceive;
  60. /// <summary>
  61. /// 连接关闭事件
  62. /// </summary>
  63. public TcpAgentEvent.OnCloseEventHandler OnClose;
  64. /// <summary>
  65. /// 服务关闭事件
  66. /// </summary>
  67. public TcpAgentEvent.OnShutdownEventHandler OnShutdown;
  68. protected bool IsCreate = false;
  69. public TcpAgent()
  70. {
  71. CreateListener();
  72. }
  73. ~TcpAgent()
  74. {
  75. Destroy();
  76. }
  77. /// <summary>
  78. /// 创建socket监听&服务组件
  79. /// </summary>
  80. /// <returns></returns>
  81. protected virtual bool CreateListener()
  82. {
  83. if (IsCreate == true || pListener != IntPtr.Zero || pAgent != IntPtr.Zero)
  84. {
  85. return false;
  86. }
  87. pListener = Sdk.Create_HP_TcpAgentListener();
  88. if (pListener == IntPtr.Zero)
  89. {
  90. return false;
  91. }
  92. pAgent = Sdk.Create_HP_TcpAgent(pListener);
  93. if (pAgent == IntPtr.Zero)
  94. {
  95. return false;
  96. }
  97. IsCreate = true;
  98. return true;
  99. }
  100. /// <summary>
  101. /// 终止服务并释放资源
  102. /// </summary>
  103. public virtual void Destroy()
  104. {
  105. Stop();
  106. if (pAgent != IntPtr.Zero)
  107. {
  108. Sdk.Destroy_HP_TcpAgent(pAgent);
  109. pAgent = IntPtr.Zero;
  110. }
  111. if (pListener != IntPtr.Zero)
  112. {
  113. Sdk.Destroy_HP_TcpAgentListener(pListener);
  114. pListener = IntPtr.Zero;
  115. }
  116. IsCreate = false;
  117. }
  118. /// <summary>
  119. /// 启动通讯组件
  120. /// 启动完成后可开始连接远程服务器
  121. /// </summary>
  122. /// <param name="address">绑定地址</param>
  123. /// <param name="async">是否异步</param>
  124. /// <returns></returns>
  125. public bool Start(string address, bool async = true)
  126. {
  127. if (string.IsNullOrEmpty(address) == true)
  128. {
  129. throw new Exception("address is null");
  130. }
  131. if (IsCreate == false)
  132. {
  133. return false;
  134. }
  135. if (IsStarted == true)
  136. {
  137. return false;
  138. }
  139. SetCallback();
  140. return Sdk.HP_Agent_Start(pAgent, address, async);
  141. }
  142. /// <summary>
  143. /// 停止通讯组件
  144. /// </summary>
  145. /// <returns></returns>
  146. public bool Stop()
  147. {
  148. if (IsStarted == false)
  149. {
  150. return false;
  151. }
  152. return Sdk.HP_Agent_Stop(pAgent);
  153. }
  154. /// <summary>
  155. /// 连接服务器,连接成功后 IAgentListener 会接收到 OnConnect() 事件
  156. /// </summary>
  157. /// <param name="address"></param>
  158. /// <param name="port"></param>
  159. /// <param name="connId"></param>
  160. /// <returns></returns>
  161. public bool Connect(string address, ushort port, ref IntPtr connId)
  162. {
  163. return Sdk.HP_Agent_Connect(pAgent, address, port, ref connId);
  164. }
  165. /// <summary>
  166. /// 发送数据
  167. /// </summary>
  168. /// <param name="connId"></param>
  169. /// <param name="bytes"></param>
  170. /// <param name="size"></param>
  171. /// <returns></returns>
  172. public bool Send(IntPtr connId, byte[] bytes, int size)
  173. {
  174. return Sdk.HP_Agent_Send(pAgent, connId, bytes, size);
  175. }
  176. /// <summary>
  177. /// 发送数据
  178. /// </summary>
  179. /// <param name="connId"></param>
  180. /// <param name="bufferPtr"></param>
  181. /// <param name="size"></param>
  182. /// <returns></returns>
  183. public bool Send<T>(IntPtr connId, T obj)
  184. {
  185. byte[] buffer = StructureToByte<T>(obj);
  186. return Send(connId, buffer, buffer.Length);
  187. }
  188. /// <summary>
  189. /// 序列化对象后发送数据,序列化对象所属类必须标记[Serializable]
  190. /// </summary>
  191. /// <param name="connId"></param>
  192. /// <param name="bufferPtr"></param>
  193. /// <param name="size"></param>
  194. /// <returns></returns>
  195. public bool SendBySerializable(IntPtr connId, object obj)
  196. {
  197. byte[] buffer = ObjectToBytes(obj);
  198. return Send(connId, buffer, buffer.Length);
  199. }
  200. /// <summary>
  201. /// 发送数据
  202. /// </summary>
  203. /// <param name="connId"></param>
  204. /// <param name="bufferPtr"></param>
  205. /// <param name="size"></param>
  206. /// <returns></returns>
  207. public bool Send(IntPtr connId, IntPtr bufferPtr, int size)
  208. {
  209. return Sdk.HP_Agent_Send(pAgent, connId, bufferPtr, size);
  210. }
  211. /// <summary>
  212. /// 发送数据
  213. /// </summary>
  214. /// <param name="connId"></param>
  215. /// <param name="bytes"></param>
  216. /// <param name="offset">针对bytes的偏移</param>
  217. /// <param name="size">发多大</param>
  218. /// <returns></returns>
  219. public bool Send(IntPtr connId, byte[] bytes, int offset, int size)
  220. {
  221. return Sdk.HP_Agent_SendPart(pAgent, connId, bytes, size, offset);
  222. }
  223. /// <summary>
  224. /// 发送数据
  225. /// </summary>
  226. /// <param name="connId"></param>
  227. /// <param name="bufferPtr"></param>
  228. /// <param name="offset">针对bufferPtr的偏移</param>
  229. /// <param name="size">发多大</param>
  230. /// <returns></returns>
  231. public bool Send(IntPtr connId, IntPtr bufferPtr, int offset, int size)
  232. {
  233. return Sdk.HP_Agent_SendPart(pAgent, connId, bufferPtr, size, offset);
  234. }
  235. /// <summary>
  236. /// 发送多组数据
  237. /// 向指定连接发送多组数据
  238. /// TCP - 顺序发送所有数据包
  239. /// </summary>
  240. /// <param name="connId">连接 ID</param>
  241. /// <param name="pBuffers">发送缓冲区数组</param>
  242. /// <param name="iCount">发送缓冲区数目</param>
  243. /// <returns>TRUE.成功,FALSE.失败,可通过 SYSGetLastError() 获取 Windows 错误代码</returns>
  244. public bool SendPackets(IntPtr connId, WSABUF[] pBuffers, int count)
  245. {
  246. return Sdk.HP_Agent_SendPackets(pAgent, connId, pBuffers, count);
  247. }
  248. /// <summary>
  249. /// 发送多组数据
  250. /// 向指定连接发送多组数据
  251. /// TCP - 顺序发送所有数据包
  252. /// </summary>
  253. /// <param name="connId">连接 ID</param>
  254. /// <param name="pBuffers">发送缓冲区数组</param>
  255. /// <param name="iCount">发送缓冲区数目</param>
  256. /// <returns>TRUE.成功,FALSE.失败,可通过 SYSGetLastError() 获取 Windows 错误代码</returns>
  257. public bool SendPackets<T>(IntPtr connId, T[] objects)
  258. {
  259. bool ret = false;
  260. WSABUF[] buffer = new WSABUF[objects.Length];
  261. IntPtr[] ptrs = new IntPtr[buffer.Length];
  262. try
  263. {
  264. for (int i = 0; i < objects.Length; i++)
  265. {
  266. buffer[i].Length = Marshal.SizeOf(typeof(T));
  267. ptrs[i] = Marshal.AllocHGlobal(buffer[i].Length);
  268. Marshal.StructureToPtr(objects[i], ptrs[i], true);
  269. buffer[i].Buffer = ptrs[i];
  270. }
  271. ret = SendPackets(connId, buffer, buffer.Length);
  272. }
  273. catch (Exception ex)
  274. {
  275. throw ex;
  276. }
  277. finally
  278. {
  279. for (int i = 0; i < ptrs.Length; i++)
  280. {
  281. if (ptrs[i] != IntPtr.Zero)
  282. {
  283. Marshal.FreeHGlobal(ptrs[i]);
  284. }
  285. }
  286. }
  287. return ret;
  288. }
  289. /// <summary>
  290. /// 名称:发送小文件
  291. /// 描述:向指定连接发送 4096 KB 以下的小文件
  292. /// </summary>
  293. /// <param name="connId"></param>
  294. /// <param name="filePath">文件路径</param>
  295. /// <param name="head">头部附加数据</param>
  296. /// <param name="tail">尾部附加数据</param>
  297. /// <returns>TRUE.成功,FALSE.失败,可通过 SYSGetLastError() 获取 Windows 错误代码</returns>
  298. public bool SendSmallFile(IntPtr connId, string filePath, ref WSABUF head, ref WSABUF tail)
  299. {
  300. return Sdk.HP_TcpAgent_SendSmallFile(pAgent, connId, filePath, ref head, ref tail);
  301. }
  302. /// <summary>
  303. /// 名称:发送小文件
  304. /// 描述:向指定连接发送 4096 KB 以下的小文件
  305. /// </summary>
  306. /// <param name="connId"></param>
  307. /// <param name="filePath">文件路径</param>
  308. /// <param name="head">头部附加数据,可以为null</param>
  309. /// <param name="tail">尾部附加数据,可以为null</param>
  310. /// <returns>TRUE.成功,FALSE.失败,可通过 SYSGetLastError() 获取 Windows 错误代码</returns>
  311. public bool SendSmallFile(IntPtr connId, string filePath, byte[] head, byte[] tail)
  312. {
  313. IntPtr pHead = IntPtr.Zero;
  314. IntPtr pTail = IntPtr.Zero;
  315. WSABUF wsaHead = new WSABUF() { Length = 0, Buffer = pHead };
  316. WSABUF wsatail = new WSABUF() { Length = 0, Buffer = pTail };
  317. if (head != null)
  318. {
  319. wsaHead.Length = head.Length;
  320. wsaHead.Buffer = Marshal.UnsafeAddrOfPinnedArrayElement(head, 0);
  321. }
  322. if (tail != null)
  323. {
  324. wsaHead.Length = tail.Length;
  325. wsaHead.Buffer = Marshal.UnsafeAddrOfPinnedArrayElement(tail, 0);
  326. }
  327. return SendSmallFile(connId, filePath, ref wsaHead, ref wsatail);
  328. }
  329. /// <summary>
  330. /// 名称:发送小文件
  331. /// 描述:向指定连接发送 4096 KB 以下的小文件
  332. /// </summary>
  333. /// <param name="connId"></param>
  334. /// <param name="filePath">文件路径</param>
  335. /// <param name="head">头部附加数据,可以为null</param>
  336. /// <param name="tail">尾部附加数据,可以为null</param>
  337. /// <returns>TRUE.成功,FALSE.失败,可通过 SYSGetLastError() 获取 Windows 错误代码</returns>
  338. public bool SendSmallFile<T1, T2>(IntPtr connId, string filePath, T1 head, T2 tail)
  339. {
  340. byte[] headBuffer = null;
  341. if (head != null)
  342. {
  343. headBuffer = StructureToByte<T1>(head);
  344. }
  345. byte[] tailBuffer = null;
  346. if (tail != null)
  347. {
  348. tailBuffer = StructureToByte<T2>(tail);
  349. }
  350. return SendSmallFile(connId, filePath, headBuffer, tailBuffer);
  351. }
  352. /// <summary>
  353. /// 断开某个连接
  354. /// </summary>
  355. /// <param name="connId"></param>
  356. /// <param name="force">强制</param>
  357. /// <returns></returns>
  358. public bool Disconnect(IntPtr connId, bool force = true)
  359. {
  360. return Sdk.HP_Agent_Disconnect(pAgent, connId, force);
  361. }
  362. /// <summary>
  363. /// 断开超过指定时间的连接
  364. /// </summary>
  365. /// <param name="period">毫秒</param>
  366. /// <param name="force">强制</param>
  367. /// <returns></returns>
  368. public bool DisconnectLongConnections(uint period, bool force = true)
  369. {
  370. return Sdk.HP_Agent_DisconnectLongConnections(pAgent, period, force);
  371. }
  372. /// <summary>
  373. /// 断开超过指定时长的静默连接
  374. /// </summary>
  375. /// <param name="period">毫秒</param>
  376. /// <param name="force">强制</param>
  377. /// <returns></returns>
  378. public bool DisconnectSilenceConnections(uint period, bool force = true)
  379. {
  380. return Sdk.HP_Agent_DisconnectSilenceConnections(pAgent, period, force);
  381. }
  382. ///// <summary>
  383. ///// 设置连接的附加数据
  384. ///// </summary>
  385. ///// <param name="connId"></param>
  386. ///// <param name="obj"></param>
  387. ///// <returns></returns>
  388. //public bool SetConnectionExtra(IntPtr connId, object obj)
  389. //{
  390. // IntPtr ptr = IntPtr.Zero;
  391. // // 释放附加数据
  392. // if (Sdk.HP_Agent_GetConnectionExtra(pAgent, connId, ref ptr) && ptr != IntPtr.Zero)
  393. // {
  394. // Marshal.FreeHGlobal(ptr);
  395. // ptr = IntPtr.Zero;
  396. // }
  397. // if (obj != null)
  398. // {
  399. // // 设置附加数据
  400. // ptr = Marshal.AllocHGlobal(Marshal.SizeOf(obj));
  401. // Marshal.StructureToPtr(obj, ptr, false);
  402. // }
  403. // return Sdk.HP_Agent_SetConnectionExtra(pAgent, connId, ptr);
  404. //}
  405. ///// <summary>
  406. ///// 获取附加数据
  407. ///// 如设置的是个结构体/类对象,可以用 Type objA = (Type)Marshal.PtrToStructure(ptr, typeof(Type)) 获取
  408. ///// 其中Type是结构体/类名,ptr是该方法的传出值,在该方法返回为true的时候可用
  409. ///// </summary>
  410. ///// <param name="connId"></param>
  411. ///// <param name="ptr"></param>
  412. ///// <returns></returns>
  413. //[Obsolete("该非泛型方法已过期,推荐使用泛型方法: T GetConnectionExtra<T>(IntPtr connId)")]
  414. //public bool GetConnectionExtra(IntPtr connId, ref IntPtr ptr)
  415. //{
  416. // return Sdk.HP_Agent_GetConnectionExtra(pAgent, connId, ref ptr) && ptr != IntPtr.Zero;
  417. //}
  418. ///// <summary>
  419. ///// 获取附加数据
  420. ///// 成功时返回对象,失败时返回T类型默认值,如:int=0, classA=null
  421. ///// </summary>
  422. ///// <param name="connId"></param>
  423. ///// <returns></returns>
  424. //public T GetConnectionExtra<T>(IntPtr connId)
  425. //{
  426. // IntPtr ptr = IntPtr.Zero;
  427. // T obj = default(T);
  428. // if (Sdk.HP_Agent_GetConnectionExtra(pAgent, connId, ref ptr))
  429. // {
  430. // obj = (T)Marshal.PtrToStructure(ptr, typeof(T));
  431. // }
  432. // return obj;
  433. //}
  434. ///// <summary>
  435. ///// 移除连接中的附加数据, 同SetConnectionExtra(id, null)
  436. ///// </summary>
  437. ///// <param name="connId"></param>
  438. ///// <returns></returns>
  439. //public bool RemoveConnectionExtra(IntPtr connId)
  440. //{
  441. // return SetConnectionExtra(connId, null);
  442. //}
  443. /// <summary>
  444. /// 获取错误码
  445. /// </summary>
  446. public SocketError ErrorCode
  447. {
  448. get
  449. {
  450. return Sdk.HP_Agent_GetLastError(pAgent);
  451. }
  452. }
  453. /// <summary>
  454. /// 获取错误信息
  455. /// </summary>
  456. public string ErrorMessage
  457. {
  458. get
  459. {
  460. IntPtr ptr = Sdk.HP_Agent_GetLastErrorDesc(pAgent);
  461. string desc = Marshal.PtrToStringUni(ptr);
  462. return desc;
  463. }
  464. }
  465. /// <summary>
  466. /// 获取连接中未发出数据的长度
  467. /// </summary>
  468. /// <param name="connId"></param>
  469. /// <param name="length"></param>
  470. /// <returns></returns>
  471. public bool GetPendingDataLength(IntPtr connId, ref int length)
  472. {
  473. return Sdk.HP_Agent_GetPendingDataLength(pAgent, connId, ref length);
  474. }
  475. // 是否启动
  476. public bool IsStarted
  477. {
  478. get
  479. {
  480. if (pAgent == IntPtr.Zero)
  481. {
  482. return false;
  483. }
  484. return Sdk.HP_Agent_HasStarted(pAgent);
  485. }
  486. }
  487. /// <summary>
  488. /// 状态
  489. /// </summary>
  490. public ServiceState State
  491. {
  492. get
  493. {
  494. return Sdk.HP_Agent_GetState(pAgent);
  495. }
  496. }
  497. public uint ConnectionCount
  498. {
  499. get
  500. {
  501. return Sdk.HP_Agent_GetConnectionCount(pAgent);
  502. }
  503. }
  504. /// <summary>
  505. /// 获取所有连接,未获取到连接返回null
  506. /// </summary>
  507. /// <returns></returns>
  508. public IntPtr[] GetAllConnectionIDs()
  509. {
  510. IntPtr[] arr = null;
  511. do
  512. {
  513. uint count = ConnectionCount;
  514. if (count == 0)
  515. {
  516. break;
  517. }
  518. arr = new IntPtr[count];
  519. if (Sdk.HP_Agent_GetAllConnectionIDs(pAgent, arr, ref count))
  520. {
  521. if (arr.Length > count)
  522. {
  523. IntPtr[] newArr = new IntPtr[count];
  524. Array.Copy(arr, newArr, count);
  525. arr = newArr;
  526. }
  527. break;
  528. }
  529. } while (true);
  530. return arr;
  531. }
  532. /// <summary>
  533. /// 获取某个连接的本地地址信息
  534. /// </summary>
  535. /// <param name="ip"></param>
  536. /// <param name="port"></param>
  537. /// <returns></returns>
  538. public bool GetLocalAddress(IntPtr connId, ref string ip, ref ushort port)
  539. {
  540. int ipLength = 40;
  541. StringBuilder sb = new StringBuilder(ipLength);
  542. bool ret = Sdk.HP_Agent_GetLocalAddress(pAgent, connId, sb, ref ipLength, ref port);
  543. if (ret == true)
  544. {
  545. ip = sb.ToString();
  546. }
  547. return ret;
  548. }
  549. /// <summary>
  550. /// 获取某个连接的远程地址信息
  551. /// </summary>
  552. /// <returns></returns>
  553. public bool GetRemoteAddress(IntPtr connId, ref string ip, ref ushort port)
  554. {
  555. int ipLength = 40;
  556. StringBuilder sb = new StringBuilder(ipLength);
  557. bool ret = Sdk.HP_Agent_GetRemoteAddress(pAgent, connId, sb, ref ipLength, ref port);
  558. if (ret == true)
  559. {
  560. ip = sb.ToString();
  561. }
  562. return ret;
  563. }
  564. /// <summary>
  565. /// 获取指定连接的连接时长(毫秒)
  566. /// </summary>
  567. /// <param name="connId"></param>
  568. /// <param name="period"></param>
  569. /// <returns></returns>
  570. public bool GetConnectPeriod(IntPtr connId, ref uint period)
  571. {
  572. return Sdk.HP_Agent_GetConnectPeriod(pAgent, connId, ref period);
  573. }
  574. /// <summary>
  575. /// 获取某个连接静默时间(毫秒)
  576. /// </summary>
  577. /// <param name="connId"></param>
  578. /// <param name="period"></param>
  579. /// <returns></returns>
  580. public bool GetSilencePeriod(IntPtr connId, ref uint period)
  581. {
  582. return Sdk.HP_Agent_GetSilencePeriod(pAgent, connId, ref period);
  583. }
  584. ///////////////////////////////////////////////////////////////////////////////////////
  585. /// <summary>
  586. /// 获取或设置是否启用地址重用机制(默认:不启用)
  587. /// </summary>
  588. public bool IsReuseAddress
  589. {
  590. get
  591. {
  592. return Sdk.HP_TcpAgent_IsReuseAddress(pAgent);
  593. }
  594. set
  595. {
  596. Sdk.HP_TcpAgent_SetReuseAddress(pAgent, value);
  597. }
  598. }
  599. /// <summary>
  600. /// 设置最大连接数(组件会根据设置值预分配内存,因此需要根据实际情况设置,不宜过大)
  601. /// </summary>
  602. public uint MaxConnectionCount
  603. {
  604. get
  605. {
  606. return Sdk.HP_Agent_GetMaxConnectionCount(pAgent);
  607. }
  608. set
  609. {
  610. Sdk.HP_Agent_SetMaxConnectionCount(pAgent, value);
  611. }
  612. }
  613. /// <summary>
  614. /// 读取或设置工作线程数量(通常设置为 2 * CPU + 2)
  615. /// </summary>
  616. public uint WorkerThreadCount
  617. {
  618. get
  619. {
  620. return Sdk.HP_Agent_GetWorkerThreadCount(pAgent);
  621. }
  622. set
  623. {
  624. Sdk.HP_Agent_SetWorkerThreadCount(pAgent, value);
  625. }
  626. }
  627. /// <summary>
  628. /// 读取或设置通信数据缓冲区大小(根据平均通信数据包大小调整设置,通常设置为 1024 的倍数)
  629. /// </summary>
  630. public uint SocketBufferSize
  631. {
  632. get
  633. {
  634. return Sdk.HP_TcpAgent_GetSocketBufferSize(pAgent);
  635. }
  636. set
  637. {
  638. Sdk.HP_TcpAgent_SetSocketBufferSize(pAgent, value);
  639. }
  640. }
  641. /// <summary>
  642. /// 读取或设置 Socket 缓存对象锁定时间(毫秒,在锁定期间该 Socket 缓存对象不能被获取使用)
  643. /// </summary>
  644. public uint FreeSocketObjLockTime
  645. {
  646. get
  647. {
  648. return Sdk.HP_Agent_GetFreeSocketObjLockTime(pAgent);
  649. }
  650. set
  651. {
  652. Sdk.HP_Agent_SetFreeSocketObjLockTime(pAgent, value);
  653. }
  654. }
  655. /// <summary>
  656. /// 读取或设置 Socket 缓存池大小(通常设置为平均并发连接数量的 1/3 - 1/2)
  657. /// </summary>
  658. public uint FreeSocketObjPool
  659. {
  660. get
  661. {
  662. return Sdk.HP_Agent_GetFreeSocketObjPool(pAgent);
  663. }
  664. set
  665. {
  666. Sdk.HP_Agent_SetFreeSocketObjPool(pAgent, value);
  667. }
  668. }
  669. /// <summary>
  670. /// 读取或设置内存块缓存池大小(通常设置为 Socket 缓存池大小的 2 - 3 倍)
  671. /// </summary>
  672. public uint FreeBufferObjPool
  673. {
  674. get
  675. {
  676. return Sdk.HP_Agent_GetFreeBufferObjPool(pAgent);
  677. }
  678. set
  679. {
  680. Sdk.HP_Agent_SetFreeBufferObjPool(pAgent, value);
  681. }
  682. }
  683. /// <summary>
  684. /// 读取或设置 Socket 缓存池回收阀值(通常设置为 Socket 缓存池大小的 3 倍)
  685. /// </summary>
  686. public uint FreeSocketObjHold
  687. {
  688. get
  689. {
  690. return Sdk.HP_Agent_GetFreeSocketObjHold(pAgent);
  691. }
  692. set
  693. {
  694. Sdk.HP_Agent_SetFreeSocketObjHold(pAgent, value);
  695. }
  696. }
  697. /// <summary>
  698. /// 读取或设置内存块缓存池回收阀值(通常设置为内存块缓存池大小的 3 倍)
  699. /// </summary>
  700. public uint FreeBufferObjHold
  701. {
  702. get
  703. {
  704. return Sdk.HP_Agent_GetFreeBufferObjHold(pAgent);
  705. }
  706. set
  707. {
  708. Sdk.HP_Agent_SetFreeBufferObjHold(pAgent, value);
  709. }
  710. }
  711. /// <summary>
  712. /// 读取或设置心跳包间隔(毫秒,0 则不发送心跳包))
  713. /// </summary>
  714. public uint KeepAliveTime
  715. {
  716. get
  717. {
  718. return Sdk.HP_TcpAgent_GetKeepAliveTime(pAgent);
  719. }
  720. set
  721. {
  722. Sdk.HP_TcpAgent_SetKeepAliveTime(pAgent, value);
  723. }
  724. }
  725. /// <summary>
  726. /// 读取或设置心跳确认包检测间隔(毫秒,0 不发送心跳包,如果超过若干次 [默认:WinXP 5 次, Win7 10 次] 检测不到心跳确认包则认为已断线)
  727. /// </summary>
  728. public uint KeepAliveInterval
  729. {
  730. get
  731. {
  732. return Sdk.HP_TcpAgent_GetKeepAliveInterval(pAgent);
  733. }
  734. set
  735. {
  736. Sdk.HP_TcpAgent_SetKeepAliveInterval(pAgent, value);
  737. }
  738. }
  739. /// <summary>
  740. /// 读取或设置是否标记静默时间(设置为 TRUE 时 DisconnectSilenceConnections() 和 GetSilencePeriod() 才有效,默认:FALSE)
  741. /// </summary>
  742. public bool IsMarkSilence
  743. {
  744. get
  745. {
  746. return Sdk.HP_Agent_IsMarkSilence(pAgent);
  747. }
  748. set
  749. {
  750. Sdk.HP_Agent_SetMarkSilence(pAgent, value);
  751. }
  752. }
  753. /// <summary>
  754. /// 读取或设置数据发送策略
  755. /// </summary>
  756. public SendPolicy SendPolicy
  757. {
  758. get
  759. {
  760. return Sdk.HP_Agent_GetSendPolicy(pAgent);
  761. }
  762. set
  763. {
  764. Sdk.HP_Agent_SetSendPolicy(pAgent, value);
  765. }
  766. }
  767. /// <summary>
  768. /// 根据错误码返回错误信息
  769. /// </summary>
  770. /// <param name="code"></param>
  771. /// <returns></returns>
  772. public string GetSocketErrorDesc(SocketError code)
  773. {
  774. IntPtr ptr = Sdk.HP_GetSocketErrorDesc(code);
  775. string desc = Marshal.PtrToStringUni(ptr);
  776. return desc;
  777. }
  778. ///////////////////////////////////////////////////////////////////////////////////////
  779. Sdk.OnPrepareConnect _OnPrepareConnect = null;
  780. Sdk.OnConnect _OnConnect = null;
  781. Sdk.OnReceive _OnReceive = null;
  782. Sdk.OnSend _OnSend = null;
  783. Sdk.OnClose _OnClose = null;
  784. Sdk.OnShutdown _OnShutdown = null;
  785. /// <summary>
  786. /// 设置回调函数
  787. /// </summary>
  788. protected virtual void SetCallback()
  789. {
  790. _OnPrepareConnect = new Sdk.OnPrepareConnect(SDK_OnPrepareConnect);
  791. _OnConnect = new Sdk.OnConnect(SDK_OnConnect);
  792. _OnSend = new Sdk.OnSend(SDK_OnSend);
  793. _OnReceive = new Sdk.OnReceive(SDK_OnReceive);
  794. _OnClose = new Sdk.OnClose(SDK_OnClose);
  795. _OnShutdown = new Sdk.OnShutdown(SDK_OnShutdown);
  796. // 设置 Socket 监听器回调函数
  797. Sdk.HP_Set_FN_Agent_OnPrepareConnect(pListener, _OnPrepareConnect);
  798. Sdk.HP_Set_FN_Agent_OnConnect(pListener, _OnConnect);
  799. Sdk.HP_Set_FN_Server_OnSend(pListener, _OnSend);
  800. Sdk.HP_Set_FN_Server_OnReceive(pListener, _OnReceive);
  801. Sdk.HP_Set_FN_Server_OnClose(pListener, _OnClose);
  802. Sdk.HP_Set_FN_Agent_OnShutdown(pListener, _OnShutdown);
  803. }
  804. protected virtual HandleResult SDK_OnPrepareConnect(IntPtr connId, uint socket)
  805. {
  806. if (OnPrepareConnect != null)
  807. {
  808. return OnPrepareConnect(connId, socket);
  809. }
  810. return HandleResult.Ignore;
  811. }
  812. protected virtual HandleResult SDK_OnConnect(IntPtr connId)
  813. {
  814. if (OnConnect != null)
  815. {
  816. return OnConnect(connId);
  817. }
  818. return HandleResult.Ignore;
  819. }
  820. protected virtual HandleResult SDK_OnSend(IntPtr connId, IntPtr pData, int length)
  821. {
  822. if (OnSend != null)
  823. {
  824. byte[] bytes = new byte[length];
  825. Marshal.Copy(pData, bytes, 0, length);
  826. return OnSend(connId, bytes);
  827. }
  828. return HandleResult.Ignore;
  829. }
  830. protected virtual HandleResult SDK_OnReceive(IntPtr connId, IntPtr pData, int length)
  831. {
  832. if (OnPointerDataReceive != null)
  833. {
  834. return OnPointerDataReceive(connId, pData, length);
  835. }
  836. else if (OnReceive != null)
  837. {
  838. byte[] bytes = new byte[length];
  839. Marshal.Copy(pData, bytes, 0, length);
  840. return OnReceive(connId, bytes);
  841. }
  842. return HandleResult.Ignore;
  843. }
  844. protected virtual HandleResult SDK_OnClose(IntPtr connId, SocketOperation enOperation, int errorCode)
  845. {
  846. if (OnClose != null)
  847. {
  848. return OnClose(connId, enOperation, errorCode);
  849. }
  850. return HandleResult.Ignore;
  851. }
  852. protected virtual HandleResult SDK_OnShutdown()
  853. {
  854. if (OnShutdown != null)
  855. {
  856. return OnShutdown();
  857. }
  858. return HandleResult.Ignore;
  859. }
  860. /////////////////////////////////////////////////////////////////////////
  861. /// <summary>
  862. /// 获取系统返回的错误码
  863. /// </summary>
  864. /// <returns></returns>
  865. public int SYSGetLastError()
  866. {
  867. return Sdk.SYS_GetLastError();
  868. }
  869. /// <summary>
  870. /// 调用系统的 ::WSAGetLastError() 方法获取通信错误代码
  871. /// </summary>
  872. /// <returns></returns>
  873. public int SYSWSAGetLastError()
  874. {
  875. return Sdk.SYS_WSAGetLastError();
  876. }
  877. /// <summary>
  878. /// 调用系统的 setsockopt()
  879. /// </summary>
  880. /// <param name="sock"></param>
  881. /// <param name="level"></param>
  882. /// <param name="name"></param>
  883. /// <param name="val"></param>
  884. /// <param name="len"></param>
  885. /// <returns></returns>
  886. ///
  887. public int SYS_SetSocketOption(IntPtr sock, int level, int name, IntPtr val, int len)
  888. {
  889. return Sdk.SYS_SetSocketOption(sock, level, name, val, len);
  890. }
  891. /// <summary>
  892. /// 调用系统的 getsockopt()
  893. /// </summary>
  894. /// <param name="sock"></param>
  895. /// <param name="level"></param>
  896. /// <param name="name"></param>
  897. /// <param name="val"></param>
  898. /// <param name="len"></param>
  899. /// <returns></returns>
  900. ///
  901. public int SYSGetSocketOption(IntPtr sock, int level, int name, IntPtr val, ref int len)
  902. {
  903. return Sdk.SYS_GetSocketOption(sock, level, name, val, ref len);
  904. }
  905. /// <summary>
  906. /// 调用系统的 ioctlsocket()
  907. /// </summary>
  908. /// <param name="sock"></param>
  909. /// <param name="cmd"></param>
  910. /// <param name="arg"></param>
  911. /// <returns></returns>
  912. ///
  913. public int SYSIoctlSocket(IntPtr sock, long cmd, IntPtr arg)
  914. {
  915. return Sdk.SYS_IoctlSocket(sock, cmd, arg);
  916. }
  917. /// <summary>
  918. /// 调用系统的 ::WSAIoctl()
  919. /// </summary>
  920. /// <param name="sock"></param>
  921. /// <param name="dwIoControlCode"></param>
  922. /// <param name="lpvInBuffer"></param>
  923. /// <param name="cbInBuffer"></param>
  924. /// <param name="lpvOutBuffer"></param>
  925. /// <param name="cbOutBuffer"></param>
  926. /// <param name="lpcbBytesReturned"></param>
  927. /// <returns></returns>
  928. public int SYS_WSAIoctl(IntPtr sock, uint dwIoControlCode, IntPtr lpvInBuffer, uint cbInBuffer,
  929. IntPtr lpvOutBuffer, uint cbOutBuffer, uint lpcbBytesReturned)
  930. {
  931. return Sdk.SYS_WSAIoctl(sock, dwIoControlCode, lpvInBuffer, cbInBuffer,
  932. lpvOutBuffer, cbOutBuffer, lpcbBytesReturned);
  933. }
  934. /// <summary>
  935. /// 由结构体转换为byte数组
  936. /// </summary>
  937. public byte[] StructureToByte<T>(T structure)
  938. {
  939. int size = Marshal.SizeOf(typeof(T));
  940. byte[] buffer = new byte[size];
  941. IntPtr bufferIntPtr = Marshal.AllocHGlobal(size);
  942. try
  943. {
  944. Marshal.StructureToPtr(structure, bufferIntPtr, true);
  945. Marshal.Copy(bufferIntPtr, buffer, 0, size);
  946. }
  947. finally
  948. {
  949. Marshal.FreeHGlobal(bufferIntPtr);
  950. }
  951. return buffer;
  952. }
  953. /// <summary>
  954. /// 由byte数组转换为结构体
  955. /// </summary>
  956. public T ByteToStructure<T>(byte[] dataBuffer)
  957. {
  958. object structure = null;
  959. int size = Marshal.SizeOf(typeof(T));
  960. IntPtr allocIntPtr = Marshal.AllocHGlobal(size);
  961. try
  962. {
  963. Marshal.Copy(dataBuffer, 0, allocIntPtr, size);
  964. structure = Marshal.PtrToStructure(allocIntPtr, typeof(T));
  965. }
  966. finally
  967. {
  968. Marshal.FreeHGlobal(allocIntPtr);
  969. }
  970. return (T)structure;
  971. }
  972. /// <summary>
  973. /// 对象序列化成byte[]
  974. /// </summary>
  975. /// <param name="obj"></param>
  976. /// <returns></returns>
  977. public byte[] ObjectToBytes(object obj)
  978. {
  979. using (MemoryStream ms = new MemoryStream())
  980. {
  981. IFormatter formatter = new BinaryFormatter();
  982. formatter.Serialize(ms, obj);
  983. return ms.GetBuffer();
  984. }
  985. }
  986. /// <summary>
  987. /// byte[]序列化成对象
  988. /// </summary>
  989. /// <param name="Bytes"></param>
  990. /// <returns></returns>
  991. public object BytesToObject(byte[] bytes)
  992. {
  993. using (MemoryStream ms = new MemoryStream(bytes))
  994. {
  995. IFormatter formatter = new BinaryFormatter();
  996. return formatter.Deserialize(ms);
  997. }
  998. }
  999. /// <summary>
  1000. /// byte[]转结构体
  1001. /// </summary>
  1002. /// <typeparam name="T"></typeparam>
  1003. /// <param name="bytes"></param>
  1004. /// <returns></returns>
  1005. public T BytesToStruct<T>(byte[] bytes)
  1006. {
  1007. Type strcutType = typeof(T);
  1008. int size = Marshal.SizeOf(strcutType);
  1009. IntPtr buffer = Marshal.AllocHGlobal(size);
  1010. try
  1011. {
  1012. Marshal.Copy(bytes, 0, buffer, size);
  1013. return (T)Marshal.PtrToStructure(buffer, strcutType);
  1014. }
  1015. finally
  1016. {
  1017. Marshal.FreeHGlobal(buffer);
  1018. }
  1019. }
  1020. }
  1021. }