NetFlowService.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. using Oreo.PCMonitor.Commons;
  2. using Oreo.PCMonitor.Models;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Diagnostics;
  6. using System.Linq;
  7. using System.Net;
  8. using Y.Utils.AppUtils;
  9. using Y.Utils.DataUtils.Collections;
  10. using Y.Utils.NetUtils.NetInfoUtils;
  11. using Y.Utils.WindowsUtils.ProcessUtils;
  12. namespace Oreo.PCMonitor.Services
  13. {
  14. public class NetFlowService
  15. {
  16. public bool IsNetFlowRun { get { return _IsNetFlowRun; } }
  17. private bool _IsNetFlowRun = false;
  18. public bool IsNetPacketRun { get { return _IsNetPacketRun; } }
  19. private bool _IsNetPacketRun = false;
  20. public List<NetProcessInfo> NetProcessInfoList = new List<NetProcessInfo>();
  21. public List<NetConnectionInfo> NetConnectionInfoList = new List<NetConnectionInfo>();
  22. public NetFlowTool NetFlow = new NetFlowTool();
  23. List<NetPacketTool> NetPacketList = new List<NetPacketTool>();
  24. NetProcessTool.TcpRow[] TcpConnection;
  25. NetProcessTool.UdpRow[] UdpConnection;
  26. Process[] NowProcess;
  27. List<string> AllIPv4Address = new List<string>();
  28. public long LostPacketCount { get; set; }
  29. public void Start()
  30. {
  31. #region 启动系统性能计数器统计
  32. try
  33. {
  34. NetFlow.Start();
  35. NetFlow.DataMonitorEvent += DataMonitorEvent;
  36. _IsNetFlowRun = true;
  37. }
  38. catch { }
  39. #endregion
  40. #region 启动Socket包统计
  41. if (PermissionTool.IsAdmin())
  42. {
  43. List<IPAddress> hosts = NetCardInfoTool.GetIPv4Address();
  44. AllIPv4Address = NetCardInfoTool.GetAllIPv4Address();
  45. foreach (var host in hosts)
  46. {
  47. try
  48. {
  49. NetPacketTool p = new NetPacketTool(host);
  50. p.NewPacket += new NewPacketEventHandler(NewPacketEvent);
  51. p.Start();
  52. NetPacketList.Add(p);
  53. }
  54. catch { }
  55. }
  56. if (ListTool.HasElements(NetPacketList)) _IsNetPacketRun = true;
  57. }
  58. #endregion
  59. }
  60. public void Stop()
  61. {
  62. if (_IsNetFlowRun)
  63. {
  64. NetFlow.Stop();
  65. _IsNetFlowRun = false;
  66. }
  67. if (_IsNetPacketRun)
  68. {
  69. NetPacketList.ForEach(x => { x.Stop(); });
  70. _IsNetPacketRun = false;
  71. }
  72. }
  73. public void DataMonitorEvent(NetFlowTool n)
  74. {
  75. NowProcess = Process.GetProcesses();
  76. GetConnection();
  77. SetNetProcess();
  78. CalcNetProcessInfo();
  79. CheckRestart();
  80. //#region 统计
  81. //p.Protocol == Protocol.Tcp
  82. //#endregion
  83. }
  84. private void NewPacketEvent(NetPacketTool tool, Packet packet)
  85. {
  86. bool isGather = false;
  87. #region 整理TCP包
  88. if (packet.Protocol == Protocol.Tcp && ListTool.HasElements(TcpConnection) && ListTool.HasElements(NowProcess))
  89. {
  90. lock (TcpConnection)
  91. {
  92. // tcp 下载
  93. if (TcpConnection.Any(x => x.RemoteIP.ToString() == packet.DestinationAddress.ToString() && x.RemotePort == packet.DestinationPort))
  94. {
  95. var tcpDownload = TcpConnection.FirstOrDefault(x => x.RemoteIP.ToString() == packet.DestinationAddress.ToString() && x.RemotePort == packet.DestinationPort);
  96. var process = NowProcess.FirstOrDefault(x => x.Id == tcpDownload.ProcessId);
  97. if (process != null)
  98. {
  99. var info = NetProcessInfoList.FirstOrDefault(x => x.ProcessName == process.ProcessName);
  100. if (info != null)
  101. {
  102. isGather = true;
  103. info.DownloadBag += packet.TotalLength;
  104. info.DownloadBagCount += packet.TotalLength;
  105. }
  106. }
  107. }
  108. // tcp 上传
  109. if (TcpConnection.Any(x => x.LocalIP.ToString() == packet.SourceAddress.ToString() && x.LocalPort == packet.SourcePort))
  110. {
  111. var tcUpload = TcpConnection.FirstOrDefault(x => x.LocalIP.ToString() == packet.SourceAddress.ToString() && x.LocalPort == packet.SourcePort);
  112. var process = NowProcess.FirstOrDefault(x => x.Id == tcUpload.ProcessId);
  113. if (process != null)
  114. {
  115. var info = NetProcessInfoList.FirstOrDefault(x => x.ProcessName == process.ProcessName);
  116. if (info != null)
  117. {
  118. isGather = true;
  119. info.UploadBag += packet.TotalLength;
  120. info.UploadBagCount += packet.TotalLength;
  121. }
  122. }
  123. }
  124. }
  125. }
  126. #endregion
  127. #region 整理UDP包
  128. if (packet.Protocol == Protocol.Udp && ListTool.HasElements(UdpConnection) && ListTool.HasElements(NowProcess))
  129. {
  130. lock (UdpConnection)
  131. {
  132. // tcp 下载
  133. if (UdpConnection.Any(x => x.LocalPort == packet.DestinationPort) && AllIPv4Address.Contains(packet.DestinationAddress.ToString()))
  134. {
  135. var udpDownload = UdpConnection.FirstOrDefault(x => AllIPv4Address.Contains(x.LocalIP.ToString()) && x.LocalPort == packet.DestinationPort);
  136. var process = NowProcess.FirstOrDefault(x => x.Id == udpDownload.ProcessId);
  137. if (process != null)
  138. {
  139. var info = NetProcessInfoList.FirstOrDefault(x => x.ProcessName == process.ProcessName);
  140. if (info != null)
  141. {
  142. isGather = true;
  143. info.DownloadBag += packet.TotalLength;
  144. info.DownloadBagCount += packet.TotalLength;
  145. if (info.ProcessName == "Idle")
  146. {
  147. }
  148. }
  149. }
  150. }
  151. // udp 上传
  152. if (UdpConnection.Any(x => x.LocalPort == packet.SourcePort) && AllIPv4Address.Contains(packet.SourceAddress.ToString()))
  153. {
  154. var udpIp = AllIPv4Address.FirstOrDefault(x => x == packet.SourceAddress.ToString());
  155. var ucUpload = UdpConnection.FirstOrDefault(x => AllIPv4Address.Contains(x.LocalIP.ToString()) && x.LocalPort == packet.SourcePort);
  156. var process = NowProcess.FirstOrDefault(x => x.Id == ucUpload.ProcessId);
  157. if (process != null)
  158. {
  159. var info = NetProcessInfoList.FirstOrDefault(x => x.ProcessName == process.ProcessName);
  160. if (info != null)
  161. {
  162. isGather = true;
  163. info.UploadBag += packet.TotalLength;
  164. info.UploadBagCount += packet.TotalLength;
  165. if (info.ProcessName == "Idle")
  166. {
  167. }
  168. }
  169. }
  170. }
  171. }
  172. }
  173. #endregion
  174. if (!isGather)
  175. {
  176. LostPacketCount++;
  177. }
  178. }
  179. #region 获取当前程序的所有连接
  180. void GetConnection()
  181. {
  182. TcpConnection = NetProcessTool.GetTcpConnection();
  183. UdpConnection = NetProcessTool.GetUdpConnection();
  184. }
  185. #endregion
  186. #region 设置程序流量及连接数统计列表
  187. void SetNetProcess()
  188. {
  189. // 清空已有连接数
  190. if (ListTool.HasElements(NetProcessInfoList))
  191. NetProcessInfoList.ForEach(x =>
  192. {
  193. x.ConnectCount = 0;
  194. });
  195. // 统计TCP连接数
  196. if (ListTool.HasElements(TcpConnection))
  197. {
  198. foreach (var t in TcpConnection)
  199. {
  200. SetNetProcessConnection(t.ProcessId);
  201. }
  202. }
  203. // 统计UDP连接数
  204. if (ListTool.HasElements(UdpConnection))
  205. {
  206. foreach (var u in UdpConnection)
  207. {
  208. SetNetProcessConnection(u.ProcessId);
  209. }
  210. }
  211. }
  212. void SetNetProcessConnection(int pid)
  213. {
  214. try
  215. {
  216. Process p = NowProcess.FirstOrDefault(x => x.Id == pid);
  217. if (p != null)
  218. {
  219. var ppl = NetProcessInfoList.FirstOrDefault(x => x.ProcessName == p.ProcessName);
  220. if (ppl == null)
  221. {
  222. NetProcessInfoList.Add(
  223. new NetProcessInfo()
  224. {
  225. ProcessIcon = ProcessInfoTool.GetIcon(p, false),
  226. ProcessName = p.ProcessName,
  227. ConnectCount = 1,
  228. LastUpdateTime = DateTime.Now,
  229. });
  230. }
  231. else
  232. {
  233. ppl.ConnectCount++;
  234. ppl.LastUpdateTime = DateTime.Now;
  235. }
  236. }
  237. }
  238. catch (Exception e)
  239. {
  240. R.Log.e("对程序列表和网络连接列表整理时发生错误");
  241. R.Log.e(e.Message);
  242. }
  243. }
  244. #endregion
  245. #region 整理程序流量汇总信息
  246. void CalcNetProcessInfo()
  247. {
  248. if (ListTool.HasElements(NetProcessInfoList))
  249. {
  250. NetProcessInfoList.ForEach(p =>
  251. {
  252. p.UploadDataCount += p.UploadData;
  253. p.DownloadDataCount += p.DownloadData;
  254. });
  255. int allupbag = NetProcessInfoList.Sum(x => x.UploadBag);
  256. int alldownbag = NetProcessInfoList.Sum(x => x.DownloadBag);
  257. NetProcessInfoList.ForEach(p =>
  258. {
  259. if (allupbag > 0 && NetFlow.UploadData > 0)
  260. {
  261. float uprate = (float)p.UploadBag / allupbag;
  262. p.UploadData = (int)(uprate * NetFlow.UploadData);
  263. }
  264. if (alldownbag > 0 && NetFlow.DownloadData > 0)
  265. {
  266. float downrate = (float)p.DownloadBag / alldownbag;
  267. p.DownloadData = (int)(downrate * NetFlow.DownloadData);
  268. }
  269. p.UploadBag = 0;
  270. p.DownloadBag = 0;
  271. p.LastUpdateTime = DateTime.Now;
  272. });
  273. }
  274. }
  275. #endregion
  276. #region 联网断网重启计划
  277. private void CheckRestart()
  278. {
  279. bool rest = false;
  280. string[] ints = NetCardInfoTool.GetInstanceNames();
  281. if (ListTool.IsNullOrEmpty(NetFlow.Instances) && ListTool.HasElements(ints))
  282. {
  283. rest = true;
  284. }
  285. if (ListTool.HasElements(NetFlow.Instances) && ListTool.HasElements(ints) &&
  286. string.Join("-", NetFlow.Instances) != string.Join("-", ints))
  287. {
  288. rest = true;
  289. }
  290. if (rest)
  291. {
  292. //重启 系统性能计数器
  293. NetFlow.Restart();
  294. //重启 抓包监听
  295. List<IPAddress> hosts = NetCardInfoTool.GetIPv4Address();
  296. AllIPv4Address = NetCardInfoTool.GetAllIPv4Address();
  297. foreach (var host in hosts)
  298. {
  299. try
  300. {
  301. if (!NetPacketList.Any(x => x.IP.ToString() == host.ToString()))
  302. {
  303. NetPacketTool p = new NetPacketTool(host);
  304. p.NewPacket += new NewPacketEventHandler(NewPacketEvent);
  305. p.Start();
  306. NetPacketList.Add(p);
  307. }
  308. }
  309. catch { }
  310. }
  311. }
  312. }
  313. #endregion
  314. }
  315. }