在PyQt窗口中显示本地测试服务器接收图片的问题求助
解决PyQt客户端接收并显示服务器图片的问题
我帮你梳理下代码里的几个关键问题,然后给出修复后的版本:
问题分析
你的代码主要有三个核心问题:
- 服务器发送完图片后未关闭连接,导致客户端一直阻塞在
s.recv(),无法完成图片加载 - 客户端的while循环阻塞了Qt的事件循环,界面会变得无响应,而且
widget.show()放在循环里重复调用也不合理 - 没有处理图片数据可能分多次接收的情况,一次
recv不一定能拿到完整的图片二进制数据
修复后的服务器代码
import socket HOST = "0.0.0.0" PORT = 5000 with socket.socket() as s: s.bind((HOST, PORT)) print("Waiting for connection...") s.listen(5) while True: client, client_address = s.accept() print(f"{client_address} is connected") # 读取图片数据,先发送数据长度,再发送实际内容 with open(r'Screenshot_1.jpg', 'rb') as f: data = f.read() # 先发送数据的字节长度(用4字节的大端整数表示) data_len = len(data).to_bytes(4, byteorder='big') client.sendall(data_len) # 发送完整的图片数据 client.sendall(data) # 发送完后关闭客户端连接 client.close()
修复后的客户端代码
import socket import sys from PyQt5.QtWidgets import QApplication, QWidget, QLabel from PyQt5.QtGui import QPixmap def receive_image(sock): # 先接收数据长度 len_data = sock.recv(4) if not len_data: return None data_len = int.from_bytes(len_data, byteorder='big') # 按长度接收完整的图片数据 image_binaries = b'' while len(image_binaries) < data_len: chunk = sock.recv(min(data_len - len(image_binaries), 1024*1024)) if not chunk: break image_binaries += chunk return image_binaries app = QApplication(sys.argv) widget = QWidget() label = QLabel(widget) widget.show() # 先显示窗口 HOST = socket.gethostbyname(socket.gethostname()) PORT = 5000 with socket.socket() as s: s.connect((HOST, PORT)) image_data = receive_image(s) if image_data: pixmap = QPixmap() if pixmap.loadFromData(image_data): label.setPixmap(pixmap) widget.resize(pixmap.width(), pixmap.height()) else: label.setText("Failed to load image") sys.exit(app.exec_())
修改说明
- 服务器端:
- 使用
with语句自动管理socket和文件资源,避免资源泄漏 - 先发送图片数据的长度(4字节大端整数),让客户端知道需要接收多少数据
- 发送完数据后立即关闭客户端连接,避免客户端一直等待
- 使用
- 客户端:
- 单独编写
receive_image函数来保证接收完整的图片数据 - 先显示窗口,再处理图片加载和更新,避免阻塞事件循环
- 使用
with管理socket资源,接收完数据后自动关闭连接 - 添加了图片加载失败的提示
- 单独编写
这样修改后,客户端就能正常接收并显示服务器发送的图片了。
内容的提问来源于stack exchange,提问作者suleymanyaman
相关产品推荐
相关产品推荐

