Ronald Saunfe
Ronald Saunfe

Reputation: 651

How to serialize a socket object using pickle in python

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

Answers (1)

Zenul_Abidin
Zenul_Abidin

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

Related Questions