Sniffer的完整代码,基于winpcap抓包统计吞吐量
using System;
using System.Net;
using System.Net.Sockets;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using SharpPcap;
using SharpPcap.WinPcap;
using PacketDotNet;
using Demo.STP.Sniff.Packets;
namespace Demo.STP.Sniff
{
/// <summary>
/// 嗅探器,提供原始数据源
/// </summary>
public sealed class Sniffer
{
#region Instance
private static readonly Lazy<Sniffer> _lazy =
new Lazy<Sniffer>(() => new Sniffer());
public static Sniffer Instance
{
get { return _lazy.Value; }
}
private Sniffer() { }
#endregion Instance
#region Init
/// <summary>
/// 初始化嗅探器
/// </summary>
/// <param name="ipAddress">需拦截网卡所配IP</param>
/// <param name="filter">数据包过滤规则</param>
public void Init(string ipAddress, string filter = "")
{
var network = Demo.STP.Common.NetHelper.GetNetwork(ipAddress);
if (network == null)
throw new ArgumentException(string.Format("Invalid IPAddress {0}.", ipAddress));
this._currentDevice = WinPcapDeviceList.Instance.Where(deviceItem =>
string.Equals(network.Name, deviceItem.Interface.FriendlyName, StringComparison.OrdinalIgnoreCase))
.FirstOrDefault();
if (this._currentDevice == null)
throw new ArgumentException("无法从WinPcap找到对应网卡.");
this._currentDevice.OnPacketArrival += device_OnPacketArrival;
this._currentDevice.Open(DeviceMode.Normal);
this._currentDevice.Filter = filter;
}
private void device_OnPacketArrival(object sender, CaptureEventArgs e)
{
this._packetQueue.Enqueue(e.Packet);
}
#endregion Init
#region Start Hook
/// <summary>
/// 启动嗅探器
/// </summary>
public void StartHook()
{
if (this._currentDevice == null)
throw new ArgumentException("请先初始化嗅探器.");
KeepHook = true;
this._currentDevice.StartCapture();
RawCapture rawCapture = null;
Task.Factory.StartNew(() =>
{
while (KeepHook)
{
if (this._packetQueue.IsEmpty)
{
//理论上能轻松应对所有终端
//如果吞吐量达不到要求,请删除Sleep,但会占用一个核心的全部时间
Thread.Sleep();
continue;
}
if (this._packetQueue.TryDequeue(out rawCapture))
{
var basePacket = this.AnalysisPacket(rawCapture);
if (basePacket.HasValue)
{
OnPacketArrival(new PacketArrivedEventArgs { BasePacket = basePacket.Value });
}
}
}
}, TaskCreationOptions.LongRunning);
}
#endregion Start Hook
#region Stop Hook
/// <summary>
/// 停止嗅探器
/// </summary>
public void StopHook()
{
if (this._currentDevice == null) return;
KeepHook = false;
if (this._currentDevice.Started)
this._currentDevice.StopCapture();
this._currentDevice.OnPacketArrival -= device_OnPacketArrival;
this._currentDevice.Close();
}
#endregion Stop Hook
#region 解析数据包
private Nullable<IPBasePacket> AnalysisPacket(RawCapture rawCapture)
{
try
{
var rawPacket = rawCapture.ParseRawPacket();
var ipPacket = rawPacket.ExtractTragetPacket<IpPacket>();
if (ipPacket == null)
return null;
EnumIPProtocol targetProtocol;
var parseFlag = Enum.TryParse(ipPacket.Protocol.ToString(), true, out targetProtocol);
if (!parseFlag)
return null;
IPBasePacket basePacket = new IPBasePacket();
basePacket.Protocol = targetProtocol;
basePacket.IPVersion = ipPacket.Version.ToString();
basePacket.SourceIP = ipPacket.SourceAddress.ToString();
basePacket.TargetIP = ipPacket.DestinationAddress.ToString();
dynamic tcp_udp_Packet = rawPacket.ExtractTragetPacket<TcpPacket>();
if (tcp_udp_Packet == null)
tcp_udp_Packet = rawPacket.ExtractTragetPacket<UdpPacket>();
if (tcp_udp_Packet != null)
{
if (tcp_udp_Packet.PayloadData == null)
return null;
basePacket.SourcePort = tcp_udp_Packet.SourcePort;
basePacket.TargetPort = tcp_udp_Packet.DestinationPort;
//basePacket.PacketLength = (uint)tcp_udp_Packet.Bytes.Length;
//basePacket.HeaderLength = (uint)tcp_udp_Packet.Header.Length;
//basePacket.MessageLength = (uint)tcp_udp_Packet.PayloadData.Length;
//basePacket.PacketBuffer = tcp_udp_Packet.Bytes;
//basePacket.HeaderBuffer = tcp_udp_Packet.Header;
//basePacket.MessageBuffer = tcp_udp_Packet.PayloadData;
basePacket.MessageLength = (uint)tcp_udp_Packet.PayloadData.Length;
basePacket.MessageBuffer = tcp_udp_Packet.PayloadData;
}
return basePacket;
}
catch
{
return null;
}
}
#endregion 解析数据包
#region PacketArrival Event
public event EventHandler<PacketArrivedEventArgs> PacketArrival;
internal void OnPacketArrival(PacketArrivedEventArgs e)
{
if (PacketArrival != null)
{
PacketArrival(this, e);
}
}
public bool IsMonitorEmpty
{
get { return PacketArrival == null; }
}
#endregion PacketArrival Event
#region Fields & Propertys
public bool KeepHook { get; private set; }
private WinPcapDevice _currentDevice;
private ConcurrentQueue<RawCapture> _packetQueue = new ConcurrentQueue<RawCapture>();
#endregion Fields & Propertys
}
public class PacketArrivedEventArgs : EventArgs
{
public IPBasePacket BasePacket { get; set; }
}
}
Sniffer的完整代码,基于winpcap抓包统计吞吐量的更多相关文章
- winpcap抓包原理
winpcap抓包原理 WinPcap 是由伯克利分组捕获库派生而来的分组捕获库,它是在Windows 操作平台上来实现对底层包的截取过滤.WinPcap 是 BPF 模型和 Libpcap 函数库在 ...
- 基于wireshark抓包分析TCP的三次握手
1. TCP的三次握手 在TCP/IP协议通讯过程中,采用三次握手建立连接,从而保证连接的安全可靠. 所有基于TCP的通信都需要以两台主机的握手开始.这个握手过程主要是希望能达到以下不同的目的.[1] ...
- Python + winpcap抓包和发包
winpcapy Python的winpcapy库可以简单地实现收发Layer2层(数据链路层,以太网)数据. winpcapy主页:https://github.com/orweis/winpcap ...
- NetAnalyzer笔记 之 三. 用C++做一个抓包程序
[创建时间:2015-08-27 22:15:17] NetAnalyzer下载地址 经过前两篇的瞎扯,你是不是已经厌倦了呢,那么这篇让我们来点有意思的吧,什么,用C#.不,这篇我们先来C++的 Wi ...
- https wireshark抓包——要解密出原始数据光有ssl 证书还不行,还要有浏览器内的pre-master-secret(内存里)
基于wireshark抓包的分析 首先使用wireshark并且打开浏览器,打开百度(百度使用的是HTTPS加密),随意输入关键词浏览. 我这里将抓到的包进行过滤.过滤规则如下 ip.addr == ...
- 软件测试必须掌握的抓包工具Wireshark,你会了么?
作为软件测试工程师,大家在工作中肯定经常会用到各种抓包工具来辅助测试,比如浏览器自带的抓包工具-F12,方便又快捷:比如时下特别流行的Fiddler工具,使用各种web和APP测试的各种场景的抓包分析 ...
- charles 抓包 (二)
本文基于charles 抓包 https (1)中的配置完成. 1.移动设备上的网络请求 打开要调试的APP,请求就会先发送到Charles,然后验证是否允许访问. 当点击允许后,可以在Proxy - ...
- 【毕业设计】基于Android的家校互动平台开发(内含完整代码和所有文档)——爱吖校推(你关注的,我们才推)
☆ 写在前面 之前答应大家的毕业答辩之后把所有文档贡献出来,现在答辩已过,LZ信守承诺,把所有文档开源到了GitHub(这个地址包含所有的代码和文档以及PPT,外层为简单的代码).还望喜欢的朋友们,不 ...
- 基于Linux C的socket抓包程序和Package分析 (一)
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/guankle/article/details/27538031 測试执行平台:CentOS 6 ...
随机推荐
- 基本排序算法——快速排序java实现
简单的快速排序算法,我竟然花费了如此多的时间来写作,好好学习. /** * */ package basic.sort; import java.util.Arrays; import java.ut ...
- IOS开发札记(2015-08-20)
View显示数据借助Model的一个比较好的理由也是因为:有时候从服务器获取的数据相同的value可能对应不同的key(服务端多人协作开发时经常会出现这种情况) 这里盗图描述一下使用Model的好处 ...
- 设置statusBarStyle
设置状态栏的样式, typedef NS_ENUM(NSInteger, UIStatusBarStyle) { UIStatusBarStyleDefault ...
- Activity详解三 启动activity并返回结果
首先看演示: 1 简介 .如果想在Activity中得到新打开Activity 关闭后返回的数据,需要使用系统提供的startActivityForResult(Intent intent, int ...
- RoundedBitmapDrawable生成圆角图片
Bitmap src = BitmapFactory.decodeResource(getResources(), imageId); //获取Bitmap图片 RoundedBitmapDrawab ...
- SqlServer主键和外键
*主键 主键就是数据行的唯一标识.不会重复的列才能当主键.一个表可以没有主键,但是会非常难以处理,因此没有特殊理由表都要设定主键. *主键特点:1不能重复的列.2主键不能为null. *同名时如何处理 ...
- [AlwaysOn Availability Groups]CLUSTER.LOG(AG)
CLUSTER.LOG(AG) 作为故障转移资源,在SQL Server和windows故障转移集群服务的资源DLL(hadrres.dll)之间有额外的内部交流,DLL无法被SQL Server监控 ...
- 今天发现一些很有意思的ubuntu命令
跑火车的sl/LS 终端数字雨cmatrix 可能是名言警句也可能是逗你玩的笑话的fortune/fortune-zh 一只会说话的牛 一只会吟诗的牛 上真牛喽! 炫酷 炫酷到这里了!!!
- MMORPG大型游戏设计与开发(服务器 游戏场景 地图和区域)
地图的数据以及区域的信息是场景的重要组成部分,这些数据同时存在客户端和服务器,而且都是由编辑器生成的.那么保存的文件数据结构是怎样的?一张3D的场景地图又是怎样处理这些数据的?同时告诉大家这里同样只是 ...
- C#学习笔记-图像处理篇(一)绘制公章
上个月免费帮别人做事,就一直在服务员和程序员中来回切换,所以好多事情都弄得乱糟糟的,家里也是乱七八糟的,所以学习这一块也放了一段时间. 刚刚开始当服务员的时间看到了形形色色的人,觉得很好玩,他们每个人 ...