使用套接字发送图像导致图像无法正确显示

Sending image with socket causing that the image doesnt show correnclty

我想编写一个程序,允许我将图像从客户端发送到服务器并编写此服务器和此客户端:

服务器:

import io
import struct
import socket
from PIL import ImageFile, Image


def server():
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind(('localhost', 3999))
    server_socket.listen(1)
    print('Server is listening on port 3999')
    while True:
        ImageFile.LOAD_TRUNCATED_IMAGES = True
        client_socket, address = server_socket.accept()
        print('Connection from: ', address)
        image = Image.open(io.BytesIO(client_socket.recv(1024)))
        image = image.resize((640, 480), Image.ANTIALIAS)
        image.save("transfer/image.jpg")
        client_socket.close()


if __name__ == '__main__':
    server()

这是客户:

import socket
import io

from PIL import Image


def Client():
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.connect(("localhost", 3999))
    byteImgIO = io.BytesIO()
    byteImg = Image.open("old.jpeg")
    byteImgIO.seek(0)
    byteImg.save(byteImgIO, format="JPEG")
    byteImgIO.seek(0)
    client.send(byteImgIO.read())
    client.close()


if __name__ == '__main__':
    Client()
    print("File sent to server")

这是图片: Image to send

这是输出: Image received

我做错了什么?

问题是你的图片不完整。至少有两个问题:

  • 首先,您只尝试在客户端读取1024字节。您的图片可能比那个大,而且您得到的图片可能会少于 1024 字节。因此,您需要读取直到获得正确的字节数,并且您可能希望发送一个 4 字节的网络 byte-order 大小(以字节为单位)作为帧的第一部分,以便客户端知道要读取多少字节。请记住,TCP 是一个连续的流,而不是数据包或消息。接收方需要被告知要读取多少字节。

  • 其次,发件人的磁盘上已经有一个 JPEG-encoded 文件。无需将其从 JPEG 解码以将其转换为 PIL Image 然后 re-encode 到 BytesIO 中的 JPEG 以发送它。只需以二进制方式打开磁盘文件,读取它并发送您读取的内容。

您可以在串行 here 上看到一个非常相似的示例,以了解读取 JPEG 和发送帧大小的想法。

recvall() 函数 展示了一种在循环中在套接字上接收特定字节数的方法。