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

如何将Python2的Socket发送代码完美迁移至Python3适配Klipper服务

Python2转Python3:适配Klipper的Socket客户端改造

问题背景

现有一个基于Python2的Socket客户端脚本,用于连接Klipper 3D打印服务,需要升级至Python3。仅允许修改客户端的connect和send方法,不改动Klipper服务端代码。尝试修改发送逻辑后服务无响应,需完全复刻Python2的消息发送格式。

原Python2代码

连接方法

def connect(self):
    sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    sys.stderr.write("Waiting for connect to %s\n" % (self.uds_filename,))
    while 1:
        try:
            sock.connect(self.uds_filename)
        except socket.error as e:
            if e.errno == errno.ECONNREFUSED:
                time.sleep(0.1)
                continue
            sys.stderr.write("Unable to connect socket %s [%d,%s]\n"
                             % (self.uds_filename, e.errno,
                                errno.errorcode[e.errno]))
            sys.exit(-1)
        break
    print("CONNECTED")
    self.webhook_socket = sock

发送方法

def send(self, message):
    self.webhook_socket.send("%s\x03" % (message))  # message is type 'str'

失败的尝试

修改发送方法为以下代码后,Klipper服务无任何响应:

def send(self, message):
    self.webhook_socket.send(message.encode())

正确的改造方案

连接方法的Python3适配

Python3中socket.error已合并到OSError,同时将while 1改为更符合Python3风格的while True,其余逻辑保持一致:

def connect(self):
    sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    sys.stderr.write("Waiting for connect to %s\n" % (self.uds_filename,))
    while True:
        try:
            sock.connect(self.uds_filename)
        except OSError as e:
            if e.errno == errno.ECONNREFUSED:
                time.sleep(0.1)
                continue
            sys.stderr.write("Unable to connect socket %s [%d,%s]\n"
                             % (self.uds_filename, e.errno,
                                errno.errorcode[e.errno]))
            sys.exit(-1)
        break
    print("CONNECTED")
    self.webhook_socket = sock

发送方法的Python3适配

要生成和Python2完全一致的字节流,需将字符串编码为ASCII(Python2的str默认使用ASCII编码),并追加终止符0x03的字节。以下两种写法等价:

# 写法1:拼接编码后的字符串和终止符字节
def send(self, message):
    self.webhook_socket.send(message.encode('ascii') + bytes([0x03]))
# 写法2:先拼接字符串再编码
def send(self, message):
    self.webhook_socket.send(("%s\x03" % message).encode('ascii'))

内容的提问来源于stack exchange,提问作者Vincent Bénet

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 21:37:32