0

事实证明,我对 struct.pack 的使用在这里很好。由于复制/粘贴错误,我只是使用了错误的变量。请记住在您自己的代码中注意此类错误!

原问题如下,如果你想看的话。


我需要在 UDP 数据包上发送两条不同的信息作为有效负载。这些数据包携带有关对象目标的信息(即目标 IP 地址和目标端口号)。我已经用其他方法确认我正在打包正确的信息。我的问题在于一旦我发送信息就对其进行解码。这是我编码的信息,以及用于编码它们的方法:

IP 地址:xxx.xxx.xxx.xxx(xxx 是 0 到 255 之间的任意数字)

  1. IP 地址分为四个数字的列表。

  2. 四个数字的列表使用 struct.struct('4B') 打包,其中每个字节都是列表数字之一。

  3. 在接收端,使用相同的 struct.struct("4B") 接收和解包

  4. 一个表示 IP 地址的字符串是使用四个解压缩的值和正确放置的句点重建的。

对于端口号:

端口号:单个整数,一般为千位(即8000,我的测试值)

  1. 使用 struct.struct("H") 存储(这是一个包含数字的 2 字节对象)

  2. 在接收端使用相同的 struct.struct("H") 解包

我认为我正在做的事情一直到编码部分,因为我在编码和发送之前检查了这些值,它们是正确的。当我在另一端得到它们并对其进行解码时,这些值都是错误的,我不知道为什么。这是一个例子:

输入IP和端口:

IP:164.107.112.70 端口:8000

输出 IP 和端口:

IP:64.31.0.0 端口:10

我在这里可能做错了什么来遇到这些问题?

编辑:这是要求的一些代码。

#pack IP for transport

#split into four 1-byte values
SplitIP = IP.split('.')

#create a 4-byte struct to pack IP, and pack it in remoteIP
GB = struct.Struct("4B")

remoteIP = GB.pack(int(SplitIP[0]),int(SplitIP[1]),int(SplitIP[2]),int(SplitIP[3]))
#remoteIP is now a 4-byte string of packed IP values


#pack Port for transport

#create a 2-byte struct to pack port, and pack it in remotePort
GBC = struct.Struct("H")

remoteIP = GBC.pack(int(PORT))  #needs another byte
#remoteIP is now a 2-byte string of packed IP values


#Join the two parts together

remoteIP += str(remotePort)

在此之后,一些额外的元素被打包(一个 1 字节标志、一个 1 字节 ABP 的 0/1 值(尚未实现)和一个有效负载(在这种情况下,文件大小为 4 字节值) . 然后它们通过 socket send 命令发送到同一台机器上客户端提供的端口号的另一个进程(在我的测试中,使用 4000)。

#get size of file from os command
filesize = bytearray(4)
#save as 4-byte string
filesize = str(os.stat(localfile).st_size)

#add flag
flag1 = bytearray(1)
flag1 = str(1)

#add zerone
if(zerone == 0):
    zerone = 1
else:
    zerone = 0

zeon = str(zerone)

#package the filesize string

filesizestr = ''.join(remoteIP)
filesizestr = filesizestr + flag1 + zeon    #now contains 4,2,1,1 byte arrays

filesizestr += filesize                     #now we have complete packet

s.sendto(filesizestr, ('127.0.0.1', int(TPORT)))

编辑:复制/粘贴出现错误,确实是一个共同的敌人,在编码的每一个环节都必须考虑。

当前出现的问题是,虽然 IP 地址现在可以正常发送,但端口是错误的。

发送端口为8000

接收到的端口是@\x1f

我不完全确定如何解释该输出,如果有人可以帮助我弄清楚发生了什么,那么我将非常感激。我的假设是我要么犯了编码错误,要么我抓取了错误的数据。至于数据,发送的字符串的排列应该是:

IP 4 字节,端口 2 字节等。

所以我用以下两行来获取该信息:

packedIP = data[0:4]    #grab 4-byte IP data
packedPort = data[4:6]  #grab 2-byte port data

这是正确的,是吗?我仍然对 Python 字符串访问器的工作方式有些困惑。我得到了正确的IP,所以我认为我还可以。

编辑:以前不要介意这个问题,我使用错误的变量犯了更愚蠢的错误。

4

1 回答 1

1

所以理论上线上的字节应该是:

A4 6B 70 46 1F 40

但你解码的似乎是

40 1F 00 00 00 0A

第一组的最后两个字节是第二组的前两个字节(反转),这看起来很可疑。我们可以看看你正在使用的代码吗?这可能有助于确定确切的问题。

另外,机器是小端还是大端?当我做字节压缩结构时,我通常使用网络排序(大端),这意味着你应该在你的结构字符串前面加上一个感叹号(参见http://docs.python.org/2/library/struct.html)。

编辑:你的问题是这一行:

remoteIP = GBC.pack(int(PORT))  #needs another byte

它应该是

remotePort = GBC.pack(int(PORT))  #needs another byte
于 2013-11-12T20:34:57.287 回答