/// <summary> /// When one packet is captured by threads, we store the information in the manager. /// </summary> /// <param name="packet">The information of one packet</param> /// <param name="len">The length of bytes of one packet</param> public void AddPacket(PacketFlow packet, int len) { lock (this) { if (packet.type != PacketFlow.FlowType.DROP) { if (packet.hasIPAndPort) { Port p = new Port(packet.myIP, packet.port, packet.protocol); if (!portMap.TryGetValue(p, out PortStatistic statistic)) { statistic = new PortStatistic { port = p }; portMap[p] = statistic; } if (packet.type == PacketFlow.FlowType.DOWNLOAD) { statistic.downLen += len; downloadStatistic += len; } else { statistic.upLen += len; uploadStatistic += len; } } else { if (packet.type == PacketFlow.FlowType.UPLOAD) { noPortStatistic.upLen += len; uploadStatistic += len; } else { noPortStatistic.downLen += len; downloadStatistic += len; } } } } }
/// <summary> /// Get the statistic result. This method analyses the network traffic before this method is called to the last time this method called. /// So invoking this method twice will get different statistic result. /// </summary> /// <param name="topMax">The top N processes.</param> /// <param name="portProcessMap">The relationships of Process and Socket Address</param> /// <returns></returns> public UDStatistic NextStatistic(int topMax, PortProcessMap portProcessMap) { lock (this) { UDStatistic statistic = new UDStatistic { upload = uploadStatistic, download = downloadStatistic }; DateTime now = DateTime.Now; statistic.timeSpan = now.Subtract(lastTime).TotalMilliseconds; lastTime = now; Init(); if (portProcessMap.Enabled) { Dictionary <int, ProcessStatistic> nowProMap = new Dictionary <int, ProcessStatistic>(); long unKnownUp = 0; long unKnownDown = 0; foreach (var i in portMap.Values) { int id = portProcessMap.GetIPPortProcesId(i.port); if (id == -1) { unKnownDown += i.downLen; unKnownUp += i.upLen; } else { if (!nowProMap.TryGetValue(id, out ProcessStatistic sta)) { sta = new ProcessStatistic { processId = id }; nowProMap[id] = sta; } sta.downLen += i.downLen; sta.upLen += i.upLen; } } var values = nowProMap.Values.ToList(); foreach (ProcessStatistic i in values) { i.sum = i.downLen + i.upLen; } values.Sort(); HashSet <int> processes = new HashSet <int>(); int k = 0; while (k < topMax && k < values.Count) { ProcessStatistic ps = values[k]; if (ps.sum == 0) { break; } UDOneItem item = new UDOneItem(ps.processId, values[k].upLen, values[k].downLen); statistic.items.Add(item); processes.Add(ps.processId); k++; } k = 0; while (statistic.items.Count < topMax && k < lastTimeUDItems.Count) { UDOneItem item = lastTimeUDItems[k]; if (item.ProcessID >= 0) { if (!processes.Contains(item.ProcessID) && portProcessMap.IsProcessHasConnect(item.ProcessID)) { statistic.items.Add(new UDOneItem(item.ProcessID, 0, 0)); processes.Add(item.ProcessID); } } k++; } if (unKnownDown != 0 || unKnownUp != 0) { //statistic.items.Add(new UDOneItem() { name = "miss", download = unKnownDown, upload = unKnownUp}); } if (noPortStatistic.downLen != 0 || noPortStatistic.upLen != 0 || (lastTimeUDItems.Count > 0 && lastTimeUDItems[lastTimeUDItems.Count - 1].ProcessID == -1)) { statistic.items.Add(new UDOneItem(-1, noPortStatistic.upLen, noPortStatistic.downLen)); } lastTimeUDItems = new List <UDOneItem>(statistic.items); } noPortStatistic = new PortStatistic(); portMap.Clear(); return(statistic); } }