我正在尝试显示我从pyqt窗口内的测试本地服务器收到的图像。我试过这个链接,但我无法让它工作。你可以帮忙吗?提前致谢。
Displaying Image (in bytes) in PyQt
客户代码
import socket
from PIL import Image
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel
from PyQt5.QtGui import QIcon, QPixmap
app = QApplication(sys.argv)
widget = QWidget()
label = QLabel(widget)
HOST = socket.gethostbyname(socket.gethostname())
PORT = 5000
s = socket.socket()
s.connect((HOST, PORT))
while True:
image_binaries = s.recv(100000000)
if not image_binaries:
break
#img = Image.open(BytesIO(image_binaries))
pixmap = QPixmap()
pixmap.loadFromData(image_binaries)
label.setPixmap(pixmap)
widget.resize(pixmap.width(), pixmap.height())
widget.show()
sys.exit(app.exec_())
服务器代码
import socket
HOST = "0.0.0.0"
PORT = 5000
s = socket.socket()
s.bind((HOST, PORT))
data = open(r'Screenshot_1.jpg', 'rb').read()
print("Waiting for connection...")
s.listen(5)
while True:
client, client_address = s.accept()
print(client_address, "is connected")
client.send(data)
此代码中存在不同的问题。
首先是读取循环是错误的。 TCP是一种流协议。这意味着数据可能包含您必须连接的可变数量的数据包。所以它应该是:
image_binaries = b""
while True:
chunk = s.recv(100000000)
if not chunk:
break
image_binaries += chunk
s.close()
然后你有一个可能的竞争条件服务器端。一旦所有数据排队等待传输,client.send(data)
将立即返回。如果立即发生另一个连接,将重用client
,这可能导致先前的连接在发送所有内容之前关闭。你应该在这里使用graceful shutdown:
while True:
client, client_address = s.accept()
print(client_address, "is connected")
client.send(data)
client.shutdown(socket.SHUT_WR) # notify that nothing more is to be sent
_ = client.recv(16) # wait for the client to close when everything has been received
client.close() # Ok, we can explicitely close