この記事の内容は、Python が Socket データ フローの異常バイトを解析する問題 (詳細) に関するもので、一定の参考価値がありますので、困っている友人は参考にしていただければ幸いです。
Python がソケット経由でデータを送信する場合、英語の文字は元の文字にエスケープされ、1 バイトを占有します (例: s は転送後に s に転送されます)が、中国語の文字はエスケープ後に 2 文字が必要です。漢字を識別します (例: エスケープ後のベルは \x92\x9f)。送信側には問題はありませんが、主にソケットクライアントで問題が発生します。クライアントがデータ ストリームを受け入れる場合、各受け入れにはバイト制限があり、中国語の文字は 2 回受け入れられるため、受け入れられたストリームが文字にエスケープされるたびに 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 作为下次接受
である場合、プログラムの異常終了を回避するには、次の 2 つの方法があります。対処:
1) データ損失処理
このとき、通常の受け入れ方法でバイトストリームをエスケープすると、UnicodeDecodeError 例外が発生しますので、例外を報告しないようにするために、方法 2 を使用します。エスケープするときに 2 番目のパラメータを指定します。パラメータは次のように無視されます:
smsg = bmsg.decode('utf-8', 'ignore') # 输出: 分\n ,如果为 replace 则 \n 后为 ?
2) データ ストリームを分割して処理します
一般に、ソケット サーバーはデータを送信します。各データ ストリームは完全であり、特定の文字 (\n など) の終わりとともに送信されます。この現状を踏まえ、データを受信するたびに、この特定の文字に従ってデータを分割して、単一のデータ ストリームを保存するリストを作成します。リストの最初のストリームは不完全である可能性があります。最後に受け入れられたストリームと結合して完全なデータ ストリームにし、エスケープします。中央のストリームは通常通りエスケープできるデータ ストリームです。最後のストリームも不完全であるため、保存してください。 、次に受け入れられたストリームを結合し、上記の操作を繰り返すために使用されます。これにより、プログラムが異常終了することがなくなり、データの整合性が保証されます。おおよそのコードは次のとおりです:
データ受け入れ:
初回 msg1 = b'\xe5\x88\x86\n\xe9' が受け入れられます; # クロックは \xe9 と \ に分割されますx92\x9f
2 回目は 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 の問題 (詳細)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。