Python解析Socket數據流異常bytes問題


Python解析Socket數據流異常bytes問題 -- 2019-03-12

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)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM