n_fails = 0
for i in range(1, 100):
rokus = get_ecp_urls()
n_fails += 3 - len(rokus)
print i, 'runs,', 100 * n_fails // (3*i), '% failure rate'
$ python oo.py
1 runs, 0 % failure rate
2 runs, 0 % failure rate
3 runs, 0 % failure rate
4 runs, 0 % failure rate
5 runs, 13 % failure rate
6 runs, 22 % failure rate
7 runs, 19 % failure rate
8 runs, 16 % failure rate
9 runs, 14 % failure rate
10 runs, 13 % failure rate
11 runs, 12 % failure rate
12 runs, 11 % failure rate
13 runs, 10 % failure rate
14 runs, 9 % failure rate
15 runs, 8 % failure rate
16 runs, 8 % failure rate
17 runs, 9 % failure rate
18 runs, 9 % failure rate
...
"squirreltown" wrote:
Yes, it is not the most efficient - it works by attrition. Typical run, find roku# - 2,2,1,2,3,1,3,4. So, it finds them eventually, because it's looping . No clue why it picks one or the other in the first place - perhaps the most recent roku broadcast?
It's only been a day but no hiccups so far with 4 rokus.
"squirreltown" wrote:
How does a media player find a server? The pi is setup as a webserver. The Roku is set up to enter the I.P. manually now. Sure would be nice...
function discover_my_server_ip() as String:
port = createObject("roMessagePort")
for each hash in createObject("roDeviceInfo").getIpAddrs().items():
octets = hash.value.split(".")
xfers = { }
for i = 1 to 254:
octets[3] = i.toStr()
url = "http://" + octets.join(".") + "/path/unique/to/squirreltown"
req = createObject("roUrlTransfer")
xfers[req.getIdentity().toStr()] = req
req.setUrl(url)
req.setMessagePort(port)
req.asyncHead()
next
while not xfers.isEmpty():
msg = port.waitMessage(0)
if type(msg) = "roUrlEvent":
if msg.getResponseCode() = 200 then return msg.GetTargetIpAddress()
xfers.delete(msg.GetSourceIdentity().toStr())
end if
end while
next
return ""
end function
"ST: roku:ecp" to "ST:ssdp:all"
import socket
import struct
MSEARCH_RESPONSE = ('HTTP/1.1 200 OK\r\n'
'Cache-Control: max-age=3600\r\n'
'ST: roku:ecp\r\n'
'USN: uuid:roku:ecp:H0A0AP999999\r\n'
'Ext:\r\n'
'Server: Roku UPnP/1.0 MiniUPnPd/1.4\r\n'
'Location: http://{ipAddr}:8060/\r\n'
'\r\n')
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('', 1900))
addMembershipData = struct.pack('4sl', socket.inet_aton('239.255.255.250'), socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, addMembershipData)
while True:
data, addr = sock.recvfrom(4096)
if data.startswith(b'M-SEARCH'):
response = str.encode(MSEARCH_RESPONSE.format(ipAddr=addr[0]))
sock.sendto(response, addr)
"belltown" wrote:
One issue with your subnet scan method is that it assumes your local network is configured to use a 24-bit subnet id (8-bit host id). That may be common for most home networks, but it's by no means guaranteed. Ideally, you'd have to figure out the subnet mask somehow and use that determine how many possible hosts to scan. That's a lot more network traffic if you've configured a 16-bit subnet id for, example.