module Util.Net (listenOnLocalhost, listenOnLocalhostAnyPort) where
import Control.Exception (bracketOnError)
import Network.Socket
listenOnLocalhost :: PortNumber -> IO Socket
listenOnLocalhost :: PortNumber -> IO Socket
listenOnLocalhost PortNumber
port = do
let hints :: AddrInfo
hints = AddrInfo
defaultHints { addrSocketType = Stream }
localhost:_ <- Maybe AddrInfo -> Maybe HostName -> Maybe HostName -> IO [AddrInfo]
forall (t :: * -> *).
GetAddrInfo t =>
Maybe AddrInfo
-> Maybe HostName -> Maybe HostName -> IO (t AddrInfo)
getAddrInfo (AddrInfo -> Maybe AddrInfo
forall a. a -> Maybe a
Just AddrInfo
hints) (HostName -> Maybe HostName
forall a. a -> Maybe a
Just HostName
"127.0.0.1") (HostName -> Maybe HostName
forall a. a -> Maybe a
Just (HostName -> Maybe HostName) -> HostName -> Maybe HostName
forall a b. (a -> b) -> a -> b
$ PortNumber -> HostName
forall a. Show a => a -> HostName
show PortNumber
port)
bracketOnError
(socket AF_INET Stream defaultProtocol)
(close)
(\Socket
sock -> do
Socket -> SocketOption -> Int -> IO ()
setSocketOption Socket
sock SocketOption
ReuseAddr Int
1
Socket -> SockAddr -> IO ()
bind Socket
sock (AddrInfo -> SockAddr
addrAddress AddrInfo
localhost)
Socket -> Int -> IO ()
listen Socket
sock Int
maxListenQueue
Socket -> IO Socket
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Socket
sock
)
listenOnLocalhostAnyPort :: IO (Socket, PortNumber)
listenOnLocalhostAnyPort :: IO (Socket, PortNumber)
listenOnLocalhostAnyPort = do
let hints :: AddrInfo
hints = AddrInfo
defaultHints { addrSocketType = Stream }
localhost:_ <- Maybe AddrInfo -> Maybe HostName -> Maybe HostName -> IO [AddrInfo]
forall (t :: * -> *).
GetAddrInfo t =>
Maybe AddrInfo
-> Maybe HostName -> Maybe HostName -> IO (t AddrInfo)
getAddrInfo (AddrInfo -> Maybe AddrInfo
forall a. a -> Maybe a
Just AddrInfo
hints) (HostName -> Maybe HostName
forall a. a -> Maybe a
Just HostName
"127.0.0.1") (HostName -> Maybe HostName
forall a. a -> Maybe a
Just HostName
"0")
bracketOnError
(socket AF_INET Stream defaultProtocol)
(close)
(\Socket
sock -> do
Socket -> SocketOption -> Int -> IO ()
setSocketOption Socket
sock SocketOption
ReuseAddr Int
1
Socket -> SockAddr -> IO ()
bind Socket
sock (AddrInfo -> SockAddr
addrAddress AddrInfo
localhost)
Socket -> Int -> IO ()
listen Socket
sock Int
maxListenQueue
port <- Socket -> IO PortNumber
socketPort Socket
sock
return (sock, port)
)