How can I get Haskell to listen for UDP and TCP on the same port?
Here is the code I have so far (based on acme-http):
listenOn portm = do
protoTCP <- getProtocolNumber "tcp"
E.bracketOnError
(socket AF_INET Stream protoTCP)
sClose
(\sock -> do
setSocketOption sock ReuseAddr 1
setSocketOption sock NoDelay 1
bindSocket sock (SockAddrInet (fromIntegral portm) iNADDR_ANY)
listen sock (max 1024 maxListenQueue)
return sock
)
protoUDP <- getProtocolNumber "udp"
E.bracketOnError
(socket AF_INET Datagram protoUDP)
sClose
(\sock -> do
setSocketOption sock ReuseAddr 1
bindSocket sock (SockAddrInet (fromIntegral portm) iNADDR_ANY)
return sock
)
I compiles fine, but I get the follow runtime error:
user error (accept: can't perform accept on socket ((AF_INET,Datagram,17)) in status Bound)
Unfortunately, documentation on network programming in Haskell is a bit limited (as usual). I don't really know where I'm supposed to look to figure this stuff out.
[UPDATE]
For anyone is interested, here is the result:
https://github.com/joehillen/acme-sip/blob/master/Acme/Serve.hs
I realize there is a lot of room for improvement, but it works.
No. Only one application can bind to a port at a time, and behavior if the bind is forced is indeterminate.
The UDP and TCP port namespaces are totally independent, despite the fact that they are in the same numerical range.
There doesn't seem to be anything wrong with this code, but somewhere else your code seems to be calling accept()
on the UDP socket, which isn't legal. All you need to do with a UDP socket is receive from it and send with it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With