-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A portable and extensible sockets library. -- @package socket @version 0.3.0.1 module System.Socket.Protocol class Protocol p protocolNumber :: Protocol p => p -> CInt instance Protocol () module System.Socket.Protocol.UDP data UDP instance Protocol UDP module System.Socket.Protocol.TCP data TCP instance Protocol TCP module System.Socket.Type class Type t typeNumber :: Type t => t -> CInt module System.Socket.Type.DGRAM data DGRAM instance Type DGRAM module System.Socket.Type.RAW data RAW instance Type RAW module System.Socket.Type.SEQPACKET data SEQPACKET instance Type SEQPACKET module System.Socket.Type.STREAM data STREAM instance Type STREAM module System.Socket.Family class Storable (SockAddr f) => Family f where type family SockAddr f familyNumber :: Family f => f -> CInt module System.Socket.Unsafe tryWaitAndRetry :: Socket f t p -> (Fd -> IO (IO ())) -> (Fd -> IO CInt) -> IO CInt unsafeSend :: Socket a t p -> Ptr a -> CSize -> MsgFlags -> IO CInt unsafeSendTo :: Socket f t p -> Ptr b -> CSize -> MsgFlags -> Ptr (SockAddr f) -> CInt -> IO CInt unsafeRecv :: Socket a t p -> Ptr b -> CSize -> MsgFlags -> IO CInt unsafeRecvFrom :: Socket f t p -> Ptr b -> CSize -> MsgFlags -> Ptr (SockAddr f) -> Ptr CInt -> IO CInt module System.Socket.Family.INET data INET -- | To avoid errors with endianess it was decided to keep this type -- abstract. -- -- Hint: Use the Storable instance if you really need to access. -- It exposes it exactly as found within an IP packet (big endian if you -- insist on interpreting it as a number). -- -- Another hint: Use getAddrInfo for parsing and suppress -- nameserver lookups: -- --
-- > getAddrInfo (Just "127.0.0.1") Nothing aiNUMERICHOST :: IO [AddrInfo SockAddrIn STREAM TCP]
-- [AddrInfo {addrInfoFlags = AddrInfoFlags 4, addrAddress = "127.0.0.1:0", addrCanonName = Nothing}]
--
data AddrIn
data SockAddrIn
SockAddrIn :: Word16 -> AddrIn -> SockAddrIn
sinPort :: SockAddrIn -> Word16
sinAddr :: SockAddrIn -> AddrIn
-- | -- 0.0.0.0 --inaddrANY :: AddrIn -- |
-- 255.255.255.0 --inaddrBROADCAST :: AddrIn -- |
-- 255.255.255.0 --inaddrNONE :: AddrIn -- |
-- 127.0.0.1 --inaddrLOOPBACK :: AddrIn -- |
-- 224.0.0.0 --inaddrUNSPEC_GROUP :: AddrIn -- |
-- 224.0.0.1 --inaddrALLHOSTS_GROUP :: AddrIn -- |
-- 224.0.0.2 --inaddrALLRTS_GROUP :: AddrIn -- |
-- 224.0.0.255 --inaddrMAXLOCAL_GROUP :: AddrIn instance Eq AddrIn instance Eq SockAddrIn instance Storable SockAddrIn instance Storable AddrIn instance Show AddrIn instance Show SockAddrIn instance Family INET module System.Socket.Family.INET6 data INET6 -- | To avoid errors with endianess it was decided to keep this type -- abstract. -- -- Hint: Use the Storable instance if you really need to access. -- It exposes it exactly as found within an IP packet (big endian if you -- insist on interpreting it as a number). -- -- Another hint: Use getAddrInfo for parsing and suppress -- nameserver lookups: -- --
-- > getAddrInfo (Just "::1") Nothing aiNUMERICHOST :: IO [AddrInfo SockAddrIn6 STREAM TCP]
-- [AddrInfo {addrInfoFlags = AddrInfoFlags 4, addrAddress = [0000:0000:0000:0000:0000:0000:0000:0001]:0, addrCanonName = Nothing}]
--
data AddrIn6
data SockAddrIn6
SockAddrIn6 :: Word16 -> Word32 -> AddrIn6 -> Word32 -> SockAddrIn6
sin6Port :: SockAddrIn6 -> Word16
sin6Flowinfo :: SockAddrIn6 -> Word32
sin6Addr :: SockAddrIn6 -> AddrIn6
sin6ScopeId :: SockAddrIn6 -> Word32
-- | -- :: --in6addrANY :: AddrIn6 -- |
-- ::1 --in6addrLOOPBACK :: AddrIn6 instance Eq AddrIn6 instance Eq SockAddrIn6 instance Storable SockAddrIn6 instance Storable AddrIn6 instance Show AddrIn6 instance Show SockAddrIn6 instance Family INET6 -- | This starts a TCP server on localhost, sends "Hello world!" -- to connecting peers and closes the connection immediately. -- --
-- {-# LANGUAGE OverloadedStrings #-}
-- module Main where
--
-- import System.Socket
-- import System.Socket.Family.INET (inaddrLOOPBACK)
-- import Data.Monoid
-- import Data.ByteString
-- import Control.Monad
-- import Control.Concurrent
-- import Control.Exception
--
-- main :: IO ()
-- main = do
-- s <- socket :: IO (Socket INET STREAM TCP)
-- setSockOpt s (SO_REUSEADDR True)
-- bind s (SockAddrIn 8080 inaddrLOOPBACK)
-- listen s 5
-- forever $ do
-- (peer,addr) <- accept s
-- forkIO $ do
-- sendAll peer "Hello world!" mempty `finally` close peer
--
--
-- This downloads the [Haskell website](http://www.haskell.org) and shows
-- how to handle exceptions. Note the use of IPv4-mapped IPv6 addresses:
-- This will work even if you don't have IPv6 connectivity yet and is the
-- preferred method when writing new applications.
--
--
-- {-# LANGUAGE OverloadedStrings #-}
-- module Main where
--
-- import Control.Monad
-- import Control.Exception
--
-- import Data.Function (fix)
-- import qualified Data.ByteString as BS
--
-- import System.IO
-- import System.Exit
-- import System.Socket
--
-- main :: IO ()
-- main = fetch
-- `catch` (\e-> do
-- hPutStr stderr "Something failed when resolving the name: "
-- hPutStrLn stderr $ show (e :: AddrInfoException)
-- exitFailure
-- )
-- `catch` (\e-> do
-- hPutStr stderr "Something went wrong with the socket: "
-- hPutStrLn stderr $ show (e :: SocketException)
-- exitFailure
-- )
--
-- fetch :: IO ()
-- fetch = do
-- addrs <- getAddrInfo6 (Just "www.haskell.org") (Just "80") aiV4MAPPED :: IO [AddrInfo INET6 STREAM TCP]
-- case addrs of
-- (addr:_) ->
-- -- always use the `bracket` pattern to reliably release resources!
-- bracket
-- ( socket :: IO (Socket INET6 STREAM TCP) )
-- ( close )
-- ( \s-> do connect s (addrAddress addr)
-- sendAll s "GET / HTTP/1.0\r\nHost: www.haskell.org\r\n\r\n" mempty
-- fix $ \recvMore-> do
-- bs <- recv s 4096 mempty
-- BS.putStr bs
-- if BS.length bs == 0 -- an empty string means the peer terminated the connection
-- then exitSuccess
-- else recvMore
-- )
-- _ -> error "Illegal state: getAddrInfo yields non-empty list or exception."
--
module System.Socket
data AddrInfo f t p
AddrInfo :: AddrInfoFlags -> SockAddr f -> Maybe ByteString -> AddrInfo f t p
addrInfoFlags :: AddrInfo f t p -> AddrInfoFlags
addrAddress :: AddrInfo f t p -> SockAddr f
addrCanonName :: AddrInfo f t p -> Maybe ByteString
class Family f => GetAddrInfo f
getAddrInfo :: (GetAddrInfo f, Type t, Protocol p) => Maybe ByteString -> Maybe ByteString -> AddrInfoFlags -> IO [AddrInfo f t p]
-- | Maps addresss to readable host- and service names.
--
-- The operation throws AddrInfoExceptions.
--
--
-- > getNameInfo (SockAddrIn 80 inaddrLOOPBACK) mempty
-- ("localhost.localdomain","http")
--
class Family f => GetNameInfo f
getNameInfo :: GetNameInfo f => SockAddr f -> NameInfoFlags -> IO (ByteString, ByteString)
-- | Creates a new socket.
--
-- Whereas the underlying POSIX socket operation takes 3 parameters, this
-- library encodes this information in the type variables. This rules out
-- several kinds of errors and escpecially simplifies the handling of
-- addresses (by using associated type families). Examples:
--
-- -- -- create a IPv4-UDP-datagram socket -- sock <- socket :: IO (Socket INET DGRAM UDP) -- -- create a IPv6-TCP-streaming socket -- sock6 <- socket :: IO (Socket INET6 STREAM TCP) ---- --
result <- bracket -- (socket :: IO (Socket INET6 STREAM TCP)) close $ \sock-> do -- somethingWith sock -- your computation here return -- somethingelse
-- sendAll sock buf flags = do -- sent <- send sock buf flags -- when (sent < length buf) $ sendAll sock (drop sent buf) flags --sendAll :: Socket f STREAM p -> ByteString -> MsgFlags -> IO () -- | A generic socket type. Also see socket for details. -- -- The socket is just an MVar-wrapped file descriptor. It is -- exposed in order to make this library easily extensible, but it is -- usually not necessary nor advised to work directly on the file -- descriptor. If you do, the following rules must be obeyed: -- --
-- AddrInfoException "Temporary failure in name resolution" --eaiAGAIN :: AddrInfoException -- |
-- AddrInfoException "Bad value for ai_flags" --eaiBADFLAGS :: AddrInfoException -- |
-- AddrInfoException "Non-recoverable failure in name resolution" --eaiFAIL :: AddrInfoException -- |
-- AddrInfoException "ai_family not supported" --eaiFAMILY :: AddrInfoException -- |
-- AddrInfoException "Memory allocation failure" --eaiMEMORY :: AddrInfoException -- |
-- AddrInfoException "No such host is known" --eaiNONAME :: AddrInfoException -- |
-- AddrInfoException "ai_socktype not supported" --eaiSOCKTYPE :: AddrInfoException -- |
-- AddrInfoException "Servname not supported for ai_socktype" --eaiSERVICE :: AddrInfoException -- |
-- AddrInfoException "System error" --eaiSYSTEM :: AddrInfoException class GetSockOpt o getSockOpt :: GetSockOpt o => Socket f t p -> IO o class SetSockOpt o setSockOpt :: SetSockOpt o => Socket f t p -> o -> IO () data SO_ACCEPTCONN SO_ACCEPTCONN :: Bool -> SO_ACCEPTCONN data SO_REUSEADDR SO_REUSEADDR :: Bool -> SO_REUSEADDR -- | Use the Monoid instance to combine several flags: -- --
-- mconcat [msgNOSIGNAL, msgWAITALL] ---- -- Use the Bits instance to check whether a flag is set: -- --
-- if flags .&. msgEOR /= mempty then ... --newtype MsgFlags MsgFlags :: CInt -> MsgFlags msgDONTWAIT :: MsgFlags msgEOR :: MsgFlags msgMORE :: MsgFlags msgNOSIGNAL :: MsgFlags msgOOB :: MsgFlags msgTRUNC :: MsgFlags msgWAITALL :: MsgFlags -- | Use the Monoid instance to combine several flags: -- --
-- mconcat [aiADDRCONFIG, aiV4MAPPED] --newtype AddrInfoFlags AddrInfoFlags :: CInt -> AddrInfoFlags aiADDRCONFIG :: AddrInfoFlags aiALL :: AddrInfoFlags aiCANONNAME :: AddrInfoFlags aiNUMERICHOST :: AddrInfoFlags aiNUMERICSERV :: AddrInfoFlags aiPASSIVE :: AddrInfoFlags aiV4MAPPED :: AddrInfoFlags -- | Use the Monoid instance to combine several flags: -- --
-- mconcat [niNAMEREQD, niNOFQDN] --newtype NameInfoFlags NameInfoFlags :: CInt -> NameInfoFlags -- | Throw an exception if the hostname cannot be determined. niNAMEREQD :: NameInfoFlags -- | Service is datagram based (UDP) rather than stream based (TCP). niDGRAM :: NameInfoFlags -- | Return only the hostname part of the fully qualified domain name for -- local hosts. niNOFQDN :: NameInfoFlags -- | Return the numeric form of the host address. niNUMERICHOST :: NameInfoFlags -- | Return the numeric form of the service address. niNUMERICSERV :: NameInfoFlags