如何将从套接字接收的多个值存储在python的结构中

Posted

技术标签:

【中文标题】如何将从套接字接收的多个值存储在python的结构中【英文标题】:How to store multiple values received from socket in a structure in python 【发布时间】:2021-10-14 03:27:02 【问题描述】:

我想从套接字接收多条消息,我想将它存储在类似c++ 的结构中。将用于进一步验证。

这是我的代码:

def Receive(event,self):
   
    message = socket.recv(0.1)

message 是一个具有message.arbitrationmessage.timestamp 等属性的对象 我想在结构中存储message.timestamp 和即将到来的recv socket API 的其他属性,如下所示:

struct canmessage[0].timestamp[0]=message.timestamp

例如,如果我收到 100 条消息, 我想将这 100 条消息存储在 python 中的结构中。

如何在python中实现这个逻辑。

我尝试了listdict,但没有成功。

谁能帮忙解决这个问题。

【问题讨论】:

如果message 已经是一个对象,你不能将它们存储在listmessages = [] messages.append(message) 中吗?然后使用messages[0].timestamp 访问它们?虽然我怀疑socket 本身会给你一个message 对象而不涉及一些抽象。 如何接收十分之一字节? ?????? 感谢 cmets,目前我正在使用这个 github.com/hardbyte/python-can/blob/develop/can/message.py 类消息来接收套接字可以消息。我想使用这个类并按照我的要求存储在结构中。这还有可能吗? 【参考方案1】:

struct 模块可以将 Python 数据与适合通过套接字传输的字节流相互转换。当你有一个固定的格式结构被传输或接收时,我可以使用。

在以下示例中,发送或接收的数据包遵循网络排序(big-endian)双精度格式,后跟一个 10 字节 UTF-8 编码字符串,必要时用空字节填充。存储结构使用datetime 对象和Python Unicode str

from datetime import datetime
import struct

class Message:

    def __init__(self, ts, arb):
        self.timestamp = ts
        self.arbitration = arb

    def __repr__(self):
        return f'Message(timestamp=self.timestamp!r, arbitration=self.arbitration!r)'

    def serialize(self):
        return struct.pack('!d10s', self.timestamp.timestamp(), self.arbitration.encode())

    @classmethod
    def deserialize(cls, raw):
        ts, arb = struct.unpack('!d10s', raw)
        return Message(datetime.fromtimestamp(ts), arb.decode().rstrip('\x00'))

x = Message(datetime.now(), 'Yes?')
data = x.serialize()
print(data)
msg = Message.deserialize(data)
print(msg)
print(msg.timestamp.ctime(), msg.arbitration)

输出:

b'A\xd8D\xbb\x15R\xdb4Yes?\x00\x00\x00\x00\x00\x00'
Message(timestamp=datetime.datetime(2021, 8, 10, 14, 15, 1, 294629), arbitration='Yes?')
Tue Aug 10 14:15:01 2021 Yes?

如果您没有固定格式,JSON 是一种流行的、可读的数据传输格式:

from datetime import datetime
import json

class Message:

    def __init__(self, ts, arb):
        self.timestamp = ts
        self.arbitration = arb

    def __repr__(self):
        return f'Message(timestamp=self.timestamp!r, arbitration=self.arbitration!r)'

    def json(self):
        data = 'timestamp': self.timestamp.timestamp(), 'arbitration': self.arbitration
        return json.dumps(data, ensure_ascii=False).encode()

    @classmethod
    def from_json(cls, raw):
        data = json.loads(raw)
        return Message(datetime.fromtimestamp(data['timestamp']), data['arbitration'])

x = Message(datetime.now(), 'Yes?')
data = x.json()
print(data)
msg = Message.from_json(data)
print(msg)
print(msg.timestamp.ctime(), msg.arbitration)

输出:

b'"timestamp": 1628630908.680338, "arbitration": "Yes?"'
Message(timestamp=datetime.datetime(2021, 8, 10, 14, 28, 28, 680338), arbitration='Yes?')
Tue Aug 10 14:28:28 2021 Yes?

您还可以使用pickle 模块,该模块用于序列化/反序列化任意 Python 对象,但请注意,您必须相信接收到的数据,因为取消任意对象可能是不安全的。

from dataclasses import dataclass
import pickle

@dataclass
class Message:
    timestamp: datetime = datetime.now()
    arbitration: str = ''

data = pickle.dumps(Message(datetime.now(), 'Yes?'))
print(data)
msg = pickle.loads(data)
print(msg)

输出:

b'\x80\x04\x95j\x00\x00\x00\x00\x00\x00\x00\x8c\x08__main__\x94\x8c\x07Message\x94\x93\x94)\x81\x94\x94(\x8c\ttimestamp\x94\x8c\x08datetime\x94\x8c\x08datetime\x94\x93\x94C\n\x07\xe5\x08\n\x0e\x12#\x0e^\xa4\x94\x85\x94R\x94\x8c\x0barbitration\x94\x8c\x04Yes?\x94ub.'
Message(timestamp=datetime.datetime(2021, 8, 10, 14, 18, 35, 941732), arbitration='Yes?')

发送和接收字节数据包留给 OP 练习 ?。 struct 格式是固定大小的(从套接字读取 18 个字节)。 json 可以使用 socket.makefilereadline() 如果在单个换行符终止的行中传输,则一次读取一行。 pickle 可以直接从封装在 makefile 中的套接字读取腌制对象。

【讨论】:

感谢 cmets,目前我正在使用这个 github.com/hardbyte/python-can/blob/develop/can/message.py 类消息来接收套接字可以消息。我想使用这个类并按照我的要求存储在结构中。这还有可能吗?【参考方案2】:

也许这个帖子here 有帮助。 建议使用 dataclass 模块来获得类似结构的行为:

from dataclasses import dataclass
@dataclass
class Message:
  timestamp: list = []
  arbitration: list = []

message = socket.recv(0.1)
can_messages = [Message()]
can_messages[0].timestamp.append(message.timestamp)

我不确定这是否正是您正在寻找的,但我希望它可以帮助您。

【讨论】:

感谢 cmets,目前我正在使用这个 github.com/hardbyte/python-can/blob/develop/can/message.py 类消息用于接收套接字可以消息。我想使用这个类并按照我的要求存储在结构中。这还有可能吗?

以上是关于如何将从套接字接收的多个值存储在python的结构中的主要内容,如果未能解决你的问题,请参考以下文章

Swift:如何将从委托接收到的值传递给函数的完成块?

使用 python 套接字发送/接收数据

如何在 Python 中使用套接字创建通道

如何将从 json 接收到的 ko.observable 字符串解析为整数(数字)值

如何将从接口取到的json数据存入mysql数据库

在一个变量 sql 中接收多个值