Go语言获取实时网速(gopacket实践)
简介
gopacket
是经过cgo
封装的libpcap
的接口,这样便于我们在go
语言中使用libpcap
。
前提
libpcap
是Linux平台的抓包框架,它也有Windows移植版,比如winpcap
,但在2013年已停止维护。所以本文采用的是winpcap
官方推荐的npcap
。
npcap的安装
- 首先下载npcap以及npcap-sdk;
- 安装
npcap
; - 解压
npcap-sdk
到C:\WpdPack
。(gopacket
的cgo
实现会在这个位置寻找pcap.h
)
代码
package mainimport ("errors""flag""fmt""github.com/google/gopacket""github.com/google/gopacket/layers""github.com/google/gopacket/pcap""log""net""os""time"
)var (downStreamDataSize = 0 // 单位时间内下行的总字节数upStreamDataSize = 0 // 单位时间内上行的总字节数deviceName = flag.String("i", "eth0", "network interface device name") // 要监控的网卡名称
)func main() {flag.Parse()// Find all devices// 获取所有网卡devices, err := pcap.FindAllDevs()if err != nil {log.Fatal(err)}// Find exact device// 根据网卡名称从所有网卡中取到精确的网卡var device pcap.Interfacefor _, d := range devices {if d.Name == *deviceName {device = d}}// 根据网卡的ipv4地址获取网卡的mac地址,用于后面判断数据包的方向macAddr, err := findMacAddrByIp(findDeviceIpv4(device))if err != nil {panic(err)}fmt.Printf("Chosen device's IPv4: %s\n", findDeviceIpv4(device))fmt.Printf("Chosen device's MAC: %s\n", macAddr)// 获取网卡handler,可用于读取或写入数据包handle, err := pcap.OpenLive(*deviceName, 1024 /*每个数据包读取的最大值*/, true /*是否开启混杂模式*/, 30*time.Second /*读包超时时长*/)if err != nil {panic(err)}defer handle.Close()// 开启子线程,每一秒计算一次该秒内的数据包大小平均值,并将下载、上传总量置零go monitor() // 开始抓包packetSource := gopacket.NewPacketSource(handle, handle.LinkType())for packet := range packetSource.Packets() {// 只获取以太网帧ethernetLayer := packet.Layer(layers.LayerTypeEthernet)if ethernetLayer != nil {ethernet := ethernetLayer.(*layers.Ethernet)// 如果封包的目的MAC是本机则表示是下行的数据包,否则为上行if ethernet.DstMAC.String() == macAddr {downStreamDataSize += len(packet.Data()) // 统计下行封包总大小} else {upStreamDataSize += len(packet.Data()) // 统计上行封包总大小}}}
}// 获取网卡的IPv4地址
func findDeviceIpv4(device pcap.Interface) string {for _, addr := range device.Addresses {if ipv4 := addr.IP.To4(); ipv4 != nil {return ipv4.String()}}panic("device has no IPv4")
}// 根据网卡的IPv4地址获取MAC地址
// 有此方法是因为gopacket内部未封装获取MAC地址的方法,所以这里通过找到IPv4地址相同的网卡来寻找MAC地址
func findMacAddrByIp(ip string) (string, error) {interfaces, err := net.Interfaces()if err != nil {panic(interfaces)}for _, i := range interfaces {addrs, err := i.Addrs()if err != nil {panic(err)}for _, addr := range addrs {if a, ok := addr.(*net.IPNet); ok {if ip == a.IP.String() {return i.HardwareAddr.String(), nil}}}}return "", errors.New(fmt.Sprintf("no device has given ip: %s", ip))
}// 每一秒计算一次该秒内的数据包大小平均值,并将下载、上传总量置零
func monitor() {for {os.Stdout.WriteString(fmt.Sprintf("\rDown:%.2fkb/s \t Up:%.2fkb/s", float32(downStreamDataSize)/1024/1, float32(upStreamDataSize)/1024/1))downStreamDataSize = 0upStreamDataSize = 0time.Sleep(1 * time.Second)}
}
运行
运行的时候需要指定网卡名称,如: ./speedTest -i etc0
。
但是在Windows
平台有些不一样,因为gopacket
接口返回的deviceName
是Windows
平台特有Transport Name
,通过getmac
命令即可获得MAC
与Transport Name
的对应关系了:
C:\Users\hanzi>getmac物理地址 传输名称
=================== ==========================================================
00-50-56-C0-00-08 \Device\Tcpip_{0849F909-8F06-475C-B0D3-81F5902DA026}
00-FF-D8-BD-B9-CF 媒体已断开连接
00-50-56-C0-00-01 \Device\Tcpip_{55A0F561-C6BF-4E15-9E97-D378BDB2B856}
36-15-2F-36-64-AE \Device\Tcpip_{E1264F2B-388D-4992-A9DE-040165E3A4EE}
4C-CC-6A-B7-E6-D6 \Device\Tcpip_{DF0ECEC3-C9D5-4D38-946F-3E5CD67CCA2E}
02-00-4C-4F-4F-50 \Device\Tcpip_{0D1DF6B1-ADA4-485B-B0A6-B95C2EC619A5}
在笔者电脑上运行./speedTest -i \Device\NPF_{DF0ECEC3-C9D5-4D38-946F-3E5CD67CCA2E}
, 输出:
Chosen device's IPv4: 192.168.0.8
Chosen device's MAC: 4c:cc:6a:b7:e6:d6
Down:48.26kb/s Up:3.20kb/s
以上代码的正确运行需要网卡有IPv4
,但可以很容易的扩展到IPv6
(响应工信部号召) 。
Go语言获取实时网速(gopacket实践)相关推荐
- linux查看当前网卡网速,Linux环境编程:获取网卡的实时网速
在Windows下面,我们可以看到360或者是qq安全卫士的"安全球",上面显示实时的网速情况.那么在Linux里面如何获取网卡的实时网速?其实原理很简单,读取需要获取网速的网卡在 ...
- ubuntu中显示实时网速的方法
ubuntu中显示实时网速的方法:1.打开ubuntu系统终端:2.输入"sudo add-apt-repository ppa:fossfreedom/indicator-sysmonit ...
- 实时网速监测app_实时网速-实时网速app安卓版下载v1.0-我爱秘籍
实时网速app,是一款非常方便实用的手机网速监测软件.平台为用户提供了监测展示流量数据使用情况的功能,用户可以自定义设置界面和展示的显示信息,实时查询手机数据,感兴趣的用户快来下载吧! 实时网速特色 ...
- C# 实现实时网速
前言 最近参加了一个项目,所以写博客的时间就少了,项目中有一个功能就是在窗体上显示实时网速,用了半天的时间写了出来,想想今天时间蛮充足,就把它分享到博客上吧. 项目展示 项目核心代码: private ...
- windows状态栏里显示实时网速
小可爱我上线了~ 如标题所示:windows状态栏里显示实时网速 图如下 在这里插入图片描述 U:Upload-上传速度 D:Download-下载速度 接下来贴出我成功的步骤 下载网速检测模块net ...
- python request下载文件时、显示进度以及网速_实时网速显示_实例_python
import psutil import time from tkinter import * def make_app(): app =Tk() app.geometry('200x100') ap ...
- <Linux开发> ubuntu开发工具-Ubuntu测试网速及实时网速图
<Linux开发> ubuntu开发工具-Ubuntu测试网速及实时网速图 一.查看网线上行.下行网速 1.安装speedtest-cli工具 water@water-Tower-PC:~ ...
- 【Linux】监控实时网速 查看实时网速
sar sar -n DEV 1 100 1代表一秒统计并显示一次 100代表统计一百次 nload # 查看所有网卡实时网速 sudo nload -m # 查看指定网卡实时网速 sudo nloa ...
- Mac上实时网速、内存等显示
对我这种有强迫症的,要监控各种参数,比如实时网速显示,这里给大家推荐 iStat Menus 1.官网下载 https://bjango.com/mac/istatmenus/ 2.注册码(仅供学习 ...
最新文章
- JAVA基础2-输出语句
- React使用Styled-Componets来添加样式
- 关于程序为什么要代码段,程序段
- TRzCheckTree
- 获取 input 单选框和多选框的值
- 如何进行I/O评估、监控、定位和优化?
- 深入php内核,从底层c语言剖析php实现原理
- 高性能云网关,打通云内外业务互通的任督二脉
- Matlab之subplot函数
- EXCEL中制作省市区行政区地图
- SQL中删除重复数据问题
- STM32 USART 多摩川编码器调试
- w ndows10启动黑屏,win10开机一直黑屏的解决方法
- 单路视频编码器怎么使用
- voip 软电话 客户端实例 SIP
- linux下下载fnl数据,如何下载fnl
- 焦点弦的垂直平分线和轴的交点到焦点的距离和焦点弦的距离之比为二分之e
- 邻居表项的mcast_solicit数量
- ReadProcessMemory()
- stackoverflow 查看最新回复