socket_download.py 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. import socket
  2. import time
  3. def http_download_file(url: str, file_path: str, buff_size=1024):
  4. # Parse the URL to extract the host and path
  5. if not url.startswith('http://'):
  6. print("Only HTTP protocol is supported")
  7. return -1
  8. host = url.split("//")[1].split('/')[0]
  9. path = url[url.find(host) + len(host):]
  10. if len(path) == 0:
  11. path = "/"
  12. print("Host:", host)
  13. print("Path:", path)
  14. # Establish a socket connection
  15. try:
  16. sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  17. sock.connect((host, 80))
  18. print("Connected to:", host)
  19. except Exception as e:
  20. print("Connection error:", e)
  21. return -1
  22. # Send HTTP GET request
  23. get_request = "GET " + path + " HTTP/1.1\r\nHost: " + \
  24. host + "\r\nConnection: close\r\n\r\n"
  25. sock.send(get_request.encode())
  26. # Open file to write
  27. f = open(file_path, 'wb') # Manually open the file
  28. data_received = False
  29. head_received = False
  30. while True:
  31. try:
  32. data = sock.recv(buff_size)
  33. except:
  34. print('End of data')
  35. break
  36. print("[Data received:", len(data), ']')
  37. if head_received:
  38. sz = f.write(data)
  39. # print("Data written:", sz)
  40. # print(data.decode())
  41. if len(data) == 0:
  42. print("Length of data:", len(data))
  43. if not data_received:
  44. print("No data received.")
  45. f.close()
  46. return -1
  47. print("No more data to receive")
  48. break
  49. data_received = True
  50. # Handle the end of the HTTP header if it's still present
  51. if head_received == False:
  52. if b'\r\n\r\n' in data:
  53. # print("Header received", data)
  54. head_received = True
  55. aplited = data.split(b'\r\n\r\n', 1)
  56. if len(aplited) == 2:
  57. sz = f.write(aplited[1])
  58. # Close file and socket manually
  59. f.close()
  60. sock.close()
  61. print("Download completed")
  62. return 0
  63. assert http_download_file("http://pikapython.com", "pikapython.html") == 0
  64. print("PASS")