Python丢包测试脚本(以串口为例)

说明

Python作为接收端,以指定格式接收数据,可以统计速率和丢包率等信息,效果如下:

运行: 9751| 总接收: 4889456640 字节 | 速率: 489.894 KB/s | 3.827 Mbps | 收到 4774860| 丢了 0| 当前包序 11098121
运行: 9752| 总接收: 4889960448 字节 | 速率: 489.320 KB/s | 3.823 Mbps | 收到 4775352| 丢了 0| 当前包序 11098613

格式

| AA 55 | 4B 序列号 | 数据 | 4B CRC32(序列号+数据) |

例如第一包:

AA 55 00 00 00 01 ---1014字节数据---  56 0d 2a 33

配置

这里以串口为例,仅维护port_init()和port_read()即可

# 接口配置(这里已串口为例)--------------------------------------------------------
ser = None

def port_init():
    global ser, buffer
    try:
        ser = serial.Serial(port='COM38', baudrate=115200, timeout=0.1)
    except:
        print("串口打开失败")
        exit(-1)

def port_read():
    global ser
    return ser.read(4096)
# -----------------------------------------------------------------------------

完整源代码

import serial
import time
import binascii

# 配置参数(必须与发送端一致)--------------------------------------------------------
# | AA 55 | 4B 序列号 | 数据 | 4B CRC(序列号+数据) |
PACKET_SIZE = 1024  # 每个数据包的总字节数
HEADER = b'\xAA\x55'  # 2字节包头
SEQ_OFFSET = 2  # 包头后4字节为序列号

last_seq = -1
total_packets = 0
lost_packets = 0

buffer = bytearray()
# -----------------------------------------------------------------------------


# 接口配置(这里已串口为例)--------------------------------------------------------
ser = None

def port_init():
    global ser, buffer
    try:
        ser = serial.Serial(port='COM38', baudrate=115200, timeout=0.1)
    except:
        print("串口打开失败")
        exit(-1)

def port_read():
    global ser
    return ser.read(4096)
# -----------------------------------------------------------------------------

# 以下代码无需修改--------------------------------------------------------
def parse_packets():
    """解析数据包 计算丢包率"""

    global buffer, last_seq, total_packets, lost_packets
    while len(buffer) >= PACKET_SIZE:
        # 查找包头
        header_pos = buffer.find(HEADER)
        if header_pos == -1:
            buffer.clear()
            return

        # 丢弃包头前的无效数据
        if header_pos > 0:
            del buffer[:header_pos]
            continue

        # 提取序列号(4字节 高字节在前)
        seq = int.from_bytes(buffer[SEQ_OFFSET:SEQ_OFFSET + 4], 'big', signed=False)
        crc = int.from_bytes(buffer[PACKET_SIZE-4:PACKET_SIZE], 'big', signed=False)
        check_crc = binascii.crc32(buffer[2:PACKET_SIZE-4])

        if check_crc == crc:
            #计算丢包
            if last_seq != -1 and seq != (last_seq + 1):
                lost_packets += (seq - last_seq - 1)

            last_seq = seq

        total_packets += 1

        # 移除已处理的数据包
        del buffer[:PACKET_SIZE]


def main():
    global buffer, last_seq, total_packets, lost_packets

    print("监控中...")

    total_received = 0  # 所有接收字节
    current_count = 0  # 当前接收字节 计算码率
    last_time = time.time()
    start_time = time.time()

    while True:
        # 读取数据
        data = port_read()
        if data:
            data_len = len(data)
            total_received += data_len
            current_count += data_len

            buffer.extend(data)
            parse_packets()

        delta_time = time.time() - last_time

        # 每秒显示统计
        if time.time() - last_time >= 1:
            rate = current_count / delta_time  # 字节/秒
            print(
                f"运行: {int(time.time() - start_time)} 秒 | "
                f"总接收: {total_received} 字节 | "
                f"速率: {rate / 1024:.3f} KB/s | "
                f"{rate * 8 / (1024 * 1024):.3f} Mbps | "
                f"收到 {total_packets} 包 | "
                f"丢了 {lost_packets} 包 | "
                f"当前包序 {last_seq}"
            )

            current_count = 0
            last_time = time.time()

        # 降低CPU占用
        time.sleep(0.001)

if __name__ == "__main__":
    port_init()
    main()

你可能感兴趣的:(python,网络,c语言,单片机,嵌入式)