• 技术文章 >后端开发 >Python教程

    Python解析Socket数据流异常bytes的问题(详细)

    不言不言2019-03-13 13:26:56转载1468
    本篇文章给大家带来的内容是关于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中文网其它相关文章!

    声明:本文转载于:博客园,如有侵犯,请联系admin@php.cn删除
    专题推荐:Python
    上一篇:Django中ModelForm组件的介绍(代码示例) 下一篇:python实现循环定时器的方法介绍(附代码)
    VIP课程(WEB全栈开发)

    相关文章推荐

    • 【活动】充值PHP中文网VIP即送云服务器• Python实现发短信的方法介绍(附代码)• Python基础流程控制的介绍(代码示例)• python中pandas和xlsxwriter读写xlsx文件的方法介绍(附代码)• python有序列表以及方法的介绍(代码)
    1/1

    PHP中文网