throughput_protocols.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #!/usr/bin/python3
  2. #
  3. import basic_protocols
  4. import logging
  5. import enum
  6. import time
  7. import socket
  8. #
  9. class ClientProtocol(basic_protocols.Protocol):
  10. def __init__(self, endpoint, total_bytes, proxy=None, username=None, wait_until=None, send_buffer_len=None, use_acceleration=None):
  11. self.endpoint = endpoint
  12. self.total_bytes = total_bytes
  13. self.proxy = proxy
  14. self.username = username
  15. self.wait_until = wait_until
  16. self.send_buffer_len = send_buffer_len
  17. self.use_acceleration = use_acceleration
  18. #
  19. self.states = enum.Enum('CLIENT_CONN_STATES', 'READY_TO_BEGIN CONNECT_TO_PROXY SEND_GROUP_ID PUSH_DATA DONE')
  20. self.state = self.states.READY_TO_BEGIN
  21. #
  22. self.socket = socket.socket()
  23. self.sub_protocol = None
  24. self.group_id = int(self.wait_until*1000) if self.wait_until is not None else 0
  25. # a group id of 0 means no group
  26. #
  27. if self.proxy is None:
  28. logging.debug('Socket %d connecting to endpoint %r...', self.socket.fileno(), self.endpoint)
  29. self.socket.connect(self.endpoint)
  30. else:
  31. logging.debug('Socket %d connecting to proxy %r...', self.socket.fileno(), self.proxy)
  32. self.socket.connect(self.proxy)
  33. #
  34. #
  35. def _run_iteration(self, block=True):
  36. if self.state is self.states.READY_TO_BEGIN:
  37. if self.proxy is None:
  38. group_id_bytes = self.group_id.to_bytes(8, byteorder='big', signed=False)
  39. self.sub_protocol = basic_protocols.SendDataProtocol(self.socket, group_id_bytes)
  40. self.state = self.states.SEND_GROUP_ID
  41. else:
  42. self.sub_protocol = basic_protocols.Socks4Protocol(self.socket, self.endpoint, username=self.username)
  43. self.state = self.states.CONNECT_TO_PROXY
  44. #
  45. #
  46. if self.state is self.states.CONNECT_TO_PROXY:
  47. if self.sub_protocol.run(block=block):
  48. group_id_bytes = self.group_id.to_bytes(8, byteorder='big', signed=False)
  49. self.sub_protocol = basic_protocols.SendDataProtocol(self.socket, group_id_bytes)
  50. self.state = self.states.SEND_GROUP_ID
  51. #
  52. #
  53. if self.state is self.states.SEND_GROUP_ID:
  54. if block and self.wait_until is not None:
  55. time.sleep(self.wait_until-time.time())
  56. #
  57. if (self.wait_until is None or time.time() >= self.wait_until) and self.sub_protocol.run(block=block):
  58. self.sub_protocol = basic_protocols.PushDataProtocol(self.socket, self.total_bytes,
  59. send_buffer_len=self.send_buffer_len,
  60. use_acceleration=self.use_acceleration)
  61. self.state = self.states.PUSH_DATA
  62. #
  63. #
  64. if self.state is self.states.PUSH_DATA:
  65. if self.sub_protocol.run(block=block):
  66. self.state = self.states.DONE
  67. return True
  68. #
  69. #
  70. return False
  71. #
  72. #
  73. class ServerProtocol(basic_protocols.Protocol):
  74. def __init__(self, socket, conn_id, group_id_callback=None, bandwidth_callback=None, use_acceleration=None):
  75. self.socket = socket
  76. self.conn_id = conn_id
  77. self.group_id_callback = group_id_callback
  78. self.bandwidth_callback = bandwidth_callback
  79. self.use_acceleration = use_acceleration
  80. #
  81. self.states = enum.Enum('SERVER_CONN_STATES', 'READY_TO_BEGIN RECV_GROUP_ID PULL_DATA DONE')
  82. self.state = self.states.READY_TO_BEGIN
  83. #
  84. self.sub_protocol = None
  85. #
  86. def _run_iteration(self, block=True):
  87. if self.state is self.states.READY_TO_BEGIN:
  88. self.sub_protocol = basic_protocols.ReceiveDataProtocol(self.socket)
  89. self.state = self.states.RECV_GROUP_ID
  90. #
  91. if self.state is self.states.RECV_GROUP_ID:
  92. if self.sub_protocol.run(block=block):
  93. group_id = int.from_bytes(self.sub_protocol.received_data, byteorder='big', signed=False)
  94. if group_id == 0:
  95. # a group of 0 means no group
  96. group_id = None
  97. #
  98. self.group_id_callback(self.conn_id, group_id)
  99. self.sub_protocol = basic_protocols.PullDataProtocol(self.socket, use_acceleration=self.use_acceleration)
  100. self.state = self.states.PULL_DATA
  101. #
  102. #
  103. if self.state is self.states.PULL_DATA:
  104. if self.sub_protocol.run(block=block):
  105. self.state = self.states.DONE
  106. if self.bandwidth_callback:
  107. self.bandwidth_callback(self.conn_id, self.sub_protocol.data_size, self.sub_protocol.calc_transfer_rate())
  108. #
  109. return True
  110. #
  111. #
  112. return False
  113. #
  114. #