Python服务端向客户端发送字典数据失败,求助排查
问题分析与解决方案
核心问题
- 收发次数不匹配:服务端循环发送多条记录,但客户端仅调用一次
server.recv(1024)。TCP是流式协议,没有天然的消息边界,客户端只能收到服务端发送的部分数据(可能是第一条,或者多条粘在一起的片段),无法获取完整的所有记录。 - 潜在的换行符残留:读取文件时,每行末尾的
\n会被包含在最后一个字段number中,导致发送的字符串带有多余换行,可能影响后续数据解析。
解决办法
方法1:添加结束标记,客户端循环接收
在服务端发送完所有记录后,发送一个约定的结束信号(如"END"),客户端循环接收直到收到该标记:
服务端修改代码:
# 先处理文件读取时的换行问题 records = {} with open("data.txt") as f: for line in f: # 先strip掉换行再split,避免字段带换行 name1, age, location, number = line.strip().split("|") records[str(name1)] = [age, location, number] # 发送所有记录 for keys in records.keys(): value_list = records[keys] string = f"{keys}|{value_list[0]}|{value_list[1]}|{value_list[2]}" client.send(string.encode()) # 发送结束标记 client.send(b"END")
客户端修改代码:
buffer = "" while True: data = server.recv(1024).decode() if not data: # 服务端断开连接 break if "END" in data: # 去掉结束标记,拼接剩余数据 buffer += data.replace("END", "") break buffer += data # 打印并拆分记录 print("Server:") for record in buffer.split("\n"): if record: print(record)
方法2:先发送数据长度,再发送完整内容
通过先发送数据的总长度,让客户端明确知道需要接收多少字节,彻底避免粘包问题:
服务端修改代码:
import struct # 处理文件读取,去除换行 records = {} with open("data.txt") as f: for line in f: name1, age, location, number = line.strip().split("|") records[str(name1)] = [age, location, number] # 拼接所有记录,用换行分隔 all_records = [] for key in records: vals = records[key] all_records.append(f"{key}|{vals[0]}|{vals[1]}|{vals[2]}") full_data = "\n".join(all_records).encode() # 发送数据长度(用4字节大端整数表示) client.send(struct.pack('!I', len(full_data))) # 发送完整数据 client.send(full_data)
客户端修改代码:
import struct # 接收数据长度 len_bytes = server.recv(4) if not len_bytes: print("服务端断开连接") exit() data_length = struct.unpack('!I', len_bytes)[0] # 循环接收直到获取完整数据 received_data = b"" while len(received_data) < data_length: chunk = server.recv(min(1024, data_length - len(received_data))) if not chunk: break received_data += chunk # 解析并打印 full_records = received_data.decode() print("Server:") for line in full_records.split("\n"): if line: print(line)
内容的提问来源于stack exchange,提问作者gt_green
相关产品推荐
相关产品推荐

