TcpServer.cs 35 KB

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