复杂网络下根据包序号统计丢包率
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Description:
* @Date: 2020/12/14 9:55
* @Author: Justin
*/
public class Test {
private static final Logger ONOFFLINE_INFO_LOG = LoggerFactory.getLogger(Test.class);
private static Map<String, Map<String, Object>> packageNumMap = new HashMap<>();
private static int byteMaxNum = 65536;
//private static int data[] = {9, 8, 4, 5, 6, 7, 0, 1, 2, 3, 5, 11, 10, 5, 6, 7};
//private static int data[] = {9, 8, 4, 5, 6, 7, 0, 1, 2, 3};
private static int data[] = {9, 8, 4, 6, 7, 0, 1, 2, 3, 5};
public static void main(String[] args) {
for (int j = 0; j < data.length; j++) {
judgeLosePackage("test", data[j], "03", "80");
try {
Map<String, Map<String, Object>> packageNumMap = getPackageNumMap();
for (String key : packageNumMap.keySet()) {
Map<String, Object> packageMap = packageNumMap.get(key);
int minPno = (int) packageMap.get("minPno");
int maxPno = (int) packageMap.get("maxPno");
int currentMaxPno = (int) packageMap.get("maxPno");
byte[] packageByte = (byte[]) packageMap.get("packageByte");
int num = maxPno - minPno + 1;
Integer loseCount = 0;
List list = new ArrayList<>();
for (int i = 0; i < num; maxPno--, i++) {
if (get(packageByte, maxPno) == 0) {
loseCount++;
}
list.add(get(packageByte, maxPno));
}
System.out.println(list.toString());
DecimalFormat decimalFormat = new DecimalFormat("0.0000");
String losePercent = decimalFormat.format((float) loseCount / num);
ONOFFLINE_INFO_LOG.info("丢包 unicode|functionCode is:{}, 当前最小包序号:{}, 当前最大包序号:{}, 累计应收到包:{}个, 累计丢包: {}个, 丢包率 is: {}",
key, minPno, currentMaxPno, num, loseCount, losePercent);
}
} catch (Exception e) {
ONOFFLINE_INFO_LOG.error("judgeLosePackage error:{}", e.getMessage());
}
}
}
public static Map<String, Map<String, Object>> getPackageNumMap() {
return packageNumMap;
}
private static void setPackageMap(int currentPno, Map<String, Object> packageMap) {
packageMap.put("minPno", currentPno);
packageMap.put("maxPno", currentPno);
byte[] packageByte = new byte[byteMaxNum];
set(packageByte, currentPno);
packageMap.put("packageByte", packageByte);
}
/**
unicode: 唯一码
currentPno:包序号
functionCode:功能码
frameType:帧类型
**/
public static void judgeLosePackage(String unicode, int currentPno, String functionCode, String frameType) {
String key = unicode + "|" + functionCode;
if (packageNumMap.containsKey(key)) {
// 每天重新设置计时时间
Map<String, Object> packageMap = packageNumMap.get(key);
int minPno = (int) packageMap.get("minPno");
int maxPno = (int) packageMap.get("maxPno");
// 初始化是清空序号
if (currentPno == 0 && maxPno < 65535 && frameType.equals("00")) {
ONOFFLINE_INFO_LOG.info("重启,frameType:{}, 序号清零:{}", key, frameType);
setPackageMap(currentPno, packageMap);
}
byte[] packageByte = (byte[]) packageMap.get("packageByte");
if (currentPno < minPno) {
minPno = currentPno;
} else if (currentPno > maxPno) {
maxPno = currentPno;
}
// 最新包序号与初始序号相差较大时清空序号
if ((maxPno - minPno) >= byteMaxNum) {
maxPno = minPno;
ONOFFLINE_INFO_LOG.info("frameType:{}, 序号清零:{}", key, frameType);
setPackageMap(maxPno, packageMap);
packageByte = (byte[]) packageMap.get("packageByte");
} else if (Math.abs((maxPno - currentPno)) >= 50) {
ONOFFLINE_INFO_LOG.info("当前包与上一个包序号相差大于50则重置 frameType:{}, 序号清零:{}, currentPno:{}, maxPno:{}", key, frameType, currentPno, maxPno);
// 当前包与上一个包序号相差大于100则重置
setPackageMap(currentPno, packageMap);
packageByte = (byte[]) packageMap.get("packageByte");
} else {
if (currentPno == minPno) {
packageMap.put("minPno", currentPno);
} else if (currentPno == maxPno) {
packageMap.put("maxPno", currentPno);
}
}
set(packageByte, currentPno);
packageNumMap.put(key, packageMap);
} else {
Map<String, Object> packageMap = new HashMap();
setPackageMap(currentPno, packageMap);
ONOFFLINE_INFO_LOG.info("数据接收:key is {}, currentPno is {}", key, currentPno);
packageNumMap.put(key, packageMap);
}
}
/**
* num/8得到byte[]的index
*/
public static int getIndex(int num) {
return num >> 3;
}
/**
* 计算num在byte[]中的位置
*/
public static int getPosition(int num) {
return num & 0x07;
}
public static int get(byte[] bits, int num) {
return bits[getIndex(num)] >> getPosition(num) & 1;
}
public static void set(byte[] bits, int num) {
bits[getIndex(num)] |= 1 << getPosition(num);
}
}