Reputation: 651
I want to serialize a dict which has sockets object as values but i cannot get things to work.
Here is my code:
self.client_dictionary[username] = socket.socket() # update dictionary
file = open('client_sockets.pickle','wb')
pickle.dump(self.client_dictionary, file) #here is where the error is
file.close()
But i get the following error:
File "D:\Users\saunfe\AppData\Local\Programs\Python\Python35-
32\lib\socket.py",
line 175, in __getstate__ raise TypeError("Cannot serialize socket object")
TypeError: Cannot serialize socket object
Upvotes: 4
Views: 9104
Reputation: 819
Socket objects can't be pickled. The documentation for the pickle module explains which types can be pickled:
The following types can be pickled:
None, True, and False
integers, floating point numbers, complex numbers
strings, bytes, bytearrays
tuples, lists, sets, and dictionaries containing only picklable objects
functions defined at the top level of a module (using def, not lambda)
built-in functions defined at the top level of a module
classes that are defined at the top level of a module
instances of such classes whose
__dict__
or the result of calling__getstate__()
is picklable (see section Pickling Class Instances for details).
Now a socket
object isn't any of these types, and it doesn't even have a __dict__
(and its __getstate__()
complains that it can't be pickled).
From the way you wrote your question you most likely want to pickle the client connection of the socket, not the socket itself. Since you have an empty socket (from looking at your code snippet), you should pickle the parameters to the socket constructor, like this:
from socket import socket
import pickle
socket_args = {}
self.client_dictionary[username] = socket_args # update dictionary
file = open('client_sockets.pickle','wb')
pickle.dump(self.client_dictionary, file)
file.close()
# ...
# file open and load omitted for brevity
socket_args = self.client_dictionary[username]
socket_object = socket(**socket_args)
If the socket call had arguments, like `socket(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0), you would use this dictionary instead:
import socket
socket_args = {'family': socket.AF_INET, 'type': socket.SOCK_STREAM, 'proto': 0}
# ...
# pickle socket_args here
# ...
# load socket_args
socket_object = socket.socket(**socket_args)
Upvotes: 3