如何将套接字数据转换为 json 对象或带有 Python 的字典 3

How to convert socket data to json object or to Dictionary with Python 3

所以我正在尝试将数据从套接字转换为 json 对象。 下面是我的 python 从套接字服务器获取数据的代码。

import socket

HOST = "myHOST"
PORT = myPORT
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((myHOST, myPORT))
    s.sendall(b" ")
    buffer_size = 4096
    print("Received: ")
    while True:
        data = s.recv(buffer_size)
        print(repr(data))
s.close()

我正在获取此数据作为输出:

Received: 
b'2018-08-06T17:35:45.0612|power|ON|mode|MANUAL|execution|READY|Xact|215.13|Yact|331.34|Zact|22.16|Xcom|0.00|Ycom|0.00|Zcom|0.00|path_feedrate|0.00|line|0|Block|0|program|Plate 1_imported_dxf.ORD\n'
b'2018-08-06T17:35:45.0612|comms|NORMAL||||\n2018-08-06T17:35:45.0612|Sspeed|0.00\n'

现在我想将它转换为格式化的 json 对象,以便我以后可以在我的 html 和 javascript 上使用它。我试图通过以下方式在我的 while 循环中创建 json 对象:

import socket
import json

HOST = "myHOST"
PORT = myPORT
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((myHOST, myPORT))
    s.sendall(b" ")
    buffer_size = 4096
    print("Received: ")
    while True:
        data = s.recv(buffer_size)
        print(repr(data))

        json_obj = json.loads(data)
        print(type(json_obj))
        print(json_obj.get("power").get("mode"))
s.close()

但我无法正常工作。我也尝试使用 json.dumps 但没有成功。 请大家帮忙!我也尝试制作字典但没有成功,出现错误:ValueError:要解压的值太多(预期为 2)。 下面是我的字典尝试的片段:

while True:
    data = s.recv(buffer_size).decode("utf-8")
    print(data)
    d = {}
    for pair in data.replace(' ', '').split(', '):
        k, v = pair.split('|')
        d[k] = int(v)
    print(d)

我希望答案具有键值对。

这里有点猜测,因为您没有准确定义您希望看到的输出内容,但看起来很清楚,可以尝试一下。首先,第一列似乎有一个隐含键(我将其称为 "timestamp")。然后,似乎键和值交替出现。

假设是这种情况,您将确保在输入中只提供完整的行(* 见下文),以下应该有效。为了简洁起见,您可以在这里组合很多东西。为了教育,我把这一切都打破了:

import json

input_data = [
    b'2018-08-06T17:35:45.0612|power|ON|mode|MANUAL|execution|READY|Xact|215.13|Yact|331.34|Zact|22.16|Xcom|0.00|Ycom|0.00|Zcom|0.00|path_feedrate|0.00|line|0|Block|0|program|Plate 1_imported_dxf.ORD\n',
    b'2018-08-06T17:35:45.0612|comms|NORMAL||||\n2018-08-06T17:35:45.0612|Sspeed|0.00\n'
]

for x in input_data:

    # Sometimes the input data has multiple lines, so split into lines
    for line in x.decode().splitlines():

        # Drop white space (if necessary; splitlines() already drops newlines)
        data = line.strip()
        print("LINE:", data)

        # Split by vertical bars to produce "atoms"
        atoms = data.split('|')
        print("ATOMS:", atoms)

        # Supply implicit timestamp key plus odd-numbered atoms
        keys = ['timestamp'] + list(atoms[1::2])

        # Values from even-numbered atoms
        values = list(atoms[::2])    

        print("KEYS:", keys)
        print("VALUES:", values)

        # What if they aren't one for one?
        assert len(keys) == len(values)

        # Drop key and value if key is null (reasonable that value might be null?)
        zipped = [(k, v) for k, v in zip(keys, values) if k]
        print("ZIPPED:", zipped)

        d = dict(zipped)
        print("DICT:", d)

        print("JSON:", json.dumps(d))
        print()


重要

recv 不保证向您传送整行 即使 对方将它们作为完整行发送。当这很重要时(如此处),您需要在 recv 和您的应用程序逻辑之间放置一个 "buffering" 层,它会继续接收字节直到找到行尾。

import socket

HOST = "myHOST"
PORT = myPORT
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((myHOST, myPORT))
    buffer_size = 2048
    print("Received: ")
    while True:
        devData = s.recv(buffer_size).decode("utf-8").split("|")
        timeStamp = devData.pop(0)
        devDict = dict(zip(*([iter(devData)]*2)))
        print(devDict)
s.close()

这是我得到的结果:

Received: 
{'power': 'ON', 'mode': 'MANUAL', 'execution': 'READY', 'Xact': '1113.21', 'Yact': '162.60', 'Zact': '0.00', 'Xcom': '0.00', 'Ycom': '0.00', 'Zcom': '0.00', 'path_feedrate': '0.00', 'line': '0', 'Block': '0', 'program': '37255 S1 D - .75 JET_imported_dwg.ORD\n'}
{'comms': 'NORMAL', '': '\n2018-08-07T20:40:05.0432', 'Sspeed': '0.00\n'}
{'program': '37255 S1 D - .75 JET_imported_CNC.ORD\n'}
{'power': 'ON', 'mode': 'MANUAL', 'execution': 'READY', 'Xact': '1113.21', 'Yact': '162.60', 'Zact': '0.00', 'Xcom': '0.00', 'Ycom': '0.00', 'Zcom': '0.00', 'path_feedrate': '0.00', 'line': '0', 'Block': '0', 'program': '37255 S1 D - .75 JET_imported_CNC.ORD\n'}
{'comms': 'NORMAL', '': '\n2018-08-07T20:43:57.0375', 'Sspeed': '0.00\n'}