TCP_NetworkServer.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Net;
  5. using System.Net.Sockets;
  6. using System.Threading;
  7. using System.Management;
  8. using HPSocketCS.Extended;
  9. using System.Runtime.InteropServices;
  10. namespace HPNetwork.TCPNetworkServer
  11. {
  12. #region 在线用户列表 2017/07/03
  13. /// <summary>
  14. /// 在线用户列表;
  15. /// </summary>
  16. public struct OnlineUser
  17. {
  18. public IntPtr ConnId;
  19. public string strBranchId;
  20. public DateTime dtQueryTask;
  21. public DateTime dtQueryNeedDownload;
  22. public DateTime dtQueryBranchDetail;
  23. }
  24. #endregion
  25. /// <summary>
  26. /// TCP网络通信服务端
  27. /// </summary>
  28. public class TCP_NetworkServer
  29. {
  30. #region 在线用户列表 2017/07/03
  31. /// <summary>
  32. /// 在线用户列表;
  33. /// </summary>
  34. private List<OnlineUser> onlineuserlist = new List<OnlineUser>();
  35. /// <summary>
  36. /// 在线用户列表;
  37. /// </summary>
  38. public List<OnlineUser> OnlineUserList
  39. {
  40. get { return onlineuserlist; }
  41. set { onlineuserlist = value; }
  42. }
  43. public bool IsOnlineUserExists(string branchId)
  44. {
  45. bool bExists = false;
  46. foreach ( OnlineUser user in OnlineUserList )
  47. {
  48. if (branchId == user.strBranchId)
  49. {
  50. bExists = true;
  51. break;
  52. }
  53. }
  54. return bExists;
  55. }
  56. public void AddOnlineUser(IntPtr connId, string branchId)
  57. {
  58. if (IsOnlineUserExists(branchId))
  59. return;
  60. OnlineUser user = new OnlineUser
  61. {
  62. ConnId = connId,
  63. strBranchId = branchId,
  64. dtQueryTask = DateTime.Now,
  65. dtQueryNeedDownload = DateTime.Now,
  66. dtQueryBranchDetail = DateTime.Now
  67. };
  68. OnlineUserList.Add(user);
  69. }
  70. public void RemoveOnlineUser(IntPtr connId)
  71. {
  72. foreach (OnlineUser user in OnlineUserList)
  73. {
  74. if (connId == user.ConnId)
  75. {
  76. onlineuserlist.Remove(user);
  77. break;
  78. }
  79. }
  80. }
  81. public void RemoveOnlineUser(string branchId)
  82. {
  83. foreach (OnlineUser user in OnlineUserList)
  84. {
  85. if (branchId == user.strBranchId)
  86. {
  87. onlineuserlist.Remove(user);
  88. break;
  89. }
  90. }
  91. }
  92. public bool IsQueryTaskTimeOut(IntPtr connId)
  93. {
  94. for (int i = 0; i < OnlineUserList.Count; i++ )
  95. {
  96. OnlineUser user = OnlineUserList[i];
  97. if (connId == user.ConnId)
  98. {
  99. TimeSpan tSpan = DateTime.Now - user.dtQueryTask;
  100. if (tSpan.TotalMilliseconds > 15000)
  101. {
  102. user.dtQueryTask = DateTime.Now;
  103. return true;
  104. }
  105. }
  106. }
  107. return false;
  108. }
  109. public bool IsQueryNeedDownloadTimeOut(IntPtr connId)
  110. {
  111. for (int i = 0; i < OnlineUserList.Count; i++)
  112. {
  113. OnlineUser user = OnlineUserList[i];
  114. if (connId == user.ConnId)
  115. {
  116. TimeSpan tSpan = DateTime.Now - user.dtQueryNeedDownload;
  117. if (tSpan.TotalMilliseconds > 15000)
  118. {
  119. user.dtQueryNeedDownload = DateTime.Now;
  120. return true;
  121. }
  122. }
  123. }
  124. return false;
  125. }
  126. public bool IsQueryBranchDetailTimeOut(IntPtr connId)
  127. {
  128. for (int i = 0; i < OnlineUserList.Count; i++)
  129. {
  130. OnlineUser user = OnlineUserList[i];
  131. if (connId == user.ConnId)
  132. {
  133. TimeSpan tSpan = DateTime.Now - user.dtQueryBranchDetail;
  134. if (tSpan.TotalMilliseconds > 15000)
  135. {
  136. user.dtQueryBranchDetail = DateTime.Now;
  137. return true;
  138. }
  139. }
  140. }
  141. return false;
  142. }
  143. #endregion
  144. public TCP_NetworkServer()
  145. {
  146. }
  147. public TCP_NetworkServer(HPSocketCS.Extended.CustomTraceListener _traceListenerLog)
  148. {
  149. this.TraceListenerLog = _traceListenerLog;
  150. }
  151. #region 网络程序处理代码
  152. private AppState appState = AppState.Stoped;
  153. public HPSocketCS.TcpPackServer hp_Server = new HPSocketCS.TcpPackServer();
  154. HPSocketCS.Extended.CustomTraceListener _TraceListenerLog = null;
  155. /// <summary>
  156. /// 服务器运行日志跟踪侦听器
  157. /// </summary>
  158. public HPSocketCS.Extended.CustomTraceListener TraceListenerLog
  159. {
  160. get { return _TraceListenerLog; }
  161. set { _TraceListenerLog = value; }
  162. }
  163. /// <summary>
  164. /// 启动网络
  165. /// </summary>
  166. /// <param name="ip"></param>
  167. /// <param name="port"></param>
  168. public void StartRun(string ip = "0.0.0.0", ushort port = 8500)
  169. {
  170. try
  171. {
  172. if (!this.isInitializesNetwork)
  173. {
  174. this.InitializesNetwork();
  175. }
  176. ServerStartTimeStamp = "1492583059892";//DateTime.Now.ToString("yyyyMMddHHmmsss");
  177. // 写在这个位置是上面可能会异常
  178. SetAppState(AppState.Starting);
  179. hp_Server.IpAddress = ip;
  180. hp_Server.Port = port;
  181. // 启动服务
  182. if (hp_Server.Start())
  183. {
  184. SetAppState(AppState.Started);
  185. SystemFileLogs.WriteLogs("服务器网络启动成功 IP:" + ip + ":" + port.ToString(), this.TraceListenerLog);
  186. }
  187. else
  188. {
  189. SetAppState(AppState.Stoped);
  190. throw new Exception(string.Format("$绑定套接字失败(套接字绑定),可能是端口“" + port.ToString() + "”被占用 -> {0}({1})", hp_Server.ErrorMessage, hp_Server.ErrorCode));
  191. }
  192. }
  193. catch (Exception ex)
  194. {
  195. SystemFileLogs.WriteLogs("服务器网络启动失败:" + ex.Message, this.TraceListenerLog);
  196. }
  197. }
  198. public void StopRun()
  199. {
  200. try
  201. {
  202. if (this.IsInitializesNetwork)
  203. {
  204. SetAppState(AppState.Stoping);
  205. // 停止服务
  206. SystemFileLogs.WriteLogs("服务器网络停止服务", this.TraceListenerLog);
  207. if (hp_Server.Stop())
  208. {
  209. SetAppState(AppState.Stoped);
  210. }
  211. else
  212. {
  213. SystemFileLogs.WriteLogs("服务器网络停止服务时出错:" + hp_Server.ErrorMessage + "(" + hp_Server.ErrorCode + ")", this.TraceListenerLog);
  214. }
  215. }
  216. }
  217. catch { }
  218. }
  219. bool isInitializesNetwork = false;
  220. /// <summary>
  221. /// 网络服务是否已初始化
  222. /// </summary>
  223. public bool IsInitializesNetwork
  224. {
  225. get { return isInitializesNetwork; }
  226. set { isInitializesNetwork = value; }
  227. }
  228. /// <summary>
  229. /// 初始化网络
  230. /// </summary>
  231. void InitializesNetwork()
  232. {
  233. try
  234. {
  235. // 设置服务器事件
  236. hp_Server.OnPrepareListen += new HPSocketCS.TcpServerEvent.OnPrepareListenEventHandler(OnPrepareListen);
  237. hp_Server.OnAccept += new HPSocketCS.TcpServerEvent.OnAcceptEventHandler(OnAccept);
  238. hp_Server.OnSend += new HPSocketCS.TcpServerEvent.OnSendEventHandler(OnSend);
  239. hp_Server.OnReceive += new HPSocketCS.TcpServerEvent.OnReceiveEventHandler(OnReceive);
  240. hp_Server.OnClose += new HPSocketCS.TcpServerEvent.OnCloseEventHandler(OnClose);
  241. hp_Server.OnShutdown += new HPSocketCS.TcpServerEvent.OnShutdownEventHandler(OnShutdown);
  242. // 设置包头标识,与对端设置保证一致性
  243. hp_Server.PackHeaderFlag = 0x1ff;
  244. // 设置最大封包大小
  245. hp_Server.MaxPackSize = 0x2000 * 32;
  246. hp_Server.SocketBufferSize = 512 * 1024;//hp_Server.MaxPackSize;
  247. this.isInitializesNetwork = true;
  248. SystemFileLogs.WriteLogs("服务器初始化网络成功", this.TraceListenerLog);
  249. SetAppState(AppState.Stoped);
  250. }
  251. catch (Exception ex)
  252. {
  253. SetAppState(AppState.Error);
  254. SystemFileLogs.WriteLogs("服务器初始化网络时出错:" + ex.Message, this.TraceListenerLog);
  255. }
  256. }
  257. /// <summary>
  258. /// 准备监听了事件
  259. /// </summary>
  260. /// <param name="soListen"></param>
  261. /// <returns></returns>
  262. HPSocketCS.HandleResult OnPrepareListen(IntPtr soListen)
  263. {
  264. // 监听事件到达了,一般没什么用吧?
  265. SystemFileLogs.WriteLogs("服务器已成功开始网络侦听...", this.TraceListenerLog);
  266. return HPSocketCS.HandleResult.Ok;
  267. }
  268. /// <summary>
  269. /// 连接到达事件
  270. /// </summary>
  271. /// <param name="connId"></param>
  272. /// <param name="pClient"></param>
  273. /// <returns></returns>
  274. HPSocketCS.HandleResult OnAccept(IntPtr connId, IntPtr pClient)
  275. {
  276. // 客户进入了
  277. // 获取客户端ip和端口
  278. string ip = string.Empty;
  279. ushort port = 0;
  280. if (hp_Server.GetRemoteAddress(connId, ref ip, ref port))
  281. {
  282. SystemFileLogs.WriteLogs("收接连接请求:" + ip + ":" + port.ToString(), this.TraceListenerLog);
  283. }
  284. else
  285. {
  286. SystemFileLogs.WriteLogs("获取某个连接的ip和端口时出错", this.TraceListenerLog);
  287. return HPSocketCS.HandleResult.Error;
  288. }
  289. // 设置附加数据
  290. HPSocketCS.Extended.ClientInfo ci = new HPSocketCS.Extended.ClientInfo();
  291. ci.ConnId = connId;
  292. ci.IpAddress = ip;
  293. ci.Port = port;
  294. if (hp_Server.SetConnectionExtra(connId, ci) == false)
  295. {
  296. SystemFileLogs.WriteLogs("设置连接的附加数据失败,IP地址为 " + ip + ":" + port.ToString(), this.TraceListenerLog);
  297. return HPSocketCS.HandleResult.Error;
  298. }
  299. return HPSocketCS.HandleResult.Ok;
  300. }
  301. /// <summary>
  302. /// 数据包发送事件
  303. /// </summary>
  304. /// <param name="connId"></param>
  305. /// <param name="bytes"></param>
  306. /// <returns></returns>
  307. HPSocketCS.HandleResult OnSend(IntPtr connId, byte[] bytes)
  308. {
  309. // 服务器发数据了
  310. return HPSocketCS.HandleResult.Ok;
  311. }
  312. /// <summary>
  313. /// 数据到达
  314. /// </summary>
  315. /// <param name="connId"></param>
  316. /// <param name="bytes"></param>
  317. /// <returns></returns>
  318. HPSocketCS.HandleResult OnReceive(IntPtr connId, byte[] bytes)
  319. {
  320. // 数据到达了
  321. try
  322. {
  323. bool retProcessed = true;//处理情况
  324. //收到的数据
  325. byte[] receiveBytes = new byte[0];
  326. TcpHeadInfo header = hp_Server.BytesToStruct<TcpHeadInfo>(bytes);
  327. DataType dType = (DataType)header.MsgDataType;
  328. int headSize = Marshal.SizeOf(header);
  329. TcpTailInfo tail = new TcpTailInfo();
  330. if (header.IsTail)
  331. {
  332. //有附加尾数据时
  333. int tailSize = Marshal.SizeOf(tail);
  334. byte[] tailBytes = new byte[tailSize];
  335. Array.ConstrainedCopy(bytes, bytes.Length - tailSize, tailBytes, 0, tailBytes.Length);
  336. tail = hp_Server.BytesToStruct<TcpTailInfo>(tailBytes);
  337. receiveBytes = new byte[bytes.Length - headSize - tailSize];
  338. Array.ConstrainedCopy(bytes, headSize, receiveBytes, 0, receiveBytes.Length);
  339. tailBytes = null;
  340. }
  341. else
  342. {
  343. // 因为没有附加尾数据,所以大小可以用length - objSize
  344. receiveBytes = new byte[bytes.Length - headSize];
  345. Array.ConstrainedCopy(bytes, headSize, receiveBytes, 0, receiveBytes.Length);
  346. }
  347. bytes = null;
  348. //接收到的客户端发送来的数据
  349. byte[] recbytes = null;
  350. try
  351. {
  352. if (header.TransportStart && header.TransportEnd)
  353. {
  354. recbytes = receiveBytes;
  355. receiveBytes = null;
  356. }
  357. else
  358. {
  359. ReceiveData rData = hp_Server.SCommonLibrary.GetReceiveData(header);
  360. if (rData == null)
  361. {
  362. rData = new ReceiveData();
  363. hp_Server.SCommonLibrary.AddReceiveData(rData);
  364. }
  365. rData.ReceiveRemoteClientInfo = header;
  366. rData.ReceiveDataMstream.Write(receiveBytes, 0, receiveBytes.Length);
  367. if (header.TransportEnd)
  368. {
  369. rData.ReceiveDataMstream.Position = 0;
  370. //recbytes = rData.ReceiveDataMstream.ToArray();
  371. recbytes = new byte[rData.ReceiveDataMstream.Length];
  372. rData.ReceiveDataMstream.Read(recbytes, 0, recbytes.Length);
  373. hp_Server.SCommonLibrary.RemoveReceiveDataData(rData);
  374. }
  375. }
  376. if (recbytes != null)
  377. {
  378. recbytes = HPSocketCS.Extended.DataSetSerializerDeserialize.DataDecompressRetBytes(recbytes);
  379. switch (dType)
  380. {
  381. case DataType.File:
  382. FileRequestType RequestType = (FileRequestType)tail.RequestType;
  383. if (this.EventFileDataRequest != null)
  384. {
  385. this.EventFileDataRequest(hp_Server, header, tail, connId, recbytes);
  386. }
  387. switch (RequestType)
  388. {
  389. case FileRequestType.Upload:
  390. //接收文件
  391. retProcessed = hp_Server.ReceiveFileToServerRootDirectory(tail, recbytes);
  392. break;
  393. case FileRequestType.Download:
  394. //发送文件
  395. retProcessed = hp_Server.SenFileToClient(header, tail, connId);
  396. break;
  397. }
  398. break;
  399. case DataType.SQLHelper:
  400. case DataType.Serialization:
  401. if (this.EventSerializationDataRequest != null)
  402. {
  403. this.EventSerializationDataRequest(hp_Server, header, connId, recbytes);
  404. }
  405. break;
  406. case DataType.List:
  407. break;
  408. case DataType.Array:
  409. break;
  410. case DataType.None:
  411. break;
  412. }
  413. }
  414. }
  415. finally
  416. {
  417. try
  418. {
  419. System.Array.Clear(recbytes, 0, recbytes.Length);
  420. }
  421. catch { }
  422. recbytes = null;
  423. }
  424. if (retProcessed)
  425. {
  426. return HPSocketCS.HandleResult.Ok;
  427. }
  428. else
  429. {
  430. //return HandleResult.Error;
  431. return HPSocketCS.HandleResult.Ignore;
  432. }
  433. }
  434. catch (Exception ex)
  435. {
  436. SystemFileLogs.WriteLogs("接收数据时出错:" + ex.Message, this.TraceListenerLog);
  437. return HPSocketCS.HandleResult.Ignore;
  438. }
  439. finally
  440. {
  441. System.GC.Collect();
  442. }
  443. }
  444. /// <summary>
  445. /// 连接关闭事件
  446. /// </summary>
  447. /// <param name="connId"></param>
  448. /// <param name="enOperation"></param>
  449. /// <param name="errorCode"></param>
  450. /// <returns></returns>
  451. HPSocketCS.HandleResult OnClose(IntPtr connId, HPSocketCS.SocketOperation enOperation, int errorCode)
  452. {
  453. // 移除在线用户;
  454. RemoveOnlineUser(connId);
  455. if (errorCode == 0)
  456. {
  457. HPSocketCS.Extended.ClientInfo cInfo = hp_Server.GetClientInfo(connId);
  458. if (cInfo != null)
  459. {
  460. SystemFileLogs.WriteLogs(String.Format("ID为{0}的连接已关闭,IP:{1}:{2}", connId, cInfo.IpAddress, cInfo.Port), this.TraceListenerLog);
  461. }
  462. else {
  463. SystemFileLogs.WriteLogs(String.Format("ID为{0}的连接已关闭", connId), this.TraceListenerLog);
  464. }
  465. }
  466. else if (enOperation == HPSocketCS.SocketOperation.Close)
  467. {
  468. SystemFileLogs.WriteLogs(String.Format("客户端已关闭连接 > [{0},OnError] -> OP:{1},CODE:{2}", connId, enOperation, errorCode), this.TraceListenerLog);
  469. }
  470. else
  471. {
  472. SystemFileLogs.WriteLogs(String.Format("连接出错 > [{0},OnError] -> OP:{1},CODE:{2}", connId, enOperation, errorCode), this.TraceListenerLog);
  473. // return HPSocketSdk.HandleResult.Ok;
  474. return HPSocketCS.HandleResult.Error;
  475. }
  476. //hp_Server.SCommonLibrary.ClearInvalidConnectionResource(connId);
  477. //if (hp_Server.SetConnectionExtra(connId, null) == false)
  478. //{
  479. // SystemFileLogs.WriteLogs("清除连接的附加数据失败:" + errorCode, this.TraceListenerLog);
  480. //}
  481. return HPSocketCS.HandleResult.Ok;
  482. }
  483. /// <summary>
  484. /// 服务器关闭事件
  485. /// </summary>
  486. /// <returns></returns>
  487. HPSocketCS.HandleResult OnShutdown()
  488. {
  489. // 服务关闭了
  490. hp_Server.SCommonLibrary.ClearAllInvalidResource();
  491. return HPSocketCS.HandleResult.Ok;
  492. }
  493. /// <summary>
  494. /// 设置程序状态
  495. /// </summary>
  496. /// <param name="state"></param>
  497. void SetAppState(AppState state)
  498. {
  499. appState = state;
  500. }
  501. static string _ServerStartTimeStamp = "";
  502. /// <summary>
  503. /// 服务器启动时间标识
  504. /// </summary>
  505. public static string ServerStartTimeStamp
  506. {
  507. get { return TCP_NetworkServer._ServerStartTimeStamp; }
  508. set { TCP_NetworkServer._ServerStartTimeStamp = value; }
  509. }
  510. /// <summary>
  511. /// 申明委托
  512. /// </summary>
  513. /// <param name="e"></param>
  514. /// <returns></returns>
  515. // public delegate void EventLockVerifiedHandler(EventLockVerified e);
  516. /// <summary>
  517. /// EventClientLockVerified事件
  518. /// </summary>
  519. // public event EventLockVerifiedHandler EventClientLockVerified;
  520. #endregion
  521. #region 客户端请求处理事件
  522. /// <summary>
  523. /// 申明客户端请求处理事件委托
  524. /// </summary>
  525. /// <param name="hp_Server"></param>
  526. /// <param name="header"></param>
  527. /// <param name="connId"></param>
  528. /// <param name="bytes"></param>
  529. public delegate void EventSerializationDataRequestHandler(HPSocketCS.TcpPackServer hp_Server, TcpHeadInfo header, IntPtr connId, byte[] bytes);
  530. /// <summary>
  531. /// 申明客户端请求处理事件
  532. /// </summary>
  533. public event EventSerializationDataRequestHandler EventSerializationDataRequest;
  534. /// <summary>
  535. /// 申明客户端请求文件传输处理事件委托
  536. /// </summary>
  537. /// <param name="hp_Server"></param>
  538. /// <param name="header"></param>
  539. /// <param name="connId"></param>
  540. /// <param name="bytes"></param>
  541. public delegate void EventFileDataRequestHandler(HPSocketCS.TcpPackServer hp_Server, TcpHeadInfo header, TcpTailInfo tail, IntPtr connId, byte[] bytes);
  542. /// <summary>
  543. /// 申明客户端请求文件传输处理事件
  544. /// </summary>
  545. public event EventFileDataRequestHandler EventFileDataRequest;
  546. #endregion
  547. }
  548. /// <summary>
  549. /// EventLockVerified 客户端连接事件对象
  550. /// </summary>
  551. public class EventLockVerified : EventArgs
  552. {
  553. public EventLockVerified()
  554. {
  555. }
  556. HPSocketCS.Extended.ClientInfo _CInfo;
  557. /// <summary>
  558. /// 客户端信息
  559. /// </summary>
  560. public HPSocketCS.Extended.ClientInfo CInfo
  561. {
  562. get { return _CInfo; }
  563. set { _CInfo = value; }
  564. }
  565. }
  566. }