Python Socket客户端发送TCP截图时随机挂停?问题排查求助
TCP客户端发送截图阻塞问题排查与解决
问题原因
你的客户端发送截图时阻塞在client_socket.sendall(size.to_bytes(4, 'big')),核心原因是测试服务端未读取客户端发送的数据:
TCP协议依赖接收方主动读取数据来释放发送缓冲区空间。当你发送大体积的截图数据时,如果服务端完全不处理接收,发送端的TCP发送缓冲区会很快被填满,sendall方法会因无法继续写入数据而进入阻塞状态,直到接收方读取数据腾出空间。
你测试发送字符串正常,是因为字符串数据量远小于TCP发送缓冲区的默认大小,缓冲区不会被填满,所以不会触发阻塞。
解决方案:完善服务端接收逻辑
修改测试服务端代码,添加完整的接收逻辑,主动读取客户端发送的大小信息和截图数据:
#!/usr/bin/env python3 import socket server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) host = "0.0.0.0" port = 80 server_socket.bind((host, port)) server_socket.listen(1) print("Server listening on port 80...") while True: client_socket, client_address = server_socket.accept() print(f"Connected from {client_address}") try: while True: # 接收4字节的图片大小标识 size_data = client_socket.recv(4) if not size_data: break # 客户端主动断开连接 img_size = int.from_bytes(size_data, 'big') # 循环接收完整的图片数据 img_bytes = b'' remaining = img_size while remaining > 0: # 每次最多接收4096字节,避免单次接收缓冲区溢出 chunk = client_socket.recv(min(remaining, 4096)) if not chunk: break # 连接中断 img_bytes += chunk remaining -= len(chunk) if remaining == 0: print(f"Received complete screenshot (size: {img_size} bytes)") else: print("Incomplete screenshot received, connection may have been interrupted") except Exception as e: print(f"Error occurred: {e}") finally: client_socket.close() print(f"Disconnected from {client_address}")
关键修改说明
- 添加循环接收逻辑:先读取4字节的图片长度,再按长度接收完整的截图数据
- 分块接收:使用
recv(min(remaining, 4096))分块读取数据,避免单次接收缓冲区溢出 - 异常与连接管理:处理客户端断开、连接中断的情况,确保资源正常释放
验证方法
- 启动修改后的服务端
- 运行客户端程序,此时客户端会正常循环发送截图,不再出现阻塞,控制台会持续打印
Sending screenshot
内容的提问来源于stack exchange,提问作者schlechtesterprogrammierer
相关产品推荐
相关产品推荐

