通过套接字将图像从客户端发送到服务器

时间:2019-08-11 15:26:12

标签: python python-3.x sockets python-imaging-library

我制作了一个TCP服务器和一个客户端,当服务器请求命令并接收“屏幕快照”时,客户端将获取该数据并通过图像作为字节对象发送,但是当我尝试执行.frombytes()并下载时并显示它会给我一个错误,即“图像数据不足”。

我尝试增加下载缓冲区。

服务器

import socket
from PIL import Image


class Server:
    def __init__(self, host, port):
        self.host = host
        self.port = port
        self.clients = []

    def start(self):
        server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server.bind((self.host, self.port))

        # backlog == how many connections we can have
        server.listen(1)

        while True:
            client, addr = server.accept()

            # Send our command to the client
            message = input("What is your command? ")
            client.send(message.encode(encoding="utf-8"))

            # Receive our data and check what to do with it.
            succesful_screenshot = client.recv(4096).decode(encoding="utf-8")
            if succesful_screenshot == "returnedScreenshot":
                client.settimeout(5.0)
                screenshot = client.recv(4096)

                img = Image.frombytes(data=screenshot, size=(500, 500), mode="RGB")
                img.show()
                print("hit this")


if __name__ == '__main__':
    Server(host='localhost', port=10000).start()

客户

import socket
from PIL import ImageGrab


class Client:
    def __init__(self, host, port):
        self.host = host
        self.port = port

    def start(self):
        server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server.connect((self.host, self.port))

        while True:
            data = server.recv(4096)
            decoded_data = data.decode(encoding="utf-8")
            if decoded_data == "screenshot":
                # If we receive a string from the server which equals "screenshot" then we grab a screenshot
                # We turn that screenshot into a byte object which we send back to the server and then we decrypt there.
                img = ImageGrab.grab()

                bytes_img = img.tobytes()

                # Send that we have taken a screenshot
                server.send("returnedScreenshot".encode("utf-8"))

                # Send the screenshot over.
                server.send(bytes_img)


if __name__ == '__main__':
    Client(host='localhost', port=10000).start()

错误

Traceback (most recent call last):
  File "C:/Users/Kaihan/PycharmProjects/Networking/demo/server.py", line 38, in <module>
    Server(host='localhost', port=10000).start()
  File "C:/Users/Kaihan/PycharmProjects/Networking/demo/server.py", line 32, in start
    img = Image.frombytes(data=screenshot, size=(500, 500), mode="RGB")
  File "C:\Users\Kaihan\AppData\Local\Programs\Python\Python36\lib\site-packages\PIL\Image.py", line 2412, in frombytes
    im.frombytes(data, decoder_name, args)
  File "C:\Users\Kaihan\AppData\Local\Programs\Python\Python36\lib\site-packages\PIL\Image.py", line 815, in frombytes
    raise ValueError("not enough image data")
ValueError: not enough image data

1 个答案:

答案 0 :(得分:0)

Server.start中,您执行:screenshot = client.recv(4096)。但是您不能确定:

  • 这实际上将读取4096个字节
  • 客户端发送的字节数不超过4096个字节

这正是PIL告诉您的:“图像数据不足”,这意味着您没有读取足够的数据。

您应确保阅读了客户端发送的所有内容。尝试将screenshot = client.recv(4096)替换为以下内容:

screenshot = b""
chunk = client.recv(4096)
while chunk:
    screenshot += chunk
    chunk = client.recv(4096)