I wanted to write a program that allows me to send an image from a client to a server and to write this server and this client:
Server:
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()
and this is the client:
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")
This is the image: Image to send
This is the output: Image received
what did i wrong?
CodePudding user response:
The problem is that your image is incomplete. There are at least two issues:
first, you only try to read 1024 bytes in the client. Your image may be larger than that and you may get fewer than 1024 bytes anyway. So you need to read until you get the correct number of bytes, and you probably want to send a 4-byte network byte-order size in bytes as the first part of your frame so the client knows how many bytes to read. Remember TCP is a continuous stream, not packets or messages. The receiver needs to be told how many bytes to read.
secondly, the sender already has a JPEG-encoded file on disk. There is no need to decode it from JPEG to turn it into a
PIL Image
then re-encode to a JPEG inside aBytesIO
to send it. Just open the disk file in binary mode, read it and send what you read.
You can see a very similar example over serial here to get an idea of reading a JPEG and sending the frame size.
The recvall()
function here shows a way of receiving a specific number of bytes on a socket in a loop.