throughput_server.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #!/usr/bin/python3
  2. #
  3. import throughput_protocols
  4. import basic_protocols
  5. import os
  6. import multiprocessing
  7. import queue
  8. import logging
  9. import argparse
  10. #
  11. if __name__ == '__main__':
  12. logging.basicConfig(level=logging.DEBUG)
  13. #
  14. parser = argparse.ArgumentParser(description='Test the network throughput (optionally through a proxy).')
  15. parser.add_argument('port', type=int, help='listen on port')
  16. parser.add_argument('--no-accel', action='store_true', help='don\'t use C acceleration (use pure Python)')
  17. parser.add_argument('--localhost', action='store_true', help='bind to 127.0.0.1 instead of 0.0.0.0')
  18. args = parser.parse_args()
  19. #
  20. if args.localhost:
  21. endpoint = ('127.0.0.1', args.port)
  22. else:
  23. endpoint = ('0.0.0.0', args.port)
  24. #
  25. processes = []
  26. processes_map = {}
  27. joinable_connections = multiprocessing.Queue()
  28. conn_counter = [0]
  29. group_queue = multiprocessing.Queue()
  30. bw_queue = multiprocessing.Queue()
  31. #
  32. def group_id_callback(conn_id, group_id):
  33. # put them in a queue to display later
  34. #logging.debug('For conn %d Received group id: %d', conn_id, group_id)
  35. group_queue.put({'conn_id':conn_id, 'group_id':group_id})
  36. #
  37. def bw_callback(conn_id, data_size, time_first_byte, time_last_byte, transfer_rate):
  38. # put them in a queue to display later
  39. bw_queue.put({'conn_id':conn_id, 'data_size':data_size, 'time_of_first_byte':time_first_byte, 'time_of_last_byte':time_last_byte, 'transfer_rate':transfer_rate})
  40. #
  41. def start_server_conn(socket, conn_id):
  42. server = throughput_protocols.ServerProtocol(socket, conn_id, group_id_callback=group_id_callback,
  43. bandwidth_callback=bw_callback, use_acceleration=(not args.no_accel))
  44. try:
  45. server.run()
  46. except KeyboardInterrupt:
  47. socket.close()
  48. finally:
  49. joinable_connections.put(conn_id)
  50. #
  51. #
  52. def accept_callback(socket):
  53. conn_id = conn_counter[0]
  54. conn_counter[0] += 1
  55. #logging.debug('Adding connection %d', conn_id)
  56. p = multiprocessing.Process(target=start_server_conn, args=(socket, conn_id))
  57. processes.append(p)
  58. processes_map[conn_id] = p
  59. p.start()
  60. socket.close()
  61. # close this process' copy of the socket
  62. #
  63. l = basic_protocols.ServerListener(endpoint, accept_callback)
  64. #
  65. try:
  66. while True:
  67. l.accept()
  68. try:
  69. while True:
  70. conn_id = joinable_connections.get(False)
  71. p = processes_map[conn_id]
  72. p.join()
  73. #
  74. except queue.Empty:
  75. pass
  76. #
  77. #
  78. except KeyboardInterrupt:
  79. print()
  80. #
  81. bw_values = {}
  82. group_values = {}
  83. #
  84. try:
  85. while True:
  86. bw_val = bw_queue.get(False)
  87. bw_values[bw_val['conn_id']] = bw_val
  88. #
  89. except queue.Empty:
  90. pass
  91. #
  92. try:
  93. while True:
  94. group_val = group_queue.get(False)
  95. group_values[group_val['conn_id']] = group_val
  96. #
  97. except queue.Empty:
  98. pass
  99. #
  100. group_set = set([x['group_id'] for x in group_values.values()])
  101. for group in group_set:
  102. # doesn't handle group == None
  103. conns_in_group = [x[0] for x in group_values.items() if x[1]['group_id'] == group]
  104. in_group = [x for x in bw_values.values() if x['conn_id'] in conns_in_group]
  105. if len(in_group) > 0:
  106. avg_data_size = sum([x['data_size'] for x in in_group])/len(in_group)
  107. avg_transfer_rate = sum([x['transfer_rate'] for x in in_group])/len(in_group)
  108. total_transfer_rate = sum([x['data_size'] for x in in_group])/(max([x['time_of_last_byte'] for x in in_group])-min([x['time_of_first_byte'] for x in in_group]))
  109. #
  110. logging.info('Group size: %d', len(in_group))
  111. logging.info('Avg Transferred (MB): %.4f', avg_data_size/(1024**2))
  112. logging.info('Avg Transfer rate (MB/s): %.4f', avg_transfer_rate/(1024**2))
  113. logging.info('Total Transfer rate (MB/s): %.4f', total_transfer_rate/(1024**2))
  114. #
  115. #
  116. #
  117. for p in processes:
  118. p.join()
  119. #
  120. #