17

here is my python tcp client. I want to send a json object to the server.But I can't send the object using the sendall() method. how can I do this?

import socket
import sys
import json

HOST, PORT = "localhost", 9999

m ='{"id": 2, "name": "abc"}'
jsonObj = json.loads(m)


data = jsonObj

# Create a socket (SOCK_STREAM means a TCP socket)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

try:
    # Connect to server and send data
    sock.connect((HOST, PORT))
    sock.sendall(jsonObj)


    # Receive data from the server and shut down
    received = sock.recv(1024)
finally:
    sock.close()

print "Sent:     {}".format(data)
print "Received: {}".format(received)
3
  • When you say 'I can't send the object', do you see any error? Or is the program stuck? Have you verified that a TCP server is listening at localhost:9999? Commented Oct 2, 2016 at 13:55
  • server is listening. and the following error appears.. Traceback (most recent call last): File "C:/Users/Lochana/PycharmProjects/SocketClient/TCPClient.py", line 19, in <module> sock.sendall(jsonObj) File "C:\Python27\lib\socket.py", line 228, in meth return getattr(self._sock,name)(*args) TypeError: sendall() argument 1 must be string or buffer, not dict Commented Oct 2, 2016 at 14:24
  • In that case, you need to serialize dict to string. Or pass the object 'm' to sendall instead of 'jsonObj'. (What is Serialization - en.m.wikipedia.org/wiki/Serialization) Commented Oct 2, 2016 at 14:39

3 Answers 3

9

Sending a dict with json like below worked in my program.

import socket
import sys
import json

HOST, PORT = "localhost", 9999

#m ='{"id": 2, "name": "abc"}'
m = {"id": 2, "name": "abc"} # a real dict.


data = json.dumps(m)

# Create a socket (SOCK_STREAM means a TCP socket)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

try:
    # Connect to server and send data
    sock.connect((HOST, PORT))
    sock.sendall(bytes(data,encoding="utf-8"))


    # Receive data from the server and shut down
    received = sock.recv(1024)
    received = received.decode("utf-8")

finally:
    sock.close()

print "Sent:     {}".format(data)
print "Received: {}".format(received)

Sign up to request clarification or add additional context in comments.

Comments

5

Skip the json.loads() part. Send the json object as the json string and load it from the string at the TCP client.

Also check: Python sending dictionary throught TCP

3 Comments

No, you can not send the JSON object. You need to firstly serialize it
@LochanaThenuwara Send and sendall methods of socket accept string as parameter. Hence, you need to send data as string. In this case, data is json. At client end, convert it to string and at server, convert the received string to json.
when it's just a string returns TypeError: a bytes-like object is required, not 'str' and when using with json.loads returns TypeError: a bytes-like object is required, not 'dict'
1

AS you can find out from Python sending dictionary through TCP it better convert the JSON object to a dictionary and using the following snippet

import json
data = json.load(open("data.json"))
 //or 
data = json.load('{"id": 2, "name": "abc"}')

type(data)
print(data[<keyFromTheJsonFile>])

You should serialize it with pickle:

import pickle
dict = {...}
tcp_send(pickle.dumps(dict))

And on the other end:

import pickle
dict = pickle.loads(tcp_recieve())

If the other end is not written in python, you can use a data serialization format, like xml, json or yaml.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.