ssdp_server.py 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. import socket
  4. SSDP_ADDR = '239.255.255.250'
  5. SSDP_PORT = 1900
  6. SERVICE_NAME = "urn:rt-thread:service:ssdp"
  7. class Connection():
  8. def __init__(self, s, data, addr):
  9. self.__s = s
  10. self.__data = data
  11. self.__addr = addr
  12. self.is_find_service = False
  13. def handle_request(self):
  14. if self.__data.startswith('NOTIFY * HTTP/1.1\r\n'):
  15. self.__handle_notify()
  16. def __handle_notify(self):
  17. props = self.__parse_props(['HOST'])
  18. if isinstance(props, dict):
  19. if props.has_key('NT') and props['NT'] == SERVICE_NAME:
  20. print("NT : %s"%props['NT'])
  21. print("SM_ID : %s"%props['SM_ID'])
  22. print("DEV_TYPE : %s"%props['DEV_TYPE'])
  23. print("USN : %s"%props['USN'])
  24. print("HOST : %s"%props['HOST'])
  25. print("LOCATION : %s\r\n"%props['LOCATION'])
  26. def __parse_props(self, target_keys):
  27. lines = self.__data.split('\r\n')
  28. props = {}
  29. for i in range(1, len(lines)):
  30. if not lines[i]:
  31. continue
  32. index = lines[i].find(':')
  33. if index == -1:
  34. return None
  35. props[lines[i][:index]] = lines[i][index + 1:].strip()
  36. if not set(target_keys).issubset(set(props.keys())):
  37. return None
  38. return props
  39. class SSDPServer():
  40. def __init__(self):
  41. self.__s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  42. self.__s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  43. def get_address():
  44. try:
  45. address = socket.gethostbyname(socket.gethostname())
  46. except:
  47. address = ''
  48. if not address or address.startswith('127.'):
  49. # ...the hard way.
  50. s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  51. s.connect(('1.1.1.1', 0))
  52. address = s.getsockname()[0]
  53. return address
  54. local_ip = get_address()
  55. any_ip = '0.0.0.0'
  56. self.__s.bind((any_ip, SSDP_PORT))
  57. # self.__s.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_TTL, 20)
  58. # self.__s.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP, 1)
  59. # self.__s.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF,
  60. # socket.inet_aton(intf) + socket.inet_aton('0.0.0.0'))
  61. self.__s.setsockopt(socket.SOL_IP, socket.IP_ADD_MEMBERSHIP,
  62. socket.inet_aton(SSDP_ADDR) + socket.inet_aton(local_ip))
  63. self.local_ip = local_ip
  64. def start(self):
  65. print("The SSDP service has been started.\n")
  66. while True:
  67. data, addr = self.__s.recvfrom(2048)
  68. conn = Connection(self.__s, data, addr)
  69. conn.handle_request()
  70. self.__s.setsockopt(socket.SOL_IP, socket.IP_DROP_MEMBERSHIP,
  71. socket.inet_aton(SSDP_ADDR) + socket.inet_aton(self.local_ip))
  72. self.__s.close()
  73. if __name__ == '__main__':
  74. port = SSDPServer()
  75. port.start()