{-# LANGUAGE CPP #-}moduleNetwork.Socket.SockAddr(getPeerName ,getSocketName ,connect ,bind ,accept ,sendBufTo ,recvBufFrom ,sendBufMsg ,recvBufMsg )whereimportControl.Exception(try,throwIO,IOException)importSystem.Directory(removeFile)importSystem.IO.Error(isAlreadyInUseError,isDoesNotExistError)importqualifiedNetwork.Socket.Buffer asGimportqualifiedNetwork.Socket.Name asGimportqualifiedNetwork.Socket.Syscall asGimportNetwork.Socket.Flag importNetwork.Socket.Imports #if !defined(mingw32_HOST_OS) importNetwork.Socket.Posix.Cmsg #else importNetwork.Socket.Win32.Cmsg #endif importNetwork.Socket.Types -- | Getting peer's 'SockAddr'.getPeerName ::Socket ->IOSockAddr getPeerName :: Socket -> IO SockAddr getPeerName =Socket -> IO SockAddr forall sa. SocketAddress sa => Socket -> IO sa G.getPeerName -- | Getting my 'SockAddr'.getSocketName ::Socket ->IOSockAddr getSocketName :: Socket -> IO SockAddr getSocketName =Socket -> IO SockAddr forall sa. SocketAddress sa => Socket -> IO sa G.getSocketName -- | Connect to a remote socket at address.connect ::Socket ->SockAddr ->IO()connect :: Socket -> SockAddr -> IO () connect =Socket -> SockAddr -> IO () forall sa. SocketAddress sa => Socket -> sa -> IO () G.connect -- | Bind the socket to an address. The socket must not already be-- bound. The 'Family' passed to @bind@ must be the-- same as that passed to 'socket'. If the special port number-- 'defaultPort' is passed then the system assigns the next available-- use port.bind ::Socket ->SockAddr ->IO()bind :: Socket -> SockAddr -> IO () bind Socket s SockAddr a =caseSockAddr a ofSockAddrUnix String p ->do-- gracefully handle the fact that UNIX systems don't clean up closed UNIX-- domain sockets, inspired by https://stackoverflow.com/a/13719866Either IOError () res <-IO () -> IO (Either IOError ()) forall e a. Exception e => IO a -> IO (Either e a) try(Socket -> SockAddr -> IO () forall sa. SocketAddress sa => Socket -> sa -> IO () G.bind Socket s SockAddr a )caseEither IOError () res ofRight()->() -> IO () forall (m :: * -> *) a. Monad m => a -> m a return()LeftIOError e |Bool -> Bool not(IOError -> Bool isAlreadyInUseErrorIOError e )->IOError -> IO () forall e a. Exception e => e -> IO a throwIO(IOError e ::IOException)LeftIOError e |Bool otherwise->do-- socket might be in use, try to connectEither IOError () res2 <-IO () -> IO (Either IOError ()) forall e a. Exception e => IO a -> IO (Either e a) try(Socket -> SockAddr -> IO () forall sa. SocketAddress sa => Socket -> sa -> IO () G.connect Socket s SockAddr a )caseEither IOError () res2 ofRight()->Socket -> IO () close Socket s IO () -> IO () -> IO () forall (m :: * -> *) a b. Monad m => m a -> m b -> m b >>IOError -> IO () forall e a. Exception e => e -> IO a throwIOIOError e LeftIOError e2 |Bool -> Bool not(IOError -> Bool isDoesNotExistErrorIOError e2 )->IOError -> IO () forall e a. Exception e => e -> IO a throwIO(IOError e2 ::IOException)Either IOError () _->do-- socket not actually in use, remove it and retry bindIO (Either IOError ()) -> IO () forall (f :: * -> *) a. Functor f => f a -> f () void(IO () -> IO (Either IOError ()) forall e a. Exception e => IO a -> IO (Either e a) try(IO () -> IO (Either IOError ())) -> IO () -> IO (Either IOError ()) forall a b. (a -> b) -> a -> b $String -> IO () removeFileString p ::IO(EitherIOError()))Socket -> SockAddr -> IO () forall sa. SocketAddress sa => Socket -> sa -> IO () G.bind Socket s SockAddr a SockAddr _->Socket -> SockAddr -> IO () forall sa. SocketAddress sa => Socket -> sa -> IO () G.bind Socket s SockAddr a -- | Accept a connection. The socket must be bound to an address and-- listening for connections. The return value is a pair @(conn,-- address)@ where @conn@ is a new socket object usable to send and-- receive data on the connection, and @address@ is the address bound-- to the socket on the other end of the connection.-- On Unix, FD_CLOEXEC is set to the new 'Socket'.accept ::Socket ->IO(Socket ,SockAddr )accept :: Socket -> IO (Socket, SockAddr) accept =Socket -> IO (Socket, SockAddr) forall sa. SocketAddress sa => Socket -> IO (Socket, sa) G.accept -- | Send data to the socket. The recipient can be specified-- explicitly, so the socket need not be in a connected state.-- Returns the number of bytes sent. Applications are responsible for-- ensuring that all data has been sent.sendBufTo ::Socket ->Ptra ->Int->SockAddr ->IOIntsendBufTo :: Socket -> Ptr a -> Int -> SockAddr -> IO Int sendBufTo =Socket -> Ptr a -> Int -> SockAddr -> IO Int forall sa a. SocketAddress sa => Socket -> Ptr a -> Int -> sa -> IO Int G.sendBufTo -- | Receive data from the socket, writing it into buffer instead of-- creating a new string. The socket need not be in a connected-- state. Returns @(nbytes, address)@ where @nbytes@ is the number of-- bytes received and @address@ is a 'SockAddr' representing the-- address of the sending socket.---- If the first return value is zero, it means EOF.---- For 'Stream' sockets, the second return value would be invalid.---- NOTE: blocking on Windows unless you compile with -threaded (see-- GHC ticket #1129)recvBufFrom ::Socket ->Ptra ->Int->IO(Int,SockAddr )recvBufFrom :: Socket -> Ptr a -> Int -> IO (Int, SockAddr) recvBufFrom =Socket -> Ptr a -> Int -> IO (Int, SockAddr) forall sa a. SocketAddress sa => Socket -> Ptr a -> Int -> IO (Int, sa) G.recvBufFrom -- | Send data to the socket using sendmsg(2).sendBufMsg ::Socket -- ^ Socket->SockAddr -- ^ Destination address->[(PtrWord8,Int)]-- ^ Data to be sent->[Cmsg ]-- ^ Control messages->MsgFlag -- ^ Message flags->IOInt-- ^ The length actually sentsendBufMsg :: Socket -> SockAddr -> [(Ptr Word8, Int)] -> [Cmsg] -> MsgFlag -> IO Int sendBufMsg =Socket -> SockAddr -> [(Ptr Word8, Int)] -> [Cmsg] -> MsgFlag -> IO Int forall sa. SocketAddress sa => Socket -> sa -> [(Ptr Word8, Int)] -> [Cmsg] -> MsgFlag -> IO Int G.sendBufMsg -- | Receive data from the socket using recvmsg(2).recvBufMsg ::Socket -- ^ Socket->[(PtrWord8,Int)]-- ^ A list of a pair of buffer and its size.-- If the total length is not large enough,-- 'MSG_TRUNC' is returned->Int-- ^ The buffer size for control messages.-- If the length is not large enough,-- 'MSG_CTRUNC' is returned->MsgFlag -- ^ Message flags->IO(SockAddr ,Int,[Cmsg ],MsgFlag )-- ^ Source address, received data, control messages and message flagsrecvBufMsg :: Socket -> [(Ptr Word8, Int)] -> Int -> MsgFlag -> IO (SockAddr, Int, [Cmsg], MsgFlag) recvBufMsg =Socket -> [(Ptr Word8, Int)] -> Int -> MsgFlag -> IO (SockAddr, Int, [Cmsg], MsgFlag) forall sa. SocketAddress sa => Socket -> [(Ptr Word8, Int)] -> Int -> MsgFlag -> IO (sa, Int, [Cmsg], MsgFlag) G.recvBufMsg