//************************************************************************
// https://github.com/yuzhengyang
// author: yuzhengyang
// date: 2016.5.1 - 2017.6.16
// desc: 网络流量监测工具
// Copyright (c) yuzhengyang. All rights reserved.
//************************************************************************
using Azylee.Core.AppUtils;
using Azylee.Core.DataUtils.CollectionUtils;
using Azylee.Core.ProcessUtils;
using Azylee.Core.WindowsUtils.InfoUtils;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using static Azylee.Core.NetUtils.NetProcessTool;
namespace Azylee.Core.NetUtils
{
public class NetFlowService
{
public bool IsNetFlowRun { get { return _IsNetFlowRun; } }
private bool _IsNetFlowRun = false;
public bool IsNetPacketRun { get { return _IsNetPacketRun; } }
private bool _IsNetPacketRun = false;
///
/// 程序联网信息列表
///
public List NetProcessInfoList { get { return _NetProcessInfoList; } }
List _NetProcessInfoList = new List();
///
/// 网络流量计数器
///
public NetFlowTool NetFlow { get { return _NetFlow; } }
NetFlowTool _NetFlow = new NetFlowTool();
List NetPacketList = new List();
NetProcessTool.TcpRow[] TcpConnection;
NetProcessTool.UdpRow[] UdpConnection;
Process[] NowProcess;
List AllIPv4Address = new List();
public long LostPacketCount { get; set; }
///
/// 开启网络流量监控
///
public void Start()
{
#region 启动系统性能计数器统计
try
{
_NetFlow.Start();
_NetFlow.DataMonitorEvent += DataMonitorEvent;
_IsNetFlowRun = true;
}
catch { }
#endregion
#region 启动Socket包统计
if (PermissionTool.IsAdmin())
{
List hosts = NetCardInfoTool.GetIPv4Address();
AllIPv4Address = NetCardInfoTool.GetAllIPv4Address();
foreach (var host in hosts)
{
try
{
NetPacketTool p = new NetPacketTool(host);
p.NewPacket += new NewPacketEventHandler(NewPacketEvent);
p.Start();
NetPacketList.Add(p);
}
catch { }
}
if (ListTool.HasElements(NetPacketList)) _IsNetPacketRun = true;
}
#endregion
}
///
/// 关闭网络流量监控
///
public void Stop()
{
if (_IsNetFlowRun)
{
_NetFlow.Stop();
_IsNetFlowRun = false;
}
if (_IsNetPacketRun)
{
NetPacketList.ForEach(x => { x.Stop(); });
_IsNetPacketRun = false;
}
}
///
/// 系统性能计数器每秒统计事件
///
///
public void DataMonitorEvent(NetFlowTool n)
{
NowProcess = Process.GetProcesses();
GetConnection();
SetNetProcess();
CalcNetProcessInfo();
CheckRestart();
}
///
/// 整理数据包到所属的进程
///
///
///
private void NewPacketEvent(NetPacketTool tool, Packet packet)
{
bool isGather = false;
#region 整理TCP包
if (packet.Protocol == Protocol.Tcp && ListTool.HasElements(TcpConnection) && ListTool.HasElements(NowProcess))
{
lock (TcpConnection)
{
// tcp 下载
if (TcpConnection.Any(x => x.RemoteIP.ToString() == packet.DestinationAddress.ToString() && x.RemotePort == packet.DestinationPort))
{
var tcpDownload = TcpConnection.FirstOrDefault(x => x.RemoteIP.ToString() == packet.DestinationAddress.ToString() && x.RemotePort == packet.DestinationPort);
var process = NowProcess.FirstOrDefault(x => x.Id == tcpDownload.ProcessId);
if (process != null)
{
var info = _NetProcessInfoList.FirstOrDefault(x => x.ProcessName == process.ProcessName);
if (info != null)
{
isGather = true;
info.DownloadBag += packet.TotalLength;
info.DownloadBagCount += packet.TotalLength;
}
}
}
// tcp 上传
if (TcpConnection.Any(x => x.LocalIP.ToString() == packet.SourceAddress.ToString() && x.LocalPort == packet.SourcePort))
{
var tcUpload = TcpConnection.FirstOrDefault(x => x.LocalIP.ToString() == packet.SourceAddress.ToString() && x.LocalPort == packet.SourcePort);
var process = NowProcess.FirstOrDefault(x => x.Id == tcUpload.ProcessId);
if (process != null)
{
var info = _NetProcessInfoList.FirstOrDefault(x => x.ProcessName == process.ProcessName);
if (info != null)
{
isGather = true;
info.UploadBag += packet.TotalLength;
info.UploadBagCount += packet.TotalLength;
}
}
}
}
}
#endregion
#region 整理UDP包
if (packet.Protocol == Protocol.Udp && ListTool.HasElements(UdpConnection) && ListTool.HasElements(NowProcess))
{
lock (UdpConnection)
{
// tcp 下载
if (UdpConnection.Any(x => x.LocalPort == packet.DestinationPort) && AllIPv4Address.Contains(packet.DestinationAddress.ToString()))
{
var udpDownload = UdpConnection.FirstOrDefault(x => AllIPv4Address.Contains(x.LocalIP.ToString()) && x.LocalPort == packet.DestinationPort);
var process = NowProcess.FirstOrDefault(x => x.Id == udpDownload.ProcessId);
if (process != null)
{
var info = _NetProcessInfoList.FirstOrDefault(x => x.ProcessName == process.ProcessName);
if (info != null)
{
isGather = true;
info.DownloadBag += packet.TotalLength;
info.DownloadBagCount += packet.TotalLength;
if (info.ProcessName == "Idle")
{
}
}
}
}
// udp 上传
if (UdpConnection.Any(x => x.LocalPort == packet.SourcePort) && AllIPv4Address.Contains(packet.SourceAddress.ToString()))
{
var udpIp = AllIPv4Address.FirstOrDefault(x => x == packet.SourceAddress.ToString());
var ucUpload = UdpConnection.FirstOrDefault(x => AllIPv4Address.Contains(x.LocalIP.ToString()) && x.LocalPort == packet.SourcePort);
var process = NowProcess.FirstOrDefault(x => x.Id == ucUpload.ProcessId);
if (process != null)
{
var info = _NetProcessInfoList.FirstOrDefault(x => x.ProcessName == process.ProcessName);
if (info != null)
{
isGather = true;
info.UploadBag += packet.TotalLength;
info.UploadBagCount += packet.TotalLength;
if (info.ProcessName == "Idle")
{
}
}
}
}
}
}
#endregion
if (!isGather)
{
LostPacketCount++;
}
}
#region 获取所有网络连接
///
/// 获取所有网络连接并整理列表
///
void GetConnection()
{
TcpConnection = NetProcessTool.GetTcps();
UdpConnection = NetProcessTool.GetUdps();
}
#endregion
#region 设置程序流量及连接数统计列表
///
/// 清空并重置当前所有程序的连接数
///
void SetNetProcess()
{
// 清空已有连接数
if (ListTool.HasElements(_NetProcessInfoList))
_NetProcessInfoList.ForEach(x =>
{
x.NetConnectionInfoList = new List();
});
// 统计TCP连接数
if (ListTool.HasElements(TcpConnection))
{
foreach (var t in TcpConnection)
{
SetNetProcessConnection(t);
}
}
// 统计UDP连接数
if (ListTool.HasElements(UdpConnection))
{
foreach (var u in UdpConnection)
{
SetNetProcessConnection(u);
}
}
}
///
/// 整理TCP连接到所属的进程
///
///
void SetNetProcessConnection(TcpRow t)
{
try
{
Process p = NowProcess.FirstOrDefault(x => x.Id == t.ProcessId);
if (p != null)
{
var ppl = _NetProcessInfoList.FirstOrDefault(x => x.ProcessName == p.ProcessName);
if (ppl == null)
{
_NetProcessInfoList.Add(
new NetProcessInfo()
{
ProcessId = p.Id,
ProcessIcon = ProcessInfoTool.GetIcon(p, false),
ProcessName = p.ProcessName,
LastUpdateTime = DateTime.Now,
NetConnectionInfoList = new List() {
new NetConnectionInfo() {
LocalIP = t.LocalIP.ToString(),
LocalPort = t.LocalPort,
RemoteIP = t.RemoteIP.ToString(),
RemotePort = t.RemotePort,
ProtocolName = "TCP",
Status = t.State,
LastUpdateTime = DateTime.Now,
}
},
});
}
else
{
ppl.LastUpdateTime = DateTime.Now;
var conn = ppl.NetConnectionInfoList.FirstOrDefault(x => x.LocalIP == t.LocalIP.ToString() && x.LocalPort == t.LocalPort && x.RemoteIP == t.RemoteIP.ToString() && x.RemotePort == t.RemotePort);
if (conn == null)
{
ppl.NetConnectionInfoList.Add(new NetConnectionInfo()
{
LocalIP = t.LocalIP.ToString(),
LocalPort = t.LocalPort,
RemoteIP = t.RemoteIP.ToString(),
RemotePort = t.RemotePort,
ProtocolName = "TCP",
Status = t.State,
LastUpdateTime = DateTime.Now,
});
}
}
}
}
catch (Exception e)
{ }
}
///
/// 整理UDP连接到所属的进程
///
///
void SetNetProcessConnection(UdpRow u)
{
try
{
Process p = NowProcess.FirstOrDefault(x => x.Id == u.ProcessId);
if (p != null)
{
var ppl = _NetProcessInfoList.FirstOrDefault(x => x.ProcessName == p.ProcessName);
if (ppl == null)
{
_NetProcessInfoList.Add(
new NetProcessInfo()
{
ProcessId = p.Id,
ProcessIcon = ProcessInfoTool.GetIcon(p, false),
ProcessName = p.ProcessName,
LastUpdateTime = DateTime.Now,
NetConnectionInfoList = new List() {
new NetConnectionInfo() {
LocalIP = u.LocalIP.ToString(),
LocalPort = u.LocalPort,
ProtocolName = "UDP",
LastUpdateTime = DateTime.Now,
}
},
});
}
else
{
ppl.LastUpdateTime = DateTime.Now;
var conn = ppl.NetConnectionInfoList.FirstOrDefault(x => x.LocalIP == u.LocalIP.ToString() && x.LocalPort == u.LocalPort);
if (conn == null)
{
ppl.NetConnectionInfoList.Add(new NetConnectionInfo()
{
LocalIP = u.LocalIP.ToString(),
LocalPort = u.LocalPort,
ProtocolName = "UDP",
LastUpdateTime = DateTime.Now,
});
}
}
}
}
catch (Exception e)
{ }
}
#endregion
#region 整理程序流量汇总信息
///
/// 整理计算程序网络流量
///
void CalcNetProcessInfo()
{
if (ListTool.HasElements(_NetProcessInfoList))
{
_NetProcessInfoList.ForEach(p =>
{
p.UploadDataCount += p.UploadData;
p.DownloadDataCount += p.DownloadData;
});
int allupbag = _NetProcessInfoList.Sum(x => x.UploadBag);
int alldownbag = _NetProcessInfoList.Sum(x => x.DownloadBag);
_NetProcessInfoList.ForEach(p =>
{
if (allupbag > 0 && _NetFlow.UploadData > 0)
{
float uprate = (float)p.UploadBag / allupbag;
p.UploadData = (int)(uprate * _NetFlow.UploadData);
}
if (alldownbag > 0 && _NetFlow.DownloadData > 0)
{
float downrate = (float)p.DownloadBag / alldownbag;
p.DownloadData = (int)(downrate * _NetFlow.DownloadData);
}
p.UploadBag = 0;
p.DownloadBag = 0;
p.LastUpdateTime = DateTime.Now;
});
}
}
#endregion
#region 联网断网重启计划
///
/// 联网断网重启计划(应对断网或重连后网卡抓包报错造成的不准确)
///
private void CheckRestart()
{
bool rest = false;
string[] ints = NetCardInfoTool.GetInstanceNames();
if (ListTool.IsNullOrEmpty(_NetFlow.Instances) && ListTool.HasElements(ints))
{
rest = true;
}
if (ListTool.HasElements(_NetFlow.Instances) && ListTool.HasElements(ints) &&
string.Join("-", _NetFlow.Instances) != string.Join("-", ints))
{
rest = true;
}
if (rest)
{
//重启 系统性能计数器
_NetFlow.Restart();
//重启 抓包监听
List hosts = NetCardInfoTool.GetIPv4Address();
AllIPv4Address = NetCardInfoTool.GetAllIPv4Address();
foreach (var host in hosts)
{
try
{
if (!NetPacketList.Any(x => x.IP.ToString() == host.ToString()))
{
NetPacketTool p = new NetPacketTool(host);
p.NewPacket += new NewPacketEventHandler(NewPacketEvent);
p.Start();
NetPacketList.Add(p);
}
}
catch { }
}
}
}
#endregion
}
}