【问题标题】:Getting audio file from a UDP packet从 UDP 数据包中获取音频文件
【发布时间】:2019-11-06 08:13:11
【问题描述】:

出于无奈,在此发布。任何帮助表示赞赏。谢谢。

背景故事:

我正在帮助我的朋友使用他从中国获得的设备。该设备应该使用 UDP 向我的服务器发送音频文件。

【问题讨论】:

  • 0000cf6c 看起来像一个十六进制值,它等于 53100 (53.1 KB)。要获得全部数据,您需要所有数据包(我认为上面的数据只是一个数据包)。您还需要捕获整个数据包(-s0 使用 tcpdump - 不确定wireshark)。
  • 感谢您的回复!出于某种原因,这是它发送给我的唯一数据包。我会继续玩它,看看我能得到什么
  • 设备可能会在发送更多数据之前等待确认已收到数据包。也许检查您必须查看的文档,看看是否还有其他内容
  • @SamMason 我真的只是在之前的评论之后尝试过这个!在每个数据包发送到服务器后,我发送了一个确认信息,根据wireshark,我总共收到了大约 50 个数据包,每个 911 字节

标签: python networking udp hex wireshark


【解决方案1】:

假设您希望一些 Python 代码自动执行此操作,以下是我验证和解码数据包的方法:

import struct

def decode_packet(packet):
    framehead, version, command, datalen = struct.unpack_from('!HBBH', packet)

    valid = (
        framehead == 0x55aa and
        version == 0x00 and
        command == 0x1e and
        len(packet) <= datalen + 11
    )
    if not valid:
        # ignore other protocols using this address/port
        print(
            '  header invalid',
            f'{framehead:04x} {version:02x} {command:02x} {datalen:04x}'
        )
        return

    if len(packet) < datalen + 11:
        print('  warning: packet was truncated')

    offset, = struct.unpack_from('!I', packet, 6)
    if datalen == 4:
        print(f'  end of data: file size={offset}')
        return

    data = packet[10:10+datalen]
    print(f'  got data: offset={offset} len={len(data)} hex(data)={data.hex()}')

    if len(packet) == datalen + 11:
        print(f'  hex(checksum)={packet[datalen + 10:].hex()}')

它显然会打印出很多东西,但这有助于查看设备是否真的遵循记录的协议。似乎没有,因为data length 上的+4 似乎没有被应用。您可以使用以下方法进行测试:

decode_packet(bytes.fromhex('55aa001e038400000000a9b6ad98d2923...'))

假设您可以使其正常运行,您可以将其放入一些代码中,以便在正确的端口上侦听数据包:

import socket

def server(portnum):
    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
        sock.bind(('', portnum))

        while True:
            packet, addr = sock.recvfrom(10240)
            print(f'received {len(packet)} bytes from {addr[0]}')
            decode_packet(packet)

再次,没有做太多。您希望将数据写入文件而不是将其打印出来,但您可以拉出偏移量,并在数据传输完成时收到信号

【讨论】:

  • 感谢您的回复!我将查看代码。我只是很快想问你为什么使用 sock.recvfrom(10240)?我目前正在使用 sock.recvfrom(4096) 遵循我在网上看到的示例
  • 我认为实际值并不重要,只要它比您期望收到的任何数据包都大。巨型数据包可以是 9000 字节,而 10KiB 是之后最好的整数......也就是说,超过 1500 的任何东西都可能很好(以太网的限制)
  • 请注意,您不想传递任何太疯狂的东西,例如128 兆字节!将分配该大小的缓冲区(然后在收到较少的数据时调整大小),但这里可能没问题
  • 所以如果我想将这些接收到的字节写入文件,我需要写入二进制文件吗?如何保存传入的字节并转换为音频文件?
  • 就写作而言,它只是标准的open(name, 'wb')、seek(offset) 和write(data),没有什么特别的需要。你需要弄清楚数据的格式才能回放它,希望这已经记录在某个地方,逆向工程可能会很尴尬!
猜你喜欢
  • 2012-10-18
  • 1970-01-01
  • 2012-04-28
  • 1970-01-01
  • 2017-05-29
  • 2023-02-26
  • 1970-01-01
  • 2020-09-13
  • 1970-01-01
相关资源
最近更新 更多