I am having an issue with JSON, I can't seem to figure out why this is not working. This is supposed to output JSON.
Here is my code
#!/usr/bin/env python
import socket
import struct
import json
def unpack_varint(s):
d = 0
i = 0
while True:
b = ord(s.recv(1))
d |= (b & 0x7F) << 7*i
i += 1
if not b & 0x80:
return d
def pack_data(d):
return struct.pack('>b', len(d)) + d
def pack_port(i):
return struct.pack('>H', i)
def get_info(host, port=25565):
# Connect
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
# Send handshake + status request
s.send(pack_data("\x00\x00" + pack_data(host.encode('utf8')) + pack_port(port) + "\x01"))
s.send(pack_data("\x00"))
# Read response
unpack_varint(s) # Packet length
unpack_varint(s) # Packet ID
l = unpack_varint(s) # String length
d = ""
while len(d) < l:
d += s.recv(1024)
# Close our socket
s.close()
# Load json and return
return json.loads(d.decode('utf8'))
get_info('162.213.43.124');
I am getting this error
Traceback (most recent call last):
File "main.py", line 46, in
get_info('162.213.43.124');
File "main.py", line 45, in get_info
return json.loads(d.decode('utf8'))
File "/usr/local/lib/python2.7/json/__init__.py", line 338, in loads
return _default_decoder.decode(s)
File "/usr/local/lib/python2.7/json/decoder.py", line 365, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/local/lib/python2.7/json/decoder.py", line 383, in raw_decode
raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded
If anyone could come to the rescue that would be awesome!
It seems that you have invalid JSON. In that case, that's totally dependent on the data the server sends you which you have not shown. I would suggest running the response through a JSON validator.
Related
I'm trying to make a little program which needs two clients and a server. Basically I want to send JSON from client 1 to client 2, (which client 1 has received from the server), but it doesn't work. From client 1 to the server does work though. I use a new socket connection to send from client 1 to client 2 (this is mandatory for my assignment).
I get these errors:
File "C:\Users\duser\OneDrive\Bureaublad\clientt.py", line 105, in <module>
client2()
File "C:\Users\duser\OneDrive\Bureaublad\clientt.py", line 75, in client2
newdict = json.loads(receiveclient1)
File "C:\Users\duser\AppData\Local\Programs\Python\Python38\lib\json\__init__.py", line 357, in loads
return _default_decoder.decode(s)
File "C:\Users\duser\AppData\Local\Programs\Python\Python38\lib\json\decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Users\duser\AppData\Local\Programs\Python\Python38\lib\json\decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
Here is the code:
import socket
import json
import sys
i = 0
host = "xxx.xx.xxx.xxx"
port = 55550
port2 = 44445
obj = socket.socket()
s = socket.socket()
hostname = socket.gethostname()
complete_info = ''
clientinfo = {"studentnr1": "0982130",
"studentnr2": "0943260",
"classname": "INF",
"clientid": 1,
"teamname":"Team",
"ip":socket.gethostbyname(hostname),
"secret": "",
"status": ""}
def client1():
global complete_info, newdict
obj.connect((host,port))
while True:
data = obj.recv(1024)
if len(data) == 0:
break
complete_info = data.decode("utf-8")
print(complete_info)
clientinfosend = str.encode(json.dumps(clientinfo))
obj.sendall(clientinfosend)
inforeceive = obj.recv(1024).decode("utf-8")
inforeceived = json.loads(inforeceive)
print(inforeceived)
s.connect((socket.gethostbyname(hostname),port2))
s.sendall(str.encode(json.dumps(inforeceived)))
obj.close()
print("Connection closed")
def client2():
#while loop which listens to connection from client 1
s.bind((socket.gethostbyname(hostname), port2))
s.listen()
conn, addr = s.accept()
print("Listening for connections")
while True:
print('Connection from', addr)
data = conn.recv(1024).decode("utf-8")
if not data:
break
receiveclient1 = conn.recv(1024).decode("utf-8")
newdict = json.loads(receiveclient1)
print(newdict)
temp = newdict["studentnr1"]
newdict["studentnr1"] = newdict["studentnr2"]
newdict["studentnr2"] = temp
newdict["clientid"] = sys.argv[1]
s.close()
num_arguments = len(sys.argv[1:])
i = 1
args = sys.argv[1:]
if int(sys.argv[i]) == 1:
client1()
elif int(sys.argv[i]) == 2:
client2()
In client2, you first read the socket until it is shut down or closed with:
while True:
print('Connection from', addr)
data = conn.recv(1024).decode("utf-8")
if not data:
break
That means that when you exit that loop, no data can come from the socket.
So in next lines:
receiveclient1 = conn.recv(1024).decode("utf-8")
newdict = json.loads(receiveclient1)
receiveclient1 is an empty string, which explains the error.
You should instead build receiveclient1 from the data fragments:
receiveclient1 = ''
while True:
print('Connection from', addr)
data = conn.recv(1024).decode("utf-8")
if not data:
break
receiveclient1 += data
newdict = json.loads(receiveclient1)
New in python, I am reading JSON object from the server, size of JSON object is not fix. I am getting data from the server as per the buffer size given in socket.recv(1024). How to check that JSON object from server-socket received is full/complete, Because while parsing that JSON I am getting an error.
Please note that my JSON object is not nested.
**** Sample code ****
def get_data():
s = socket.socket()
host = 'IP_Address'
port = 'Port_Number'
# connection to hostname on the port.
s.connect((host, port))
msg=''
while(True):
msg = s.recv(1024)
print(msg.decode('ascii'))
jsonObject=json.loads(msg.decode('ascii'))
s.close()
Below is the error
Traceback (most recent call last):
File "d:/xxxxxxxxxxxxx/Python_Test.py", line 26, in <module>
get_data()
File "d:/xxxxxxxxxxxxx/Python_Test.py", line 20, in get_data
temp=json.loads(msg.decode('ascii'))
File "xxxxxxxxxxxxx\Python\Python37\lib\json\__init__.py", line 348, in loads
return _default_decoder.decode(s)
File "xxxxxxxxxxxxx\Python\Python37\lib\json\decoder.py", line 340, in decode
raise JSONDecodeError("Extra data", s, end)
json.decoder.JSONDecodeError: Extra data: line 2 column 1 (char 777)
You recieve 1024 bytes in every loop and if your json object is bigger than that you have to handle uncompleted json string.
Also you may have two json object in 1024 bytes or even more. you can change your code to below code
def get_data():
s = socket.socket()
host = 'IP_Address'
port = 'Port_Number'
s.connect((host, port))
msg=''
while True:
r = s.recv(1024)
msg += r.decode('ascii')
while True:
start = msg.find("{")
end = msg.find("}")
if start==-1 or end==-1: # if can not find both { and } in string
break
jsonObject=json.loads(msg[start:end+1]) # only read { ... } and not another uncompleted data
# do whatever you want with jsonObject here
msg = msg[end+1:]
s.close()
NOTE : this code work correct only if you have not any nested json in your data (like this: {"device_id": {"another_json": "something"}})
You need to wait till the complete json is received and then parse it, something like this should work:
msg = ''
while(True):
response = s.recv(1024)
if not response:
break
msg += response
jsonObject=json.loads(msg.decode('ascii'))
Working on a script to poll a smart plug and parse the json response for further use.
This works perfectly:
while True:
try:
ip = "192.168.1.130"
port = 9999
sock_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock_tcp.connect((ip, port))
cmd_emeter = commands['emeter']
sock_tcp.send(encrypt(cmd_emeter))
data_emeter = sock_tcp.recv(2048)
sock_tcp.close()
# decrypt, parse, and relay emeter response
emeter = decrypt(data_emeter[4:])
parsed_json_emeter = json.loads(emeter)
voltage = parsed_json_emeter['emeter']['get_realtime']['voltage']
power = parsed_json_emeter['emeter']['get_realtime']['power']
print voltage
print power
publish.single("myHome/smartplug1/voltage", voltage, hostname="192.168.1.120")
publish.single("myHome/smartplug1/power", power, hostname="192.168.1.120")
time.sleep(5)
except socket.error:
quit("Cound not connect to host " + ip + ":" + str(port))
This does not:
while True:
try:
ip = "192.168.1.130"
port = 9999
sock_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock_tcp.connect((ip, port))
cmd_emeter = commands['emeter']
sock_tcp.send(encrypt(cmd_emeter))
data_emeter = sock_tcp.recv(2048)
cmd_info = commands['info']
sock_tcp.send(encrypt(cmd_info))
data_info = sock_tcp.recv(2048)
#cmd_daystats = commands['daystats']
#sock_tcp.send(encrypt(cmd_daystats))
#data_daystats = sock_tcp.recv(2048)
sock_tcp.close()
# decrypt, parse, and relay emeter response
emeter = decrypt(data_emeter[4:])
parsed_json_emeter = json.loads(emeter)
voltage = parsed_json_emeter['emeter']['get_realtime']['voltage']
power = parsed_json_emeter['emeter']['get_realtime']['power']
print voltage
print power
publish.single("myHome/smartplug1/voltage", voltage, hostname="192.168.1.120")
publish.single("myHome/smartplug1/power", power, hostname="192.168.1.120")
# decrypt, parse, and relay info response
info = decrypt(data_info[4:])
parsed_json_info = json.loads(info)
relay_state = parsed_json_info['system']['get_sysinfo']['relay_state']
print relay_state
#publish.single("myHome/smartplug1/voltage", voltage, hostname="192.168.1.120")
#publish.single("myHome/smartplug1/power", power, hostname="192.168.1.120")
time.sleep(5)
except socket.error:
quit("Cound not connect to host " + ip + ":" + str(port))
I need help figuring out why. Perhaps some sort of buffer issue with the sock_tcp.recv(2048) lines.
Here is the error message:
pi#raspberrypi:/usr/share/openhab/scripts $ python HS110-relay.py
119.622975
0
Traceback (most recent call last):
File "HS110-relay.py", line 89, in <module>
parsed_json_info = json.loads(info)
File "/usr/lib/python2.7/json/__init__.py", line 338, in loads
return _default_decoder.decode(s)
File "/usr/lib/python2.7/json/decoder.py", line 366, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python2.7/json/decoder.py", line 384, in raw_decode
raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded
Thanks.
Baobab
Stack Overflow gods I ask for your mercy...
my error: ^[[A?????????????????????????????????????????q????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????c?????????????????????????????????????,23:24:05,01/06/2015,ourfleet
Traceback (most recent call last):
File "ourfleet.py", line 33, in <module>
result = requests.post(firebase_url + '/' + gps_location + '/gps_c.json'+ auth_token, data=json.dumps(data))
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 243, in dumps
return _default_encoder.encode(obj)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 207, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 270, in iterencode
return _iterencode(o, 0)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xff in position 0: invalid start byte
I am passing GPS data through serial from an arduino uno. This is UTF-8? Why is this happening?
My Arduino code:
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
/*
This sample sketch demonstrates the normal use of a TinyGPS++ (TinyGPSPlus) object.
It requires the use of SoftwareSerial, and assumes that you have a
4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/
static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;
// The TinyGPS++ object
TinyGPSPlus gps;
// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
void setup()
{
Serial.begin(115200);
ss.begin(GPSBaud);
}
void loop()
{
// This sketch displays information every time a new sentence is correctly encoded.
while (ss.available() > 0)
if (gps.encode(ss.read()))
displayInfo();
if (millis() > 5000 && gps.charsProcessed() < 10)
{
while(true);
}
}
void displayInfo()
{
Serial.print(gps.location.lat(), 6);
Serial.print(F(","));
Serial.print(gps.location.lng(), 6);
Serial.println();
}
My Python code that sends the data through https. I am also getting an error that is saying the connection is not https and, instead, it is http. I have tried to update my Python libraries using pip etc etc to no avail. I am using an 07 MacBook pro)
import serial
import time
import requests
import json
firebase_url = 'https://ourfleet.firebaseio.com'
auth_token = '0sBNZjz4uQvLteDoCZTDUD3RNOT852aKyqahGzl4'
#Connect to Serial Port for communication
ser = serial.Serial('/dev/tty.wchusbserial410', 9600, timeout=0)
#Setup a loop to send GPS values at fixed intervals
#in seconds
fixed_interval = 10
while 1:
try:
#GPS value obtained from Arduino + Ublox
gps_c = ser.readline()
#current time and date
time_hhmmss = time.strftime('%H:%M:%S')
date_mmddyyyy = time.strftime('%d/%m/%Y')
#current location name
gps_location = 'ourfleet'
print gps_c + ',' + time_hhmmss + ',' + date_mmddyyyy + ',' + gps_location
#insert record
data = {'date':date_mmddyyyy,'time':time_hhmmss,'location':gps_c}
result = requests.post(firebase_url + '/' + gps_location + '/gps_c.json'+ auth_token, data=json.dumps(data))
#insert record
print 'Record inserted. Result Code = ' + str(result.status_code) + ',' + result.text
time.sleep(fixed_interval)
except IOError:
print('Error! Something went wrong.')
time.sleep(fixed_interval)
I am lacking the know how on this subject to modify my programs accordingly.
In your Python code, the first character of the data being read from the serial port is '\xff' in which case json.dumps() will throw the exception shown:
>>> json.dumps({'gps_c': '\xffblah'})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python2.7/json/__init__.py", line 243, in dumps
return _default_encoder.encode(obj)
File "/usr/lib64/python2.7/json/encoder.py", line 207, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/lib64/python2.7/json/encoder.py", line 270, in iterencode
return _iterencode(o, 0)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xff in position 0: invalid start byte
The data read from the serial port looks corrupted - it should be 14 bytes long (6 lat + 6 lon + ',' + '\n'), however, the data printed shows that it is far longer than that.
I suspect that the baud rates are not properly matched. In your C/C++ code you set one port to 155200 and another (SoftwareSerial) to 9600. The Python code expects 9600. Are you sure that you have configured the correct speeds?
My python script is searching thought google pages for specific things. Like paths in url for example. Here is my code
import urllib2
import urllib
import json
def search(target):
num_queries = 50 * 4
for start in range(0, num_queries, 4):
dork = 'intext: hacking'
dork = urllib.urlencode({'q' : dork})
url = 'http://ajax.googleapis.com/ajax/services/search/web?v=1.0&%s' % dork
for start in range(0, num_queries, 4):
request_url = '{0}&start={1}'.format(url, start)
search_results = urllib.urlopen(request_url)
#try:
j = json.loads(search_results.read())
#except ValueError:
#print "Error: "
#continue
results = j['responseData']['results']
for result in results:
title = result['title']
url = result['url']
if target in url:
print ( '[*]' + url )
def main():
target = raw_input("Enter target >> ")
search(target)
if __name__ == "__main__":
main()
After the 3rd result I'm getting No JSON object could be decoded. Here is the whole error:
Enter target >> .com
[*]some site
[*]some site
[*]some site
Traceback (most recent call last):
File "gs.py", line 32, in <module>
main()
File "gs.py", line 28, in main
search(target)
File "gs.py", line 15, in search
j = json.loads(search_results.read())
File "/usr/lib/python2.7/json/__init__.py", line 326, in loads
return _default_decoder.decode(s)
File "/usr/lib/python2.7/json/decoder.py", line 365, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python2.7/json/decoder.py", line 383, in raw_decode
raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded
Any idea from where the error is coming and how to fix it?
You're overwriting url with the returned value.
Under results:
url = result['url']
Then it loops back to the top:
request_url = '{0}&start={1}'.format(url, start)
This is probably due to the extra loop. Try this, without the extra loop:
def search(target):
num_queries = 50 * 4
for start in range(0, num_queries, 4):
dork = 'intext: hacking'
dork = urllib.urlencode({'q' : dork})
url = 'http://ajax.googleapis.com/ajax/services/search/web?v=1.0&%s' % dork
request_url = '{0}&start={1}'.format(url, start)
search_results = urllib.urlopen(request_url)
#try:
j = json.loads(search_results.read())
#except ValueError:
#print "Error: "
#continue
results = j['responseData']['results']
for result in results:
title = result['title']
url = result['url']
if target in url:
print ( '[*]' + url )