如何将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
相关产品推荐
相关产品推荐

