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

移除print语句后Python Socket通信中断,仅添加调试print时才可正常工作的问题求助

移除print语句后Python Socket通信中断,仅添加调试print时才可正常工作的问题求助

我在做Python Socket通信的时候遇到了一个特别奇怪的问题:发送多行字符串内容时,接收端的循环只有在保留一条调试用的print语句时才能正常完成,一旦删掉这个print,接收逻辑就会卡住,永远等不到结束标记。

发送端的代码(处理help命令,发送多行帮助内容)

这是我这边发送多行字符串的逻辑,把帮助内容按行拆分后逐个发送,最后发送"END"作为结束标记:

elif command=="help":
        help_options='''
            download <path> -> Download a File from Target Machine
            upload <path>   -> Upload a File to Targe
            get <url>       -> Download a File to Target Machine from Internet
            start <program> -> Start Program on Target Machine
            screenshot      -> Take screenshot of the Target Screen
            check           -> Check for Administrator Privileges
        '''
        lines=help_options.splitlines()
        for line in lines:
            send_payload(line.encode("utf-8"))
        send_payload("END".encode("utf-8"))

接收端的代码(客户端接收help内容)

接收端我写了循环来拼接内容,直到收到"END"为止。但试了好几种调整方式都没用,只有保留那条调试print语句时才能正常工作:

elif command=="help":
        complete_message=""
        while True:
            line=receive_payload()
            # ---- 第一次尝试失败
            # if not line:
            #     time.sleep(0.01)
            #     continue

            # --- 第二次尝试失败
            # if not line:
            #     continue

            # --- 第三次尝试失败
            # time.sleep(0.01)

            # ------- 只有保留这个print语句才能正常运行  
            # print(f"line {line}")
            if line=="END":
                break
            if isinstance(line,bytes):
                complete_message += line.decode('utf-8') + "\n"
            else:
                complete_message+=line+"\n"
        print(complete_message)

奇怪的现象

只要把print(f"line {line}")这行注释掉,接收循环就会卡住,永远触发不了line=="END"的判断;但只要把这行print加回去,就能正常接收所有行内容,然后触发break,顺利打印出完整的帮助信息。

我怀疑是不是Socket缓冲区的问题,或者数据分块处理的逻辑有漏洞?试了加sleep、判断空行这些方法都没用,只有print能"救场",实在搞不懂为什么。

补充:send_payload和receive_payload的实现

我确认这两个函数在其他命令场景下是正常工作的,不过还是贴出来供大家参考:

send_payload函数

def send_payload(data):
    if isinstance(data, bytes): 
        # 二进制数据(比如文件)先转base64
        data = base64.b64encode(data).decode('utf-8')  
        padding = len(data) % 4
        if padding != 0:
            data += "=" * (4 - padding)  # 手动补全base64的padding

    # 把数据包装成JSON格式发送,避免消息拆分或格式问题
    json_data = json.dumps({"data": data})  # 打包成字典再序列化为JSON字符串
    sock.send(json_data.encode("utf-8"))

    print("data is sent from target machine")

receive_payload函数

def receive_payload():
    json_data = ""
    while True:
        try:
            chunk = target.recv(1024).decode("utf-8")
            print(f"Chunk received: {chunk}")
            if not chunk:
                break
            json_data += chunk  # 拼接收到的JSON片段
            try:
                data = json.loads(json_data)  # 尝试解析完整的JSON
                file_data = data.get("data")
                if file_data:
                    # 补全base64的padding
                    padding = len(file_data) % 4
                    if padding != 0:
                        print(f"Adding {4 - padding} padding to base64 data.")
                        file_data += "=" * (4 - padding)
                    # 解码base64数据
                    file_data = base64.b64decode(file_data)
                return file_data  # 返回解码后的数据
            except base64.binascii.Error as e:
                print(f"Error during base64 decoding: {e}")
                pass
            return None  # 如果不是base64编码的数据,返回None
        except json.JSONDecodeError:
            # 收到的JSON不完整,继续等待更多数据
            print("Incomplete JSON received. Waiting for more data.")
            continue

有没有大佬能帮我分析一下,为什么只有加了那个print语句接收逻辑才能正常工作?是不是我在接收或者发送的逻辑里有什么隐性的问题?比如Socket的缓冲区处理、消息边界的判断,或者是receive_payload函数里的逻辑漏洞?

备注:内容来源于stack exchange,提问作者Yilmaz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 15:23:01