3

我在 python 和 Delphi 代码(仅限文本)之间设置了基本的套接字通信。现在我想发送/接收双方的数据记录。我有一个记录“C 兼容”,并希望来回传递记录,使其在 python 中具有可用格式。

我在 python 中使用 conn.send("text") 来发送文本,但是如何使用 python 发送/接收缓冲区并访问在 python 中发送的记录项?

记录

  TPacketData = record
    pID      : Integer;
    dataType : Integer;
    size     : Integer;
    value    : Double;
  end;
4

2 回答 2

0

我知道这个答案对游戏来说有点晚了,但至少可能对其他在搜索结果中找到这个问题的人有用。因为您说Delphi代码发送和接收“C兼容数据”,所以为了回答有关Python处理的问题,另一端是否是Delphi(或任何其他语言)似乎无关紧要......

python structsocket模块具有您描述的基本用法的所有功能。要发送示例记录,您将执行以下操作。为简单起见,我假设有符号整数和双精度数,并以“网络顺序”(bigendian)打包数据。这很容易成为单行,但为了冗长和可重用性,我将其拆分:

import struct
t_packet_struc = '>iiid'
t_packet_data = struct.pack(t_packet_struc, pid, data_type, size, value)
mysocket.sendall(t_packet_data)

当然,如果对格式字符串、数据准备等进行调整,则不需要进行上述“假设”。有关可能的格式字符串的描述,请参见struct inline 帮助 - 它甚至可以处理诸如 Pascal 字符串之类的内容...顺便说一句,socket模块允许打包和解包一些结构不支持的特定于网络的东西,比如 IP 地址字符串(到它们的 bigendian int-blob 形式),并允许显式函数转换数据 bigendian - 到本地,反之亦然。为了完整起见,这里是如何在 Python 端解压上面打包的数据:

t_packet_size = struct.calcsize(t_packet_struc)
t_packet_data = mysocket.recv(t_packet_size)
(pid, data_type, size, value) = struct.unpack(t_packet_struc,
                                              t_packet_data)

我知道这适用于 Python 2.x 版,并且怀疑它也应该在不改变 Python 3.x 版的情况下工作。当心一个大问题(因为很容易不去想,事后很难排除):除了不同的字节顺序,你还可以区分使用“标准尺寸和对齐方式”(便携式)或使用“原生大小和对齐方式”(快得多)取决于您如何为格式字符串添加前缀 - 或不添加前缀。这些通常会产生与您预期的完全不同的结果,而不会为您提供有关原因的线索……(有龙)。

于 2013-12-01T19:27:50.400 回答
0

我对python不太了解,但我在Delphi、C++、C#和Java之间做了很多,即使是COBOL。

无论如何,要先将记录从 Delphi 发送到 C,您需要在两端打包记录,

(德普利)

MyRecord = pack record

在 C++ 中

#pragma pack(1) 

我不知道在python中,但我想一定有一个类似的。确保两边的 sizeof(MyRecord) 长度相同。

此外,在发送记录之前,您应该注意字节顺序(您知道,Little-Endian 与 Big-Endian),在 python 中使用 Socket.htonl() 和 Socket.ntohl() 以及在 Deplhi 中的等价物WinSock 单元。此外,Delphi 中的“double”不能与 python 中的相同,在 Delphi 中也是 8 字节,请检查这一点,并将其更改为 Single(4 字节)或 Extended(10 字节),无论哪个匹配。如果所有这些都匹配,那么您可以一次性发送/接收二进制记录,否则,恐怕您必须一一发送各个字段。

于 2013-06-05T10:28:06.687 回答