I'm trying to send an MSEARCH datagram packet to discover my Roku device on my LAN. I have this implemented in Java already, and it works fine, however I'm trying to learn Haskell. While I'm not getting any compilation errors, the code is hanging during a call to recv
.
Here's my work in progress, shamelessly mostly plagiarized from the Network.Socket.ByteString documentation page.
import Network.Socket hiding (recv)
import Network.Socket.ByteString (recv, sendAll)
import qualified Data.ByteString.Char8 as C
msearch = "M-SEARCH * HTTP/1.1\r\nHost: 239.255.255.250:1900\r\nMan: \"ssdp:discover\"\nST: roku:ecp\r\n\r\n"
main :: IO ()
main = withSocketsDo $
do addrinfos <- getAddrInfo Nothing (Just "239.255.255.250") (Just "1900")
let serveraddr = head addrinfos
sock <- socket (addrFamily serveraddr) Datagram defaultProtocol
connect sock (addrAddress serveraddr)
putStrLn "Sending: "
putStrLn msearch
sendAll sock $ C.pack msearch
msg <- recv sock 1024
close sock
putStr "Got response: "
C.putStrLn msg
In Java:
import java.net.*;
public class Msearch {
public static void main(String[] args) {
try {
// MSEARCH query
String MSEARCH = "M-SEARCH * HTTP/1.1\r\nHost: 239.255.255.250:1900\r\nMan: \"ssdp:discover\"\r\nST: roku:ecp\r\n\r\n";
byte[] sendData = MSEARCH.getBytes();
// Send a datagram packet
System.out.println("Sending:\n" + MSEARCH);
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, InetAddress.getByName("239.255.255.250"), 1900);
DatagramSocket clientSocket = new DatagramSocket();
clientSocket.send(sendPacket);
// Wait for response & close
byte[] receiveData = new byte[1024];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
clientSocket.close();
// Print the response
String response = new String(receivePacket.getData());
System.out.println("Got response:\n" + response);
} catch (Exception e) {
// ...
}
}
}
The Java version works perfectly, yielding:
Sending:
M-SEARCH * HTTP/1.1
Host: 239.255.255.250:1900
Man: "ssdp:discover"
ST: roku:ecp
Got response:
HTTP/1.1 200 OK
Cache-Control: max-age=3600
ST: roku:ecp
USN: uuid:roku:ecp:2N00G7750045
Ext:
Server: Roku UPnP/1.0 MiniUPnPd/1.4
LOCATION: http://192.168.1.169:8060/
The Haskell version hangs on the call to recv
. I'm still learning Haskell and I'm not sure what I'm doing differently that may be causing this. I would be grateful for any insights!