使用套接字发送图像导致图像无法正确显示
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()
函数 展示了一种在循环中在套接字上接收特定字节数的方法。
我想编写一个程序,允许我将图像从客户端发送到服务器并编写此服务器和此客户端:
服务器:
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()
函数