client.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. #!/usr/bin/env python
  2. import socket
  3. import select
  4. import random
  5. import subprocess
  6. import time
  7. import re
  8. import peerfinder_pb2 as pf
  9. SERVER = ("::1", 9999)
  10. # In seconds
  11. HEARTBEAT_INTERVAL = random.randint(5, 15)
  12. RECONNECT_INTERVAL = random.randint(5, 15)
  13. NB_PINGS = 3
  14. ping_regexp = re.compile(r"time=(.*) ms")
  15. def ping(target, nb_pings=NB_PINGS):
  16. """Returns the list of latencies towards the given target"""
  17. args = ["ping", "-n", "-c", str(nb_pings), str(target.address)]
  18. try:
  19. out = subprocess.check_output(args, shell=False)
  20. except subprocess.CalledProcessError:
  21. return []
  22. data = out.decode("utf8").split("\n")
  23. data = [ping_regexp.search(line) for line in data]
  24. return [float(m.group(1)) for m in data if m != None]
  25. def run_measurements(s):
  26. while True:
  27. try:
  28. data = s.recv(1024)
  29. print(data)
  30. if len(data) == 0:
  31. s.close()
  32. return
  33. msg = pf.Message()
  34. msg.ParseFromString(data)
  35. if msg.type == pf.Message.Pong:
  36. print("Got pong")
  37. else:
  38. target = msg.target
  39. latencies = ping(target.target)
  40. reply = pf.Message()
  41. reply.type = pf.Message.Measurement
  42. reply.measurement.target_id = msg.target.target_id
  43. reply.measurement.probes_sent = NB_PINGS
  44. reply.measurement.probes_received = len(latencies)
  45. reply.measurement.latency_us.extend([int(1000 * l) for l in latencies])
  46. # Debug
  47. #time.sleep(random.randint(1, 5))
  48. print("Sending results")
  49. s.send(reply.SerializeToString())
  50. except socket.timeout:
  51. pass
  52. #print("Not sending heartbeat")
  53. #msg = pf.Message()
  54. #msg.type = pf.Message.Ping
  55. #s.send(msg.SerializeToString())
  56. except ConnectionResetError:
  57. s.close()
  58. return
  59. if __name__ == '__main__':
  60. while True:
  61. sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
  62. sock.settimeout(HEARTBEAT_INTERVAL)
  63. try:
  64. sock.connect(SERVER)
  65. print("Connected to {}".format(SERVER))
  66. run_measurements(sock)
  67. except ConnectionRefusedError:
  68. pass
  69. print("Disconnected, reconnecting in {} seconds".format(RECONNECT_INTERVAL))
  70. time.sleep(RECONNECT_INTERVAL)