TcpAgent.cs 34 KB

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