套接字收到无效的起始字节(UnicodeDecodeError,SOCK_STREAM)
Socket received invalid start byte (UnicodeDecodeError, SOCK_STREAM)
我正在使用 socket.socket(socket.AF_INET, socket.SOCK_STREAM)
类型的阻塞 python 套接字将消息从我的客户端发送到我的服务器。如果我快速连续发送消息(但不是同时发送),我的服务器会收到以下错误消息:
in receive
size = int(rec_sock.recv(HEADER_SIZE).decode('utf-8'))
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 0: invalid start byte
在每条消息之前,我发送一个 header,其中包含以下消息的长度。 header 由客户端以 UTF-8 编码,因此不应引发此错误。 header 也是客户端尝试使用 UTF-8 解码的消息的唯一部分,所以我不确定这个错误是如何发生的。
我正在使用以下方法发送、接收和制作 header:
BUF_SIZE = 16384
HEADER_SIZE = 16
def receive(rec_sock: socket.socket) -> Any:
message = b''
size = int(rec_sock.recv(HEADER_SIZE).decode('utf-8'))
if size:
while len(message) < size:
data = rec_sock.recv(BUF_SIZE)
message += data
return pickle.loads(message) if len(message) else None
def send(resp: Any, send_sock: socket.socket) -> None:
pickeled = pickle.dumps(resp)
send_sock.send(make_header(len(pickeled)))
send_sock.send(pickeled)
def make_header(msg_size: int) -> bytes:
encoded = str(msg_size).encode('utf-8')
return b'0' * (HEADER_SIZE - len(encoded)) + encoded
问题是我总是在我的接收方法中填充整个缓冲区,即使剩余消息的长度小于缓冲区大小。因此,如果在短时间内连续发送两条消息,则下一条消息的 header 会被先前的 receive 调用读取,而下一条消息的实际内容将被读取为 header(utf-8无法解码)
将接收方法更改为此修复它:
def receive(rec_sock: socket.socket) -> Any:
message = b''
size = int(rec_sock.recv(HEADER_SIZE).decode('utf-8'))
print("Waiting for", size, "bytes ...")
if size:
while len(message) < size:
remaining = size - len(message)
read_len = BUF_SIZE if remaining >= BUF_SIZE else remaining
data = rec_sock.recv(read_len)
message += data
print("Received", len(message), "bytes.")
return pickle.loads(message) if len(message) else None
我正在使用 socket.socket(socket.AF_INET, socket.SOCK_STREAM)
类型的阻塞 python 套接字将消息从我的客户端发送到我的服务器。如果我快速连续发送消息(但不是同时发送),我的服务器会收到以下错误消息:
in receive
size = int(rec_sock.recv(HEADER_SIZE).decode('utf-8'))
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 0: invalid start byte
在每条消息之前,我发送一个 header,其中包含以下消息的长度。 header 由客户端以 UTF-8 编码,因此不应引发此错误。 header 也是客户端尝试使用 UTF-8 解码的消息的唯一部分,所以我不确定这个错误是如何发生的。
我正在使用以下方法发送、接收和制作 header:
BUF_SIZE = 16384
HEADER_SIZE = 16
def receive(rec_sock: socket.socket) -> Any:
message = b''
size = int(rec_sock.recv(HEADER_SIZE).decode('utf-8'))
if size:
while len(message) < size:
data = rec_sock.recv(BUF_SIZE)
message += data
return pickle.loads(message) if len(message) else None
def send(resp: Any, send_sock: socket.socket) -> None:
pickeled = pickle.dumps(resp)
send_sock.send(make_header(len(pickeled)))
send_sock.send(pickeled)
def make_header(msg_size: int) -> bytes:
encoded = str(msg_size).encode('utf-8')
return b'0' * (HEADER_SIZE - len(encoded)) + encoded
问题是我总是在我的接收方法中填充整个缓冲区,即使剩余消息的长度小于缓冲区大小。因此,如果在短时间内连续发送两条消息,则下一条消息的 header 会被先前的 receive 调用读取,而下一条消息的实际内容将被读取为 header(utf-8无法解码)
将接收方法更改为此修复它:
def receive(rec_sock: socket.socket) -> Any:
message = b''
size = int(rec_sock.recv(HEADER_SIZE).decode('utf-8'))
print("Waiting for", size, "bytes ...")
if size:
while len(message) < size:
remaining = size - len(message)
read_len = BUF_SIZE if remaining >= BUF_SIZE else remaining
data = rec_sock.recv(read_len)
message += data
print("Received", len(message), "bytes.")
return pickle.loads(message) if len(message) else None