Jam3sn
Jam3sn

Reputation: 1087

Receiving data with sockets adding characters

I'm writing a mod for a game to allow me to use a second screen with a set of stats. Now I send the data and receive, however there's extra characters when I receive the data, such as , ' ). This is causing issue's preventing me to create an int variable. I've tried stripping these characters but still having problems. This is the error spat out: ValueError: invalid literal for int(*) with base 10: "(0'"

Here's what i'm sending:

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = '192.168.0.2'
port = 9000
s.bind((host,port))
s.listen(5)
conn, addr = s.accept()
print ('Got connection from', addr)
while True:

#--- RPM --
    rpm = info.physics.rpms
    max_rpm = info.static.maxRpm
    if rpm != 0:
        rpm_percent = int(rpm/max_rpm*100)
    else:
        rpm_percent = 0

#--- SPEED ---
    speed = int(info.physics.speedKmh/1.609344)

#--- GEAR ---
    gear = info.physics.gear - 1
    if gear == 0:
        gear = str("N")
    elif gear < 0:
        gear = str("R")

#--- FUEL ---
    fuel = info.physics.fuel
    max_fuel = info.static.maxFuel
    if fuel != 0:
        fuel_percent = int(fuel/max_fuel*100)
    else:
        fuel_percent = 0

#--- BRAKING ---
    brake = info.physics.brake
    braking_lvl = int(brake/100*10000)

#--- LAP ---
    current_time = info.graphics.currentTime

#--- SEND DATA ---
    time.sleep(.1)
    #print_data = 'Speed: ', speed, 'RPM: ', rpm_percent, 'Gear: ', gear, 'Braking: ', braking_lvl, 'Fuel: ', fuel, fuel_percent,'Lap Time: ', current_time
    send_data = (speed, ';', rpm, ';', rpm_percent, ';', gear, ';', braking_lvl, ';', fuel, ';', fuel_percent)
    conn.send(str(send_data).encode('ascii'))
    print(send_data)
s.close()

And on the client, which has the errors:

data = s.recv(1024).decode('ascii').replace(' ', '').replace("'", '').replace(')', '').replace(',', '')
data = data.split(';')
speed = int(data[0])
rpm = int(data[1])
rpm_percentage = int(data[2])
gear = str(data[3])
breaking_lvl = int(data[4])
fuel = int(data[5])
fuel_percentage= int(data[6])

Why is it seeing these extra characters? And what's the most effective method to remove them / prevent them?

Cheers.

Upvotes: 0

Views: 1014

Answers (2)

jfs
jfs

Reputation: 414079

send_data is a tuple. If you call str(); it returns its string representation '(item, item)'. To read it back you would need eval() or ast.literal_eval() (in simple cases). You could use json format instead.

On the server:

sock.sendall(json.dumps(data).encode('utf-8')) 

On the client (assuming the connection is closed after receiving the response from the server):

response = []
while True:
    chunk = sock.recv(1024)
    if not chunk: # EOF
       break
    response.append(chunk)
data = json.loads(b"".join(response).decode('utf-8'))

Upvotes: 1

ravenspoint
ravenspoint

Reputation: 20457

You need to check how much data you receive, and ensure that the string is null terminated at the end of the data that was received, otherwise you will be parsing random data.

For reliability, you should send a fixed length message that tells the client how much data to expect. Then the client can ensure that it receives all the data sent, and no more.

Upvotes: 0

Related Questions