I'm trying to create a Chromecast like device that can stream video from the internet and be remotely controlled. I do the remote control with HTTP get requests to the device and listen for them with the following code:
import socket
import sys
s = socket.socket()
host = "localhost"
port = 8060
s.bind(('', port))
s.listen(1)
try:
while True:
connection, clientAddress = s.accept()
try:
print clientAddress
//Do Command
//Reply
except:
print "Error"
except KeyboardInterrupt:
print('interrupt')
I then went to implement SSDP so other devices can find my device and cast to it and was planning on using similar code to listen for the MSEARCH requests except on 239.255.255.250:1900. However, when a MSEARCH is sent the code does not pick it up.
import socket
import sys
s = socket.socket()
host = "239.255.255.250"
port = 1900
s.bind((host, port))
s.listen(10)
try:
while True:
connection, clientAddress = s.accept()
try:
print("Trigger")
print clientAddress
data = connection.recv(1048)
print data
except:
print "Error"
except KeyboardInterrupt:
print('interrupt')
So the question is why are the two acting differently (I believe this is because in the first example the device listening is also the destination for the HTTP requests whereas in the second it is not) and what is a way to fix the code so I can listen for SSDP searches.
SSDP is a UDP protocol, but you don't specify UDP in the socket constructor. By using the socket constructor with no arguments,
s = socket.socket()
you get the default arguments:
socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)
As you can see, the default for type is SOCK_STREAM
, i.e. TCP. Instead, look at the server() method in this example, of which a fragment is:
MCAST_GRP = '239.255.255.250'
MCAST_PORT = 1900
def server(timeout=5):
socket.setdefaulttimeout(timeout)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
sock.bind(('', MCAST_PORT))
mreq = struct.pack('4sl', socket.inet_aton(MCAST_GRP), socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
# ... more code at the link