network-run-0.1.0: Network/Run/Core.hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE CPP #-}
module Network.Run.Core (
runClient
, resolve
, openServerSocket
) where
import qualified Control.Exception as E
import Control.Monad (when)
import Network.Socket
runClient :: SocketType -> String -> String -> (Socket -> SockAddr -> IO a) -> IO a
runClient socketType host port client = withSocketsDo $ do
addr <- resolve socketType (Just host) port False
let sockAddr = addrAddress addr
#if MIN_VERSION_network(3,1,1)
E.bracket (open addr) (\sock -> gracefulClose sock 5000)
(\sock -> client sock sockAddr)
#else
E.bracket (open addr) close $ \sock -> client sock sockAddr
#endif
where
open addr = do
sock <- openSocket addr
when (socketType == Stream) $ connect sock $ addrAddress addr
return sock
resolve :: SocketType -> Maybe HostName -> ServiceName -> Bool -> IO AddrInfo
resolve socketType mhost port passive =
head <$> getAddrInfo (Just hints) mhost (Just port)
where
hints = defaultHints {
addrSocketType = socketType
, addrFlags = if passive then [AI_PASSIVE] else []
}
openSocket :: AddrInfo -> IO Socket
openSocket addr = socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr)
openServerSocket :: AddrInfo -> IO Socket
openServerSocket addr = do
sock <- openSocket addr
setSocketOption sock ReuseAddr 1
withFdSocket sock $ setCloseOnExecIfNeeded
bind sock $ addrAddress addr
return sock