這篇文章帶給大家的內容是關於Python解析Socket資料流異常bytes的問題(詳細),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。
python在透過socket發送資料時,英文字符轉義後為原來本身的字符,佔一個字節(如:s轉移後為s),而中文字符在轉義後需要二個字節來識別一個中文字元(如:鐘轉義後為\x92\x9f)。在發送端是不存在問題的,而發生問題的主要是在socket客戶端。因為客戶端在接受資料流時,每次接受都是有位元組限制,就會出現一個中文字元分兩次接受,從而導致每次接受的流在轉義成字符時報錯UnicodeDecodeError。
目前有資料流:
bmsg = b'\xe5\x88\x86\n\xe9\x92\x9f' # 分\n钟
#正常接受並轉義為:
smsg = str(bmsg, 'utf-8') #方式一 或 smsg = bmsg.decode() # 方式二 第一参数默认utf8,第二参数默认strict,还有 ignore (忽略)、 replace (替代=?)
如果現在接受到的資料流為
bmsg = b'\xe5\x88\x86\n\xe9\x92' # \x9f 作为下次接受
如何避免程式的異常退出,有兩種處理方式:
1)資料遺失處理
此時,如果再用正常接受方式轉義bytes流,就會出現UnicodeDecodeError 異常,為使不報異常,我們在轉義時,透過方式二,指定第二個參數為ignore,如下:
smsg = bmsg.decode('utf-8', 'ignore') # 输出: 分\n ,如果为 replace 则 \n 后为 ?
2)資料流拆分,再處理
一般socket服務端在傳送資料時,每個資料流是完整的,並會以特定的字元(如:\n)結束一併發送。根據這種現狀,我們在每次接受資料時,根據這個特定字元拆分(split)為一個保存單一資料流的清單。列表的第一個流可能為不完整,把它和上次接受的流合併為一個完整的資料流並轉義;中間為可以正常轉義的資料流;最後一個流也為不完整,保存下來,用來拼接下次接受的流,並重複上述操作,這樣保障了程式不會異常退出,也保障資料的完整性。大致代碼如下:
資料接受:
第一次接受 msg1 = b'\xe5\x88\x86\n\xe9' ; # 鐘分割成 \xe9 與 \x92\x9f
第二次接受msg2 = b'\x92\x9f_stone\n'
init_msg = b'' # 初始化流 while True: msg = soc.recv(128) # 接受数据 init_msg += msg msg_arr = init_msg.split(b'\n') # 注意此处的 b'\n' ,因为被拆分的为bytes串,所以也要用bytes串来拆分 init_msg += msg_arr[-1] msg_arr.remove(msg_arr[-1]) for i in range(len(msg_arr)): string = msg_arr[i].decode('utf-8') print(string
以上是Python解析Socket資料流異常bytes的問題(詳細)的詳細內容。更多資訊請關注PHP中文網其他相關文章!