ziggy ziggy - 5 months ago 14
Python Question

How do you send a dictionary over a socket in Python?

I know that similar questions have been raised but they don't seem to work for me! I have tried serializing the dictionary then converting that to a string then encoding it before I send it over the socket. No success so far!

This is my server code:
#library
import socket
import pickle

#socket initialization
host = "127.0.0.1"
port = 5000
mainAddr = (host, port)

#dict initialization
dataDict = {} #just imagine that dict has content

#create socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #TCP
s.bind((mainAddr))
s.listen(4)
print('program started')
print('listening..')

while True:
try:
conn, addr = s.accept()
print("connection from: "+str(addr))
print("sending message..")
pickle.dumps(dataDict)
print('pickled!')
dataS = str(dataP)
print('stringed!')
dataE = dataS.encode('UTF-8')
print('encoded!')
s.sendto(dataE,addr)
print('data sent!')
except:
pass

s.close()


For the socket initialization, I've tried other types:

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #UDP
s = socket.socket()


For the sending part, I've tried these alternatives:

s.send(dataE)
s.send(dataE,addr)
s.sendall(dataE)
s.sendall(dataE,addr)


When I run the program, these get printed out:

program started
listening..
connection from:<insert addr here>
sending message..
pickled!
stringed!
encoded!


Only
data sent!
is not sent. So I am guessing that it's the sending part that has a problem.

For the client side, here's the code:

#library
import socket
import pickle

#initialization
host = '127.0.0.1'
port = 5000
buffer = 1024

#create socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #TCP
s.connect((host,port))
print('connected!')

#receive dictionary
print('receiving message..')
while True:
data, addr = s.recvfrom(buffer)
print('received!')
dataD = data.decode("UTF-8")
print('decoded!')
dataP = pickle.loads(dataD)
print('unpickled!')
print(str(dataP))

s.close()


In the client terminal, only the following prints:

connected!
receiving message..


On the client side, I've tried changing the order of unpickling and decoding but still, to no avail.

Answer Source

A TCP server socket is not actually used for sending/receiving data; I'm surprised you're not getting an error when calling s.send() or similar on it. Instead, it's a factory for producing individual sockets for each client that connects to the server - conn, in your code. So, conn.sendall() is what you should be using. No address parameter is required, the individual socket already knows who it is talking to. (.send() is unreliable without some extra work on your part; .sendto() is only used with UDP sockets that have not been connected to a particular client.)