You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 15:57:05