2011-05-16 81 views
3

我正在通过网络从C服务器接收到我的Python客户端的结构。协议是UDP。我无法控制服务器,它是协议/数据格式。它由这个结构(是的,在IPv4 +端口)的:反序列化C数据

struct ip_s { 
    uint8_t i1; 
    uint8_t i2; 
    uint8_t i3; 
    uint8_t i4; 
    uint16_t port; // big endian 
}; 

除了将其转化为大端数据被发送“原样”,浇铸到一个(char*)的端口。

如何将此结构接收为可由Python处理的格式?


其它信息:

  • Python 2.7版或3.x的
  • 跨平台
  • 最好的解决方案只使用内置模块

回答

3

查找到struct.unpack

它w生病可能是这个样子:

# socket setup 

(buffer, sockaddress) = mysocket.recvfrom(6) 
if len(buffer)== 6: 
    i1,i2,i3,i4, port = struct.unpack('!BBBBH', buffer) 
+0

已经发现它是正确的,但我会留下问题以供进一步参考。 – orlp 2011-05-16 22:29:47

+2

噢,''BBBBH''应该是''!BBBBH“'的大端口。 – orlp 2011-05-16 22:39:34

+0

我自由地编辑了你的答案。 – orlp 2011-05-17 00:24:51

0

我收到一个结构通过网络

停在那儿。不要这样做。该技术引入了以下依赖关系:

  1. 字序:big-endian或little-endian。
  2. 填充。
  3. 包装。

(2)和(3)又取决于:

  1. 编译器。
  2. 编译器版本。
  3. 周围的#pragmas。
  4. 编译C程序时有效的编译选项。

这相当多的依赖关系。不要这样做。定义一个应用程序协议并使用它。或者使用像XDR这样的解决问题的东西。

+0

也许你不应该“停在那里”,至少不要阅读:“我无法控制服务器,它的协议/数据格式。” – orlp 2011-05-17 00:18:34

+0

@nightcracker因此,无论服务器是无能的设计,有人需要得到控制,或者更可能的,这只是一种描述应用协议的方式,它实际上是一个有线协议,由四个八位字节组成,后面是网络字节顺序中的一个两字节整数。 – EJP 2011-05-17 01:15:20

+0

你的描述和我的没有区别,因为实现使用'uint8'和类似的东西,没有留下空间来实现。我真的坚持服务器的设计,它是基于[此代码]的CoD4主服务器(http://svn.icculus.org/twilight/trunk/dpmaster/src/messages.c?revision=10433&view =标记)。 – orlp 2011-05-17 01:50:14