You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

76 lines
2.4 KiB

  1. import argparse
  2. import math
  3. import os
  4. import socket
  5. IP_ADDR = "0.0.0.0"
  6. MSS = 24000 # MSS = Server buffer size (20480) - data header size (4)
  7. def await_ack(packet, addr):
  8. s.settimeout(1)
  9. while True:
  10. try:
  11. data, addr = s.recvfrom(MSS)
  12. return (data, addr)
  13. except KeyboardInterrupt:
  14. print("Server: Exiting...")
  15. exit()
  16. except socket.timeout:
  17. print("Server: Retransmitting...")
  18. s.sendto(packet, addr)
  19. if __name__ == "__main__":
  20. parser = argparse.ArgumentParser()
  21. parser.add_argument("port", type=str)
  22. args = parser.parse_args()
  23. server_port = args.port
  24. server_port = int(server_port)
  25. with socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM) as s:
  26. s.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 30000)
  27. s.bind((IP_ADDR, server_port))
  28. print(f'Listening on {IP_ADDR}:{server_port}...')
  29. data, addr = s.recvfrom(MSS)
  30. columns = data.decode('utf-8', 'replace').split('|')
  31. print(columns)
  32. if os.path.isfile(f'./{columns[2]}'):
  33. print(f'file {columns[2]} exists. Overwriting...')
  34. f = open(columns[2], 'wb')
  35. if columns[0] == 's':
  36. message = f'a|{(int(columns[1])+1)%2}'
  37. s.sendto(message.encode(), addr)
  38. data, addr = await_ack(message.encode(), addr)
  39. bytes_received = 0
  40. last = b'0'
  41. while bytes_received < int(columns[3]):
  42. new_columns = data.split(b'|')
  43. if new_columns[0] != b'd':
  44. data, addr = await_ack(message.encode(), addr)
  45. continue
  46. if new_columns[1] == last:
  47. data, addr = await_ack(message.encode(), addr)
  48. continue
  49. last = new_columns[1]
  50. bindata = new_columns[2]
  51. for i in new_columns[3:]:
  52. bindata = bindata + (b'|') + i
  53. f.write(bindata)
  54. bytes_received += len(bindata)
  55. print(f'Received: {bytes_received}/{columns[3]}')
  56. message = f'a|{(int(new_columns[1])+1)%2}'
  57. s.sendto(message.encode(), addr)
  58. data, addr = await_ack(message.encode(), addr)
  59. print(f'file {columns[2]} was successfully uploaded. Exiting...')
  60. else:
  61. exit(1)