Kotlin客户端对接Python后端Socket消息合并接收问题求助
Socket消息合并问题修复方案
问题核心原因
TCP是面向字节流的传输协议,本身没有内置消息边界。操作系统内核可能会合并多次发送的小包后传输,接收方的单次recv调用也可能一次性读取到多段发送的数据。你当前的代码没有约定消息分割规则,所以无法区分独立发送的"A"消息。
另外你原有Python服务端代码中线程启动的写法也存在错误:调用thr.run()是同步执行处理逻辑,不会启动新线程,会阻塞后续连接接入。
修复方案(推荐用文本换行作为消息边界)
Kotlin客户端修改
使用PrintWriter的println方法自动在每条消息末尾追加换行符作为边界,同时开启自动flush减少重复代码:
val socket = Socket(server_ip, server_port) val input = BufferedReader(InputStreamReader(socket.getInputStream())) // 第二个参数传true开启自动flush,调用println后会自动刷入缓冲区 val out = PrintWriter(socket.getOutputStream(), true) out.println("10") for (i in 1..10) { out.println("A") }
Python服务端修改
将socket包装为文本缓冲流,按行读取每条独立消息,同时修正线程启动逻辑:
from socket import socket, AF_INET, SOCK_STREAM from threading import Thread def handle_connection(c): # 包装为utf8编码的文本流,按行读取数据 reader = c.makefile('r', encoding='utf8') amount = int(reader.readline().strip()) for i in range(amount): msg = reader.readline().strip() print(msg) class FileReceiver: def __init__(self): self.socket = socket(AF_INET, SOCK_STREAM) def run(self): try: self.socket.bind(('0.0.0.0', 7557)) self.socket.listen() while True: c, a = self.socket.accept() thr = Thread(target=handle_connection, args=(c,)) thr.start() # 修正线程启动写法 except KeyboardInterrupt: self.socket.detach() self.socket.close() fr = FileReceiver() fr.run()
可选替代方案(固定长度读取)
如果你的业务场景中所有消息长度都是固定的,也可以直接指定recv的读取长度:
def handle_connection(c): # 前2字节为数字长度 amount = int(c.recv(2).decode("utf8")) for i in range(amount): # 每次仅读取1字节的"A"消息 print(c.recv(1).decode("utf8"))
该方案扩展性较差,仅适用于消息长度完全固定的场景。
内容的提问来源于stack exchange,提问作者Ilya
相关产品推荐
相关产品推荐

