windows下使用C#获取特定进程网络流量
最近老板接了一个中船重工的项目,需要做一个有关海军软件系统的组件评估项目,项目中有一个子项目需要获取特定进程的各种系统参数,项目使用.NET平台。在获取特定进程各种系统参数时,其它诸如进程ID,进程名,进程私有工作集,进程工作集,进程IO吞吐量,进程CPU占用率等都可以直接使用.NET中的相关API直接获取,例如使用PerformanceCounter对象可以获取进程私有工作集、进程工作集、进程IO吞吐量等,但是对于特定进程的网络上行流量和下行流量却没有办法直接使用.NET中API获取,网上也找了很多资料,了解到只能通过对特定进程使用的端口号进行抓包来获取进程网络流量,具体实现时自己也想过使用C#调用winpcap库,但由于实现比较复杂,所以就放弃了使用该方法。后来在网上找到了一个国外使用C#实现的winpcap库SharpPcap库,于是使用SharpPcap库实现了获取特定进程网络流量功能。准备工作是需要将SharpPcap库下载到计算机,然后再项目中引用PacketDotNet.dll和SharpPcap.dll,然后添加引用:
using SharpPcap; using PacketDotNet;
具体实现比较复杂,以下介绍一下实现中的核心部分:
首先定义ProcessPerformanceInfo类,用来记录进程相关信息,ProcessPerformanceInfo定义如下
//记录特定进程性能信息的类
public class ProcessPerformanceInfo : IDisposable
{
public int ProcessID { get; set; }//进程ID
public string ProcessName { get; set; }//进程名
public float PrivateWorkingSet { get; set; }//私有工作集(KB)
public float WorkingSet { get; set; }//工作集(KB)
public float CpuTime { get; set; }//CPU占用率(%)
public float IOOtherBytes { get; set; }//每秒IO操作(不包含控制操作)读写数据的字节数(KB)
public int IOOtherOperations { get; set; }//每秒IO操作数(不包括读写)(个数)
public long NetSendBytes { get; set; }//网络发送数据字节数
public long NetRecvBytes { get; set; }//网络接收数据字节数
public long NetTotalBytes { get; set; }//网络数据总字节数
public List<ICaptureDevice> dev = new List<ICaptureDevice>();
/// <summary>
/// 实现IDisposable的方法
/// </summary>
public void Dispose()
{
foreach (ICaptureDevice d in dev)
{
d.StopCapture();
d.Close();
}
}
}
定义一个ProcessPerformanceInfo类型的属性ProcInfo:
public ProcessPerformanceInfo ProcInfo { get; set; }
第一步:获取指定进程使用的所有端口号
由于一个进程可能使用多个端口号,因此监视一个进程流量时必须监视该进程使用的所有端口号,具体可以通过cmd执行命令netstat -ano并对结果进行分析。代码如下:
//进程id
int pid = ProcInfo.ProcessID;
//存放进程使用的端口号链表
List<int> ports = new List<int>();
#region 获取指定进程对应端口号
Process pro = new Process();
pro.StartInfo.FileName = "cmd.exe";
pro.StartInfo.UseShellExecute = false;
pro.StartInfo.RedirectStandardInput = true;
pro.StartInfo.RedirectStandardOutput = true;
pro.StartInfo.RedirectStandardError = true;
pro.StartInfo.CreateNoWindow = true;
pro.Start();
pro.StandardInput.WriteLine("netstat -ano");
pro.StandardInput.WriteLine("exit");
Regex reg = new Regex("\\s+", RegexOptions.Compiled);
string line = null;
ports.Clear();
while ((line = pro.StandardOutput.ReadLine()) != null)
{
line = line.Trim();
if (line.StartsWith("TCP", StringComparison.OrdinalIgnoreCase))
{
line = reg.Replace(line, ",");
string[] arr = line.Split(',');
] == pid.ToString())
{
];
int pos = soc.LastIndexOf(':');
));
ports.Add(pot);
}
}
else if (line.StartsWith("UDP", StringComparison.OrdinalIgnoreCase))
{
line = reg.Replace(line, ",");
string[] arr = line.Split(',');
] == pid.ToString())
{
];
int pos = soc.LastIndexOf(':');
));
ports.Add(pot);
}
}
}
pro.Close();
#endregion
所获取的端口号都存放在ports里。
第二步:获取本机IP地址和本机网络设备(即网卡)
//获取本机IP地址
IPAddress[] addrList = Dns.GetHostByName(Dns.GetHostName()).AddressList;
].ToString();
//获取本机网络设备
var devices = CaptureDeviceList.Instance;
int count = devices.Count;
)
{
Console.WriteLine("No device found on this machine");
return;
}
第三步:开始抓包,至于sharppcap库的使用方法,在官方有很详细的介绍:http://www.codeproject.com/Articles/12458/SharpPcap-A-Packet-Capture-Framework-for-NET
实现代码如下:
//开始抓包
; i < count; ++i)
{
; j < ports.Count; ++j)
{
CaptureFlowRecv(IP, ports[j], i);
CaptureFlowSend(IP, ports[j], i);
}
}
CaptureFlowRecv和CaptureFlowSend函数定义如下:
public void CaptureFlowSend(string IP, int portID, int deviceID)
{
ICaptureDevice device = (ICaptureDevice)CaptureDeviceList.New()[deviceID];
device.OnPacketArrival += new PacketArrivalEventHandler(device_OnPacketArrivalSend);
;
device.Open(DeviceMode.Promiscuous, readTimeoutMilliseconds);
string filter = "src host " + IP + " and src port " + portID;
device.Filter = filter;
device.StartCapture();
ProcInfo.dev.Add(device);
}
public void CaptureFlowRecv(string IP, int portID, int deviceID)
{
ICaptureDevice device = CaptureDeviceList.New()[deviceID];
device.OnPacketArrival += new PacketArrivalEventHandler(device_OnPacketArrivalRecv);
;
device.Open(DeviceMode.Promiscuous, readTimeoutMilliseconds);
string filter = "dst host " + IP + " and dst port " + portID;
device.Filter = filter;
device.StartCapture();
ProcInfo.dev.Add(device);
}
private void device_OnPacketArrivalSend(object sender, CaptureEventArgs e)
{
var len = e.Packet.Data.Length;
ProcInfo.NetSendBytes += len;
}
private void device_OnPacketArrivalRecv(object sender, CaptureEventArgs e)
{
var len = e.Packet.Data.Length;
ProcInfo.NetRecvBytes += len;
}
第四步:设置每秒刷新上行下行流量
/// <summary>
/// 实时刷新性能参数
/// </summary>
public void RefershInfo()
{
ProcInfo.NetRecvBytes = ;
ProcInfo.NetSendBytes = ;
ProcInfo.NetTotalBytes = ;
Thread.Sleep();
ProcInfo.NetTotalBytes = ProcInfo.NetRecvBytes + ProcInfo.NetSendBytes;
}
第五步:测试部分代码
while (true)
{
Console.WriteLine("proc NetTotalBytes : " + ProcInfo.NetTotalBytes);
Console.WriteLine("proc NetSendBytes : " + ProcInfo.NetSendBytes);
Console.WriteLine("proc NetRecvBytes : " + ProcInfo.NetRecvBytes);
//每隔1s调用刷新函数对性能参数进行刷新
RefershInfo();
}
//最后要记得调用Dispose方法停止抓包并关闭设备
Proc.Dispose();
以上仅仅是核心部分实现的代码简介,旨在为读者提供思路,具体实现还需要添加很多接口和类来实现。最后附上自己运行后的截图

