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 ...
随机推荐
- iOS之开发支付功能概述
前言:本随笔将对IOS开发的支付功能进行一个概述. 内容大纲: 一.常见的支付方案简介 二.第三方支付SDK 三.苹果官方支付方案 四.Web支付方案 正文: 一.常见的支付方案简介 在微信支付中 微 ...
- iOS之自定义pickerview(行驶里程数)
#pragma mark -- 里程数按钮的点击事件 - (void)mileageBtnClicked:(UIButton *)sender { UIAlertController *alert = ...
- IOS开发基础知识--碎片34
1:第三方插件SKSTableView在IOS7.1.1出现闪退的问题 解决办法,修改其内部源代码: (NSInteger)subRow { id indexpath = [NSIndexPath c ...
- [转]完美洗牌(Perfect Shuffle)问题
[转]原博文地址:https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/02.09.md ...
- mysql 基本
mysql -u root -p 输入密码进入数据库 show database; 查询当前库 use databasename 切换到某个库 show tables; 列出当前数据库的表 desc ...
- 深入解析Windows操作系统笔记——CH2系统结构
2.系统结构 本章主要介绍系统的总体结构,关键部件之间的交互,以及运行在什么环境. 2.系统结构 2.1 需求和设计目标 2.2 操作系统模型 2.3 总体结构 2.3.1 可移植性 2.3.2 对称 ...
- JDBC Driver Types
JDBC Driver Types Type1: JDBC-ODBC Bridge Driver Type2: JDBC-Native API Type3: JDBC-Net Pure Java Ty ...
- sshfs 实现普通用户可读写
先实现普通用户免密码host1可登入host2host1# yum install fuse sshfs; 如果装不上,需要安装epep源 --enablerepo=epelhost1# su - e ...
- ubuntu下apache重启报Could not reliably determine the server’s fully......
在Ubuntu上安装Apache,每次重启,都会出现以下错误提示: Could not reliably determine the server’s fully qualified domain n ...
- JQuery记住用户名和密码的具体实现
代码如下: //初始化页面时验证是否记住了密码 $(document).ready(function() { if ($.cookie("rmbUser") == "tr ...