TcpAgent.cs 42 KB

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