我在python和Delphi代码之间建立了基本的套接字通信(仅限文本)。现在我想发送/接收双方的数据记录。我有一个记录“C兼容”,并希望在python中以可用的格式来回传递记录。
我在python中使用conn.send(“text”)来发送文本但是如何使用python发送/接收缓冲区并访问在python中发送的记录项?
记录
TPacketData = record
pID : Integer;
dataType : Integer;
size : Integer;
value : Double;
end;
答案 0 :(得分:0)
我对python知之甚少,但即使使用COBOL,我在Delphi,C ++,C#和Java之间也做了很多。
无论如何,要从Delphi发送记录到C首先需要打包两端的记录,
在Deplhi
MyRecord = pack record
在C ++中
#pragma pack(1)
我不知道在python中,但我猜必须有一个类似的。确保sizeof(MyRecord)两边的长度相同。
此外,在发送记录之前,你应该注意字节顺序(你知道,Little-Endian vs Big-Endian),使用Socket python中的.htonl()和Socket.ntohl()以及在WinSock单元中的Deplhi中的等价物。 Delphi中的“double”也不能与python中的相同,Delphi中的8字节检查也是如此,并将其更改为Single(4字节)或Extended(10字节),无论哪个匹配。 如果所有匹配,那么你可以在一次关闭中发送/接收二进制记录,否则,我担心,你必须逐个发送各个字段。
答案 1 :(得分:0)
我知道这个答案在游戏中有点晚了,但至少对其他人在搜索结果中发现这个问题很有用。因为你说Delphi代码发送和接收“C兼容数据”,似乎为了解决Python的处理问题,它是否是另一端的Delphi(或任何其他语言)无关......
python struct 和 socket 模块具有您描述的基本用法的所有功能。要发送示例记录,您可以执行以下操作。为了简单和理智,我假设有符号整数和双精度,并将数据打包成“网络顺序”(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 内联帮助。 - 甚至可以处理诸如Pascal字符串之类的东西......顺便说一句, socket 模块允许打包和解包一些 struct 所不具备的网络特定的东西,就像IP地址字符串(与它们的bigendian int-blob形式一样),并允许显式函数将数据bigendian转换为native,反之亦然。为了完整起见,以下是如何在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中也可以不用更改。谨防一个大问题(因为很容易不去思考,事后难以排除故障):除了不同的字节顺序,你还可以区分使用“标准大小和对齐”(可移植)或使用“本机”包装东西大小和对齐“(快得多)取决于你的格式字符串前缀 - 或不添加前缀。这些通常会产生与你想要的截然不同的结果,而不会给你一个关于为什么......(有龙)的线索。