windows下使用C#获取特定进程网络流量的更多相关文章
- Linux下实现脚本监测特定进程占用内存情况
Linux系统下,我们可以利用以下命令来获取特定进程的运行情况: cat /proc/$PID/status 其中PID是具体的进程号,这个命令打印出/proc/特定进程/status文件的内容,信息 ...
- C++ 获取特定进程的CPU使用率<转>
C++ 获取特定进程的CPU使用率 近来发现笔记本在关闭屏幕后风扇转得特别快,打开屏幕后看任务管理器,风扇马上减速,也没有发现大量占用CPU的进程.于是想写一个小程序在后台记录每个进程的CPU使用情况 ...
- C#获取特定进程CPU和内存使用率
首先是获取特定进程对象,可以使用Process.GetProcesses()方法来获取系统中运行的所有进程,或者使用Process.GetCurrentProcess()方法来获取当前程序所对应的进程 ...
- Windows下如何创建低权限进程
1. 前言 在使用 Sysinternals 出品的 Process Explorer 过程中,对 “Run as Limited User” 功能的实现方式颇感兴趣,一番搜寻之下发现Mark ...
- windows下bat批处理实现守护进程
本文转自网络,由于找不到原作者,因而无法知道出处.如果有幸让原作者看到,请联系我加上.先转载至此. 最近几天加班加疯掉了,天天晚上没法睡.开发部的一个核心程序总是会自己宕机,然后需要手工去起,而这个服 ...
- windows下根据端口号杀死进程
Windows不像Linux,Unix那样,ps -ef 查出端口和进程号,然后根据进程号直接kill进程. Windows根据端口号杀死进程要分三步: 第一步 根据端口号寻找进程号 C:\>n ...
- windows下捕获dump之守护进程
一两个月前为产品写了一个独立的exe,由于产品使用的捕获dump是一个现成的进程外exe,如果以资源的方式集成它容易出现安全警告,由于时间关系没有寻求新的解决方法,还是遵循旧方案,不捕获dump. 最 ...
- windows下bat批处理实现守护进程(有日志)
开发部的一个核心程序总是会自己宕机,然后需要手工去起,而这个服务的安全级别又很高,只有我可以操作,搞得我晚上老没法睡,昨晚实在受不了了,想起以前在hp-ux下写的shell守护进程,这回搞个windo ...
- CentOS7 监控进程网络流量工具安装
服务器在做测试的时候,需要监控网络流量,用来了解在不同人数的时候服务器的网络使用量. 我们使用服务器环境是centos7,centos下通常使用iftop,或者nethogs来进行网络流量监控.这2个 ...
随机推荐
- MAC 如何使用Github Desktop 客户端
作为开源代码库以及版本控制系统,Github拥有140多万开发者用户.随着越来越多的应用程序转移到了云上,Github已经成为了管理软件开发以及发现已有代码的首选方法.GitHub上已自动配置的Mac ...
- 心无旁骛,向死而生:WGDC2016给创企上的一堂课
"这是最好的时代,也是最坏的时代:这是希望的春天,也是失望的冬天." ------狄更斯 WGDC2016落幕已经一月有余,我仍然记得会议结束后,穿过高大宽敞的国家会议中心大厅,走 ...
- Objective-C内存管理之-引用计数
本文会继续深入学习OC内存管理,内容主要参考iOS高级编程,Objective-C基础教程,疯狂iOS讲义,是我学习内存管理的笔记 内存管理 1 内存管理的基本概念 1.1 Objective-C中的 ...
- git笔记
这篇有关git的博客,写着写着有些崩了.里面有些碎碎念了.下次一定注意这个问题. 创建项目: midir xx :创建xx文件夹 git init : 为当前文件夹创建代码仓库 提交代码: git a ...
- mac osx install mysql
(1) download mysql dmg (2) install (3) /usr/local/mysql/bin/mysql -u root -p change password
- python文件读写操作与linux shell变量命令交互执行
python对文件的读写还是挺方便的,与linux shell的交互变量需要转换一下才能用,这比较头疼! #coding=utf-8 #!/usr/bin/python import os impor ...
- margin css的外边距
h2{margin:10px 0;} div{margin:20px 0;} ...... <h2>这是一个标题</h2> <div> <h2>这是又一 ...
- [分享] 很多人手机掉了,却不知道怎么找回来。LZ亲身经历讲述手机找回过程,申请加精!
文章开头:(LZ文笔不好,以下全部是文字描述,懒得配图.因为有人说手机掉了,他们问我是怎么找回来的.所以想写这篇帖子.只不过前段时间忙,没时间.凑端午节给大家一些经验) 还是先谢谢被偷经历吧!5月22 ...
- 微软源代码管理工具TFS2013安装与使用详细图文教程(Vs2013)
这篇文章联合软件小编主要介绍了微软源代码管理工具TFS2013安装与使用图文教程,本文详细的给出了TFS2013的安装配置过程.使用教程,需要的朋友可以参考下 最近公司新开发一个项目要用微软的TFS2 ...
- Invoke--转载
在多线程编程中,我们经常要在工作线程中去更新界面显示,而在多线程中直接调用界面控件的方法是错误的做法,Invoke 和 BeginInvoke 就是为了解决这个问题而出现的,使你在多线程中安全的更新界 ...