Java | Sigar:获取网络流量
Java | Sigar: Getting network traffic
我正在尝试在 Sigar 库
的帮助下使用 Java 中的以下代码获取网络流量
import java.util.*;
import java.util.Map.Entry;
import org.hyperic.sigar.NetFlags;
import org.hyperic.sigar.NetInterfaceConfig;
import org.hyperic.sigar.NetInterfaceStat;
import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.SigarException;
public class NetworkBandwidth {
private Map<String, Long> rxCurrentMap = new HashMap<String, Long>();
private Map<String, List<Long>> rxChangeMap = new HashMap<String, List<Long>>();
private Map<String, Long> txCurrentMap = new HashMap<String, Long>();
private Map<String, List<Long>> txChangeMap = new HashMap<String, List<Long>>();
private List<String> msg;
private Sigar sigar;
private String TAG = "LOG: ", serverCode;
private volatile boolean stopGettingNetworkBandwidth = false;
private ChannelHandlerContext ctx;
public NetworkBandwidth(String serverCode, ChannelHandlerContext ctx){
this.sigar = new Sigar();
this.serverCode = serverCode;
this.ctx = ctx;
this.msg = new ArrayList<>();
try {
getMetric();
System.out.println(TAG + "NETWORK INFO: " + networkInfo());
} catch (SigarException e) {
System.out.println(e.toString());
}
private Long[] getMetric() throws SigarException {
for (String ni : sigar.getNetInterfaceList()) {
// System.out.println(ni);
NetInterfaceStat netStat = sigar.getNetInterfaceStat(ni);
NetInterfaceConfig ifConfig = sigar.getNetInterfaceConfig(ni);
String hwaddr = null;
if (!NetFlags.NULL_HWADDR.equals(ifConfig.getHwaddr())) {
hwaddr = ifConfig.getHwaddr();
}
if (hwaddr != null) {
long rxCurrenttmp = netStat.getRxBytes();
saveChange(rxCurrentMap, rxChangeMap, hwaddr, rxCurrenttmp, ni);
long txCurrenttmp = netStat.getTxBytes();
saveChange(txCurrentMap, txChangeMap, hwaddr, txCurrenttmp, ni);
}
}
long totalrx = getMetricData(rxChangeMap);
long totaltx = getMetricData(txChangeMap);
for (List<Long> l : rxChangeMap.values())
l.clear();
for (List<Long> l : txChangeMap.values())
l.clear();
return new Long[] { totalrx, totaltx };
}
private static long getMetricData(Map<String, List<Long>> rxChangeMap) {
long total = 0;
for (Entry<String, List<Long>> entry : rxChangeMap.entrySet()) {
int average = 0;
for (Long l : entry.getValue()) {
average += l;
}
total += average / entry.getValue().size();
}
return total;
}
private static void saveChange(Map<String, Long> currentMap,
Map<String, List<Long>> changeMap, String hwaddr, long current,
String ni) {
Long oldCurrent = currentMap.get(ni);
if (oldCurrent != null) {
List<Long> list = changeMap.get(hwaddr);
if (list == null) {
list = new LinkedList<Long>();
changeMap.put(hwaddr, list);
}
list.add((current - oldCurrent));
}
currentMap.put(ni, current);
}
private String networkInfo() throws SigarException {
String info = sigar.getNetInfo().toString();
info += "\n"+ sigar.getNetInterfaceConfig().toString();
return info;
}
public void stopGettingNetworkBandwidth(boolean stop){
stopGettingNetworkBandwidth = stop;
}
public void getBandwidth() throws SigarException, InterruptedException {
new Thread(new Runnable() {
@Override
public void run() {
while (true){
try{
Long[] m = getMetric();
long totalrx = m[0];
long totaltx = m[1];
System.out.print("totalrx(download): ");
System.out.println("\t" + Sigar.formatSize(totalrx));
System.out.print("totaltx(upload): ");
System.out.println("\t" + Sigar.formatSize(totaltx));
System.out.println("-----------------------------------");
Thread.sleep(1000);
}catch (SigarException e){
System.out.println(TAG + "Failed to get Network Bandwidth, SigarException >> " + e.toString());
}catch (InterruptedException e){
System.out.println(TAG + "Failed to get Network Bandwidth, InterruptedException >> " + e.toString());
}
if (stopGettingNetworkBandwidth)break;if (stopGettingNetworkBandwidth)break;
}
}
}).start();
}
}
虽然我在浏览互联网时遇到了网络流量,但直到我意识到我得到了意想不到的结果。
我正在开发在 LAN 内部通信的服务器和客户端应用程序,当我没有使用或浏览互联网但由于应用程序正在通信时,我期望 0
作为上述代码的结果在局域网内,我总是得到一个结果。
关于如何获得互联网使用率的任何想法except when the Server and Client is sending or receiving message inside the LAN
?
感谢 Ron Maupin 有条件的想法。
我是这样解决的
我把方法getBandWidth()
改成了getTraffic()
,
public void getTraffic() throws SigarException, InterruptedException {
new Thread(new Runnable() {
@Override
public void run() {
long oldReceived = 0, oldSend = 0, newReceived, newSend;
while (true){
try{
Long[] m = getMetric();
newReceived = m[0];
newSend = m[1];
if(oldReceived != newReceived || oldSend != newSend){ //if the result is different from the previous
oldReceived = newReceived; //put the new result to old result
oldSend = newSend; //put the new result to old result
if(oldReceived > 999 || oldSend > 999 && oldReceived == 0 || oldSend == 0){
System.out.print("totalrx(download): ");
System.out.println("\t" + Sigar.formatSize(newReceived));
System.out.print("totaltx(upload): ");
System.out.println("\t" + Sigar.formatSize(newSend));
System.out.println("-----------------------------------");
}
}
Thread.sleep(1000);
}catch (SigarException e){
System.out.println(TAG + "Failed to get Network Traffic, SigarException >> " + e.toString());
}catch (InterruptedException e){
System.out.println(TAG + "Failed to get Network Traffic, InterruptedException >> " + e.toString());
}
if (stopGettingNetworkBandwidth)break;if (stopGettingNetworkBandwidth)break;
}
}
}).start();
}
我意识到我不是在寻找带宽而是网络流量,观察结果后,我发现当我的 Server
和 Client
在内部发送和接收数据时本地网络,结果不到一千,而我在浏览或下载时结果等于一千或更高。
我不确定这是否是可靠的解决方案,但与此同时我将使用此解决方案,直到找到第二个选项。
我正在尝试在 Sigar 库
的帮助下使用 Java 中的以下代码获取网络流量import java.util.*;
import java.util.Map.Entry;
import org.hyperic.sigar.NetFlags;
import org.hyperic.sigar.NetInterfaceConfig;
import org.hyperic.sigar.NetInterfaceStat;
import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.SigarException;
public class NetworkBandwidth {
private Map<String, Long> rxCurrentMap = new HashMap<String, Long>();
private Map<String, List<Long>> rxChangeMap = new HashMap<String, List<Long>>();
private Map<String, Long> txCurrentMap = new HashMap<String, Long>();
private Map<String, List<Long>> txChangeMap = new HashMap<String, List<Long>>();
private List<String> msg;
private Sigar sigar;
private String TAG = "LOG: ", serverCode;
private volatile boolean stopGettingNetworkBandwidth = false;
private ChannelHandlerContext ctx;
public NetworkBandwidth(String serverCode, ChannelHandlerContext ctx){
this.sigar = new Sigar();
this.serverCode = serverCode;
this.ctx = ctx;
this.msg = new ArrayList<>();
try {
getMetric();
System.out.println(TAG + "NETWORK INFO: " + networkInfo());
} catch (SigarException e) {
System.out.println(e.toString());
}
private Long[] getMetric() throws SigarException {
for (String ni : sigar.getNetInterfaceList()) {
// System.out.println(ni);
NetInterfaceStat netStat = sigar.getNetInterfaceStat(ni);
NetInterfaceConfig ifConfig = sigar.getNetInterfaceConfig(ni);
String hwaddr = null;
if (!NetFlags.NULL_HWADDR.equals(ifConfig.getHwaddr())) {
hwaddr = ifConfig.getHwaddr();
}
if (hwaddr != null) {
long rxCurrenttmp = netStat.getRxBytes();
saveChange(rxCurrentMap, rxChangeMap, hwaddr, rxCurrenttmp, ni);
long txCurrenttmp = netStat.getTxBytes();
saveChange(txCurrentMap, txChangeMap, hwaddr, txCurrenttmp, ni);
}
}
long totalrx = getMetricData(rxChangeMap);
long totaltx = getMetricData(txChangeMap);
for (List<Long> l : rxChangeMap.values())
l.clear();
for (List<Long> l : txChangeMap.values())
l.clear();
return new Long[] { totalrx, totaltx };
}
private static long getMetricData(Map<String, List<Long>> rxChangeMap) {
long total = 0;
for (Entry<String, List<Long>> entry : rxChangeMap.entrySet()) {
int average = 0;
for (Long l : entry.getValue()) {
average += l;
}
total += average / entry.getValue().size();
}
return total;
}
private static void saveChange(Map<String, Long> currentMap,
Map<String, List<Long>> changeMap, String hwaddr, long current,
String ni) {
Long oldCurrent = currentMap.get(ni);
if (oldCurrent != null) {
List<Long> list = changeMap.get(hwaddr);
if (list == null) {
list = new LinkedList<Long>();
changeMap.put(hwaddr, list);
}
list.add((current - oldCurrent));
}
currentMap.put(ni, current);
}
private String networkInfo() throws SigarException {
String info = sigar.getNetInfo().toString();
info += "\n"+ sigar.getNetInterfaceConfig().toString();
return info;
}
public void stopGettingNetworkBandwidth(boolean stop){
stopGettingNetworkBandwidth = stop;
}
public void getBandwidth() throws SigarException, InterruptedException {
new Thread(new Runnable() {
@Override
public void run() {
while (true){
try{
Long[] m = getMetric();
long totalrx = m[0];
long totaltx = m[1];
System.out.print("totalrx(download): ");
System.out.println("\t" + Sigar.formatSize(totalrx));
System.out.print("totaltx(upload): ");
System.out.println("\t" + Sigar.formatSize(totaltx));
System.out.println("-----------------------------------");
Thread.sleep(1000);
}catch (SigarException e){
System.out.println(TAG + "Failed to get Network Bandwidth, SigarException >> " + e.toString());
}catch (InterruptedException e){
System.out.println(TAG + "Failed to get Network Bandwidth, InterruptedException >> " + e.toString());
}
if (stopGettingNetworkBandwidth)break;if (stopGettingNetworkBandwidth)break;
}
}
}).start();
}
}
虽然我在浏览互联网时遇到了网络流量,但直到我意识到我得到了意想不到的结果。
我正在开发在 LAN 内部通信的服务器和客户端应用程序,当我没有使用或浏览互联网但由于应用程序正在通信时,我期望 0
作为上述代码的结果在局域网内,我总是得到一个结果。
关于如何获得互联网使用率的任何想法except when the Server and Client is sending or receiving message inside the LAN
?
感谢 Ron Maupin 有条件的想法。
我是这样解决的
我把方法getBandWidth()
改成了getTraffic()
,
public void getTraffic() throws SigarException, InterruptedException {
new Thread(new Runnable() {
@Override
public void run() {
long oldReceived = 0, oldSend = 0, newReceived, newSend;
while (true){
try{
Long[] m = getMetric();
newReceived = m[0];
newSend = m[1];
if(oldReceived != newReceived || oldSend != newSend){ //if the result is different from the previous
oldReceived = newReceived; //put the new result to old result
oldSend = newSend; //put the new result to old result
if(oldReceived > 999 || oldSend > 999 && oldReceived == 0 || oldSend == 0){
System.out.print("totalrx(download): ");
System.out.println("\t" + Sigar.formatSize(newReceived));
System.out.print("totaltx(upload): ");
System.out.println("\t" + Sigar.formatSize(newSend));
System.out.println("-----------------------------------");
}
}
Thread.sleep(1000);
}catch (SigarException e){
System.out.println(TAG + "Failed to get Network Traffic, SigarException >> " + e.toString());
}catch (InterruptedException e){
System.out.println(TAG + "Failed to get Network Traffic, InterruptedException >> " + e.toString());
}
if (stopGettingNetworkBandwidth)break;if (stopGettingNetworkBandwidth)break;
}
}
}).start();
}
我意识到我不是在寻找带宽而是网络流量,观察结果后,我发现当我的 Server
和 Client
在内部发送和接收数据时本地网络,结果不到一千,而我在浏览或下载时结果等于一千或更高。
我不确定这是否是可靠的解决方案,但与此同时我将使用此解决方案,直到找到第二个选项。