I was working on a project in Python using sockets when I ran into this client-side error:
Traceback (most recent call last):
File "client.py", line 384, in <module>
socket_event = json.loads(data)
File "/home/user/anaconda3/lib/python3.7/json/__init__.py", line 348, in loads
return _default_decoder.decode(s)
File "/home/user/anaconda3/lib/python3.7/json/decoder.py", line 340, in decode
raise JSONDecodeError("Extra data", s, end)
json.decoder.JSONDecodeError: Extra data: line 1 column 145 (char 144)
This usually occurs when my computer is running slowly, but occasionally it will happen when I have nothing else open other than the terminal and the scripts (server script and the client script). I printed out the data sent before json attempted to decode it.
This is what I got:
{"player locations": [[1, 232, 78, true, "one", false], [2, 234, 113, false, "two", false]], "mini-update": [[["one", 51], ["two", 47]], false]}{"player locations": [[1, 232, 78, true, "one", false], [2, 234, 113, false, "two", false]], "mini-update": [[["one", 51], ["two", 47]], false]}
but this is what I was expecting to get:
{"player locations": [[1, 232, 78, true, "one", false], [2, 234, 113, false, "two", false]], "mini-update": [[["one", 51], ["two", 47]], false]}
I think this is happens when the server is running faster than the client and the server sends data twice before the client could read the data.
Here is my client receiving code:
ins, outs, ex = select.select([n.socket], [], [], 0)
for in_ in ins:
data = in_.recv(2048)
print(data.decode() + "\n")
if data:
socket_event = json.loads(data)
event_types = [key for key in socket_event.keys()]
for event_type in event_types:
event_data_lst = socket_event[event_type]
if event_type == 'id update':
client.id = event_data_lst
and here is my server sending code:
update = {'player locations':[],"mini-update":[]} # Empty update dict
# Looping over every connected player to send to the selected client. Used for changes to the player's position or look.
# (by "look", I mean the flip value which flips the player's image, and the hit value which changes the player img's hue)
score_update_lst = []
for key, value in playermap.items():
# key is the player's id
# value[0][0] is the player's x position
# value[0][1] is the player's y position
# value[1] is the player's flip value
# value[2] is the player's name
# value[3] is the player's attacker pos value (stores the position of the attacker if hit)
# value[4] is the player's been_hit value (used for the player flash when hit)
# value[5] is the player's score value (used for minigames)
update['player locations'].append([key, value[0][0], value[0][1], value[1], value[2], value[4]])
score_update_lst.append([value[2],value[5]])
update["mini-update"].append(score_update_lst)
# Knockback stuff. If the player has been hit, the position of the attacker will be stored at playermap[playerid][3].
# If there is data there, the code in the if statement is excuted
if playermap[playerid][3]:
update['mini-update'].append(playermap[playerid][3])
playermap[playerid][3] = False
else:
update['mini-update'].append(False)
# Sending the data to the client, but if there is a error, the client socket is removed
try:
#print(json.dumps(update).encode())
target_socket.sendall(json.dumps(update).encode())
except Exception as e:
print(e)
def client_thread(conn, player_id):
while True:
try:
recvdata = conn.recv(bufsize) # Get data from client
if recvdata:
update_client(recvdata, conn) # Update the client
print(playermap)
recvdata = False
else:
break
except Exception as e:
print(e)
break
Every time a client connects, a new client thread is started that uses the client_thread
function.
If you have any questions or require extra information, feel free to ask. With this information, does anyone know why data might be being sent twice?