通过 cat /proc/net/dev 和 ethtool [net] 两个信息,计算网络带宽、吞吐速率和带宽利用率。
package demo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Properties;
/**
* 采集网络带宽使用率
*
* ****************************
* cat /proc/net/dev
* Inter-| Receive | Transmit
* face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
* lo: 341566047 4020765 0 0 0 0 0 0 341566047 4020765 0 0 0 0 0 0
* enp0s31f6: 7222870592 9003564 0 0 0 0 0 125359 680013336 4352932 0 0 0 0 0 0
*
* ****************************
* ethtool enp0s31f6
* Settings for enp0s31f6:
* Supported ports: [ TP ]
* Supported link modes: 10baseT/Half 10baseT/Full
* 100baseT/Half 100baseT/Full
* 1000baseT/Full
* Supported pause frame use: No
* Supports auto-negotiation: Yes
* Advertised link modes: 10baseT/Half 10baseT/Full
* 100baseT/Half 100baseT/Full
* 1000baseT/Full
* Advertised pause frame use: No
* Advertised auto-negotiation: Yes
* Speed: 1000Mb/s
* Duplex: Full
* Port: Twisted Pair
* PHYAD: 1
* Transceiver: internal
* Auto-negotiation: on
* MDI-X: on (auto)
*/
public class NetUsage {
private static NetUsage instance = new NetUsage();
private static Runtime r = Runtime.getRuntime();
private static float bandWidth = 1000;
private static final String NET_COMMAND = "cat /proc/net/dev";
private static final String NET_NAME = "enp0s31f6";
private static final String SPEED = "Speed";
private static final String ETH_COMMAND = "ethtool " + NET_NAME;
private NetUsage() {
}
public static NetUsage getInstance() {
return instance;
}
static {
Process process = null;
try {
process = r.exec(ETH_COMMAND);
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
line = line.trim();
if (line.startsWith(SPEED)) {
String[] temp = line.split("\\s+");
bandWidth = Float.parseFloat(temp[1].split("Mb/s")[0]);
break;
}
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
process.destroy();
}
private static class Net {
private Long time;
private Long inSize;
private Long outSize;
public Net() {
this.time = System.currentTimeMillis();
this.inSize = 0L;
this.outSize = 0L;
}
public Long getTime() {
return time;
}
public void setTime(Long time) {
this.time = time;
}
public Long getInSize() {
return inSize;
}
public void setInSize(Long inSize) {
this.inSize = inSize;
}
public Long getOutSize() {
return outSize;
}
public void setOutSize(Long outSize) {
this.outSize = outSize;
}
}
public void samplingCalculation() {
Net start = new Net();
Net end = new Net();
try {
//第一次采集流量数据
takeInAndOutSize(start);
//间隔 1s
Thread.sleep(1000);
//第二次采集流量数据
takeInAndOutSize(end);
//计算传输指标
compute(start, end);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
public float compute(Net start, Net end) {
float netUsage;
float interval = (float) (end.getTime() - start.getTime()) / 1000;
float curRate = (float) (Math.abs(end.getInSize() - start.getInSize()) + Math.abs(end.getOutSize() - start.getOutSize())) / (131072 * interval);
netUsage = curRate / bandWidth;
System.out.println("当前吞吐速率: " + curRate + "Mbps");
System.out.println("网络带宽使用率为: " + netUsage * 100 + " %");
return netUsage;
}
public void takeInAndOutSize(Net net) throws IOException {
net.setTime(System.currentTimeMillis());
Process process = r.exec(NET_COMMAND);
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
line = line.trim();
if (line.startsWith(NET_NAME)) {
String[] temp = line.split("\\s+");
net.setInSize(Long.parseLong(temp[1]));
net.setOutSize(Long.parseLong(temp[9]));
break;
}
}
reader.close();
process.destroy();
}
public static void main(String[] args) {
while (1 > 0) {
NetUsage.getInstance().samplingCalculation();
}
}
}