复杂网络下根据包序号统计丢包率

该代码实现了一个在复杂网络环境中统计TCP数据包丢包率的工具。通过对接收到的数据包序号进行管理和比较,计算丢包情况,并通过日志输出丢包率。程序首先初始化包序号映射,然后根据接收到的数据包序号更新映射,判断丢包并计算丢包率。此外,当包序号差距过大时,会进行序号重置以确保准确性。

复杂网络下根据包序号统计丢包率

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);
 }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值