thiezn / iperf3-python

Python wrapper around iperf3
https://iperf3-python.readthedocs.org/
MIT License
109 stars 52 forks source link

If I assign output to variable there is a JSON decode error. #43

Closed machoog546 closed 5 years ago

machoog546 commented 5 years ago

When running the code below if I don't assign the client.run() to a variable it will print to screen like normal. If I assign to a variable to parse it/print later I get the below error.

import iperf3, time, threading

def client():

    print("starting client")
    client = iperf3.Client()
    client.Duration = 4
    client.bind_address="192.168.200.10"
    client.server_hostname='192.168.200.20'
    client.port=6969
    time.sleep(2) #used to make sure server is up and ready
    result = client.run()
    #print(type(result))

    return result

def server():
    server = iperf3.Server()
    server.bind_address='192.168.200.20'
    server.port=6969
    print("starting server")
    server.run()
    print("server done")
    #if you see the server stating and ending quickly. the ip/port is already bound?

c = threading.Thread(target=client)
t = threading.Thread(target=server)
t.setDaemon=True

t.start()
c.start()

Error:

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.5/threading.py", line 862, in run
    self._target(*self._args, **self._kwargs)
  File "iperf3Client.py", line 12, in client
    result = client.run()
  File "/usr/local/lib/python3.5/dist-packages/iperf3/iperf3.py", line 617, in run
    return TestResult(data)
  File "/usr/local/lib/python3.5/dist-packages/iperf3/iperf3.py", line 768, in __init__
    self.json = json.loads(result)
  File "/usr/lib/python3.5/json/__init__.py", line 319, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.5/json/decoder.py", line 342, in decode
    raise JSONDecodeError("Extra data", s, end)
json.decoder.JSONDecodeError: Extra data: line 310 column 1 (char 6530)

Could it be it's seeing an extra character at the start of the list when it does the JSON formatting and it errors out? I know just enough about the JSON to get myself in trouble.

I also changed my json_output=False like in #38 but that causes it to hang. Was hoping for the NoneType, or for something different, but it wasn't the different I was expecting.

Linux machoog546-virtual-machine 4.10.0-38-generic #42~16.04.1-Ubuntu SMP Tue Oct 10 16:32:20 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

machoog546 commented 5 years ago

Side thing I just tried. If I run both functions as their own scripts it prints out with no error. Might be threading related?

machoog546 commented 5 years ago

After some more tinkering I changed multi threading to multi processing in a test VM and it worked. Still not sure why it had the issue in the first place.

import iperf3, time import multiprocessing as mp

def client_side(cli, serv, port, YesNo):

if YesNo:
    f = open("port_" + str(port) + ".txt", "w+")

traffic=iperf3.Client()
traffic.duration=90
traffic.bind_address=cli
traffic.server_hostname = serv
traffic.port=port
traffic.bandwidth = 180000000
result = traffic.run()
time.sleep(2)

if YesNo:
    result = str(result)
    time.sleep(1)

    f.write(result)
    f.close() #Not needed but i want to make sure it saves

clients = [6969, 6970,6971,6971] #not needed. can be put in the args space of the MP call

threads =[] print("starting") c1 = mp.Process(target=client_side, args=("192.168.201.10", "192.168.201.20", clients[0], True,))#, daemon = True) threads.append(c1) c2 = mp.Process(target=client_side, args=("192.168.202.10", "192.168.202.20", clients[1], True,))#, daemon = True) threads.append(c2) c3 = mp.Process(target=client_side, args=("192.168.203.10", "192.168.203.20", clients[2], True,))#, daemon = True) threads.append(c3) c4 = mp.Process(target=client_side, args=("192.168.204.10", "192.168.204.20", clients[3], True,))#, daemon = True) threads.append(c4)

print(threads) for thread in threads: print("Starting " + str(thread)) thread.start() time.sleep(2)

for thread in threads:

thread.join()
time.sleep(1)

print("Complete")