0

I am trying to read the UDP broadcast response from the code below. Two servers are found and the information is returned for both of them. What I want to do is make a dict for each response but I can't seem to separate the individual responses. Can any one make some suggestions please?

import socket
import json

socket.setdefaulttimeout(.5)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, True)
s.sendto("D", ('255.255.255.255', 30303))

while True:
    response = s.recv(2048)
    response = json.loads(response)
    print response

This is the response:

{u'Product': u'OWServer_v2-Enet', u'Name': u'OWServer_v2-Enet_19',       u'IP': u'10.0.1.19', u'TCPIntfPort': u'0', u'HTTPPort': u'80', u'MAC': u'00-04-A3-B1-F1-86', u'Bootloader': u'POST', u'FWVer': u'1.44', u'NETBios': u'EDSOWSERVER19   '}
{u'Product': u'OWServer_v2-Enet', u'Name': u'OWServer_v2-Enet_20', u'IP': u'10.0.1.20', u'TCPIntfPort': u'0', u'HTTPPort': u'80', u'MAC': u'00-04-A3-C1-43-86', u'Bootloader': u'POST', u'FWVer': u'1.44', u'NETBios': u'EDSOWSERVER20   '}
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
socket.timeout: timed out

Using your suggestions, if I have done it correctly, gives me ValueErrors.

buf = "" 

while True:
    buf = buf + s.recv(2048)
    resp = ''
    if "\n" in buf:
        resp, buf = buf.split("\n", 1)
        if resp:
            print json.loads(resp)

raise ValueError(errmsg("Expecting property name", s, end - 1))
ValueError: Expecting property name: line 1 column 32 (char 32)
bob_the_bob
  • 345
  • 1
  • 13
  • Have you tried [iteration](http://stackoverflow.com/questions/1078118/how-do-i-iterate-over-a-json-structure)? It's hard to be more helpful when I am not sure what you have tried. – Shea Price Feb 26 '16 at 16:21

1 Answers1

2

You should use a separator, for example a newline, so you get a stream of JSON-lines. You can then split on newline and parse each item separately. But of course, you must add the newline on your own when sending the packets.

A JSON entry might span multiple packets and you have to manage packet segmentation on your own. When you do s.recv(2048), you get up to 2048 bytes of data, which you need to store in buffer:

buf = buf + s.recv(2048)

Then split this buffer into full response and the rest:

resp = ''
if '\n' in buf:
    resp, buf = buf.split('\n', 1)

And then load the full response:

if resp:
    print json.loads(resp)
hruske
  • 2,205
  • 19
  • 27