이 문서의 내용은 Python 구문 분석 소켓 데이터 흐름의 비정상적인 바이트 문제에 대한 것입니다. 특정 참고 값이 있으므로 도움이 될 수 있기를 바랍니다.
파이썬이 소켓을 통해 데이터를 보낼 때 영어 문자는 이스케이프되어 원래 문자로 변환되어 1바이트를 차지합니다(예: s는 s로 전송됨). 반면 중국어 문자는 이스케이프된 후 한자를 식별하기 위해 2바이트가 필요합니다. 예를 들어, 이스케이프 후 벨은 x92x9f입니다. 송신 측에서는 문제가 없으나 주로 소켓 클라이언트에서 문제가 발생합니다. 클라이언트가 데이터 스트림을 수락할 때 각 수락에 대한 바이트 제한이 있고 한자는 두 번 허용되므로 수락된 스트림이 문자로 이스케이프될 때마다 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) 데이터 손실 처리
이때 일반적인 승인 방법을 사용하여 바이트 스트림을 이스케이프하면 예외를 보고하지 않기 위해 UnicodeDecodeError 예외가 발생합니다. 2 이스케이프할 때 다음과 같이 두 번째 매개변수를 무시로 지정합니다.
smsg = bmsg.decode('utf-8', 'ignore') # 输出: 分\n ,如果为 replace 则 \n 后为 ?
2) 데이터 스트림을 분할한 후 처리합니다.
일반적으로 소켓 서버가 데이터를 보내면 각 데이터 스트림은 완료되고 다음으로 끝납니다. 특정 문자(예: n) 종료하여 함께 보냅니다. 이러한 현재 상황에 따라 데이터를 수신할 때마다 이 특정 문자에 따라 단일 데이터 스트림을 저장하는 목록으로 분할합니다. 목록의 첫 번째 스트림은 불완전할 수 있으므로 마지막으로 허용된 스트림과 병합하여 완전한 데이터 스트림으로 이스케이프합니다. 중간 스트림은 정상적으로 이스케이프할 수 있는 데이터 스트림이므로 저장하세요. . , 다음에 승인된 스트림을 연결하고 위의 작업을 반복하는 데 사용됩니다. 이렇게 하면 프로그램이 비정상적으로 종료되지 않고 데이터의 무결성이 보장됩니다. 대략적인 코드는 다음과 같습니다.
데이터 승인:
처음 msg1 승인 = b'xe5x88x86nxe9'; # 시계는 xe9와 x92x9f로 분할됩니다.
두 번째 msg2 승인 = b'x92x9f_stonen'
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 중국어 웹사이트의 기타 관련 기사를 참조하세요!