簡體   English   中英

結構解包和打包更改數據

[英]Structs unpack and pack changes data

我目前正在嘗試將一些數據打包到腳本“p1.py”中,然后通過 pipe 將其解壓縮到另一個腳本“p2.py”中。 pipe 通信完美,我能夠在兩個腳本之間發送數據。 但是,在解包后,數據會發生變化。 在這種情況下,我在腳本“p2.py”中執行此操作,以便打包數據並將其發送到“p1.py”腳本:

COMMAND_STRUCT = struct.Struct(">fB3s")

packed_data = struct.pack(">fB3s",29.1,1,b'3s')
print(packed_data)
#lateral_airspeed_input, drop_package_commanded_byte, _ = COMMAND_STRUCT.unpack(packed_data)
#print(lateral_airspeed_input)

正如我們所看到的,我打印了“packed_data”,它被打包成一個浮點數、一個字節,然后是 3 個字節。 現在,如果我只是將打包的數據打印到我的終端,我會得到這個 output:

b'A\xe8\xcc\xcd\x013s\x00'

這只是 29.1,1 和 3 字節的壓縮形式。 如果我取消最后兩行的注釋,lateral_airspeed_input 將為 29.1 - 表示解包和打包工作,因為我可以打包數據並解包並在解包后獲得相同的數據。

現在,這就是有趣的地方。 當我引入另一個腳本時,我會執行與此處所示相同的操作:

        cmd = pilot.stdout.read(COMMAND_STRUCT.size)
        #print(cmd)
        if len(cmd) != COMMAND_STRUCT.size:
            result = CRASHED  # The pilot process must have exited
            break
        lateral_airspeed_input, drop_package_commanded_byte, _ = COMMAND_STRUCT.unpack(cmd)
        print(lateral_airspeed_input)
        lateral_airspeed = max(-30.0, min(30.0, lateral_airspeed_input))
        drop_package_commanded = bool(drop_package_commanded_byte)

在這里,打包數據被讀取到變量 cmd,然后 cmd 被解包到lateral_airspeed_input、drop_package_commanded_byte 和_變量。 理想情況下,如果我們打印lateral_airspeed_input,我們應該得到 29.1。 但是,我在打印時得到 7.713289749049545e+20。 但是,如果我直接打印 cmd ,我會得到:

b"b'A\xe8\" b'xcc\xcd\' b'x013s\x0' b"0'\r\n"

這看起來類似於之前的打包數據——當我只使用一個 py 腳本時。 出於某種原因,打包的數據會包含所有這些額外的 b" 和 0\r\n 東西。我認為這會擾亂通信,我想知道是否有辦法避免這種情況。我寧願避免這種情況而不是從行中剝離代碼。

謝謝您的幫助。 我正在使用子進程管道來管理兩個腳本之間的通信,並通過我的 windows cmd 簡單地運行子進程。

我試圖根據您提供的內容整理一個樣本。

這是腳本 p1.py:

import struct

COMMAND_STRUCT = struct.Struct(">fB3s")

packed_data = struct.pack(">fB3s",29.1,1,b'3s')
print(packed_data)

這是腳本 p2.py:

import struct
import sys

COMMAND_STRUCT = struct.Struct(">fB3s")
cmd = sys.stdin.read(COMMAND_STRUCT.size)
#print(cmd)
if len(cmd) != COMMAND_STRUCT.size:
    sys.exit(1)
lateral_airspeed_input, drop_package_commanded_byte, _ = COMMAND_STRUCT.unpack(cmd)
print(lateral_airspeed_input)
lateral_airspeed = max(-30.0, min(30.0, lateral_airspeed_input))
drop_package_commanded = bool(drop_package_commanded_byte)

如果我這樣運行它,我相信我會得到預期的結果:

%> python2 p1.py | python2 p2.py

29.1000003815

這似乎是預期的結果。 你能詳細說明你的場景與這個小例子有什么不同嗎?

更新

根據您之前的評論,我制作了一個新腳本p3.py ,如下所示:

import subprocess
import struct
import sys

COMMAND_STRUCT = struct.Struct(">fB3s")
pilot = subprocess.Popen(['python2','./p1.py'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
cmd = pilot.stdout.read(COMMAND_STRUCT.size)
#cmd = sys.stdin.read(COMMAND_STRUCT.size)
#print(cmd)
if len(cmd) != COMMAND_STRUCT.size:
    sys.exit(1)
lateral_airspeed_input, drop_package_commanded_byte, _ = COMMAND_STRUCT.unpack(cmd)
print(lateral_airspeed_input)
lateral_airspeed = max(-30.0, min(30.0, lateral_airspeed_input))
drop_package_commanded = bool(drop_package_commanded_byte)

當我運行它時,我似乎仍然得到了想要的結果:

%> python2 p3.py

29.1000003815

所以我認為我在這里仍然必須遺漏一些東西。

正如評論中已經指出的那樣,您的發件人腳本正在打印字符串的表示形式。 即代替字節序列41 e8 cc cd... ( A.. ) 你得到62 21 41... ( b"A\... )。

此外, printstdout默認在文本模式下工作。 即你會遇到原始二進制數據的麻煩。 文檔說您可以使用stdio的底層緩沖區來發送二進制數據:

import sys
sys.stdout.buffer.write(packed_data)
sys.stdout.flush()

您必須使用flush來實際發送數據。 否則只會在遇到換行符 ( 0x0d ) 時寫入。

此外,如果您這樣做,請確保標准輸出實際上並未打印到屏幕上。 否則你的終端很快就會被搞砸。

反之亦然,您應該在接收器腳本中使用二進制讀取: cmd = sys.stdin.buffer.read()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM