Reputation: 591
I have a server:
import socket
import time
import random
from PIL import ImageGrab
server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server_socket.bind(('127.0.0.1',8820))
server_socket.listen(1)
while True:
print "Waiting for commands"
a = ImageGrab.grab()
CommandDict = {"TIME" : time.strftime("%a %b %d %H:%M:%S %Y"),"NAME": "Ori","RANDOM": str(random.randint(0,10)),"EXIT":"BYE","PRINT SCREEN":a}
(client_socket, client_address) = server_socket.accept()
client_data = client_socket.recv(1024)
print "GOT COMMAND FROM " + client_address[0] + " : " + client_data
client_socket.send(CommandDict[client_data])
client_socket.close()
server_socket.close()
and the client:
import socket
from PIL import ImageGrab
while True:
client_input = raw_input("Enter You Command: ")
CommandList=["EXIT","TIME","NAME","RANDOM","PRINT SCREEN"]
if client_input in CommandList:
my_socket=socket.socket()
my_socket.connect(('127.0.0.1',8820))
my_socket.send(client_input)
data = my_socket.recv(1024) + "\n"
if client_input=="PRINT SCREEN":
data.save()
else:
print "SERVER: " + data
else:
print "Invalid command. try one of those: " + " , ".join(CommandList) + "\n" + "."
my_socket.close()
When i try this it gives me an error because it trys to send it as a string object. I want to send an object through socket and i want the client to read it. Any ideas?
Upvotes: 0
Views: 12171
Reputation: 40683
The following should allow you to pickle an image. I don't have PIL on my current machine, so I haven't been able to test it properly. The machine
import cPickle as pickle # cPickle is considerably more efficient than pickle
import copy_reg
from StringIO import StringIO
from PIL import Image, ImageGrab
def pickle_image(img):
"""Turns an image into a data stream. Only required on machine sending the
image."""
data = StringIO()
img.save(data, 'png')
data.seek(0)
return unpickle_image, (data,)
def unpickle_image(data):
"""Turns a data stream into an image. Required on both machines"""
img = Image.open(data)
data.close() # releases internal buffer immediately
return img
# tells pickle it should use the function pickle_image to pickle objects of
# type Image. Required on the machine sending the image
copy_reg.pickle(Image, pickle_image)
some_image = ImageGrab.grab()
# HIGHEST_PROTOCOL uses a more effcient representation of the object
pickled_image = pickle.dumps(some_image, pickle.HIGHEST_PROTOCOL)
unpickled_image = pickle.loads(pickled_image)
In my code I have used dumps
and loads
to create and use a string representation of the data. Ideally you should be using dump
and load
, passing my_socket.makefile()
as the file argument.
Upvotes: 1
Reputation: 249103
Python includes an object serialization module called pickle
: https://docs.python.org/2/library/pickle.html
You can use pickle.dumps(CommandDict[client_data])
to produce a string which you can then send on a socket. Then use pickle.loads
to restore the object on the other side. Of course this requires that the object is "pickleable", but many simple data structures are, or can be made so without much trouble. In your case you may need to add some code to pickle the ImageGrab
object type, but try it first and see if it works by default.
Upvotes: 2