2016-08-16 112 views
0

我有一個udp套接字接收不同長度的數據報。 第一個數據報指定了要接收的數據類型,例如64-表示bool false,65-表示bool真,66-表示sint,67-表示int等等。由於大多數數據類型都有已知的長度,但是當涉及到字符串和wstring時,第一個字節表示85-means字符串,接下來的2個字節表示字符串長度後跟實際字符串。對於wstring 85,接下來的2個字節表示wstring的長度,後面跟着實際的wstring。字符串到蟒蛇wstring

要分析上面的那種關wstring的格式b'U\x00\x07\x00C\x00o\x00u\x00p\x00o\x00n\x001'我用下面的代碼

data = str(rawdata[3:]).split("\\x00") 
data = "".join(data[1:]) 
data = "".join(data[:-1]) 

這是正確的或任何其他簡單的方法?

當我收到數據報時,我還需要發送數據報。但我不知道如何創建數據報,因爲socket.sendto需要bytes。如果我嘗試將字符串轉換爲utf-16格式,它將轉換爲wstring。如果是的話我將如何添加其餘的信息爲bytes

從上面的數據報信息U -85這是wstring的,\x00\x07 - 7長度wstring的數據,\x00C\x00o\x00u\x00p\x00o\x00n\x001 - 是實際的字符串Coupon1

回答

1

一完整的答案取決於你打算如何處理結果數據。將字符串拆分爲'\x00'(假設這就是您的意思?不知道我爲什麼有兩個反斜槓)沒有意義。首先使用wstring類型的原因是能夠表示不是普通的8位(真正的7位)ascii的字符。如果你有任何不是標準羅馬字符的字符,它們可能除零字節之外還有其他字符,這樣你的split結果將毫無意義。

警告:由於您提到sendto需要字節,我假設您使用的是python3。 python2下的細節會略有不同。

無論如何,如果我明白你的意思是什麼,那麼「utf-16-be」編解碼器可能就是你要找的。 (「utf-16」編解碼器在編碼字符串的開始處放置一個「字節順序標記」,您可能不想要;「utf-16-be」只是將大端16位字符放入字節。字符串)解碼可以進行這樣的事:

rawdata = b'U\x00\x07\x00C\x00o\x00u\x00p\x00o\x00n\x001' 

dtype = rawdata[0] 
if dtype == 85:  # wstring 
    dlen = ord(rawdata[1:3].decode('utf-16-be')) 
    data = rawdata[3: (dlen * 2) + 3] 
    dstring = data.decode('utf-16-be') 

這將使dstring爲Python unicode字符串。在python3中,所有字符串都是unicode。所以你完成了。

編碼這是可以做到這樣的事:

tosend = 'Coupon1' 
snd_data = bytearray([85]) # wstring indicator 
snd_data += bytearray([(len(tosend) >> 8), (len(tosend) & 0xff)]) 
snd_data += tosend.encode('utf-16-be')