{-# LANGUAGE CPP #-}-- |-- Module : Network.Socket.ByteString.Lazy-- Copyright : (c) Bryan O'Sullivan 2009-- License : BSD-style---- Maintainer : bos@serpentine.com-- Stability : experimental-- Portability : POSIX, GHC---- This module provides access to the BSD /socket/ interface. For detailed-- documentation, consult your favorite POSIX socket reference. All functions-- communicate failures by converting the error number to an-- 'System.IO.Error.IOError'.---- This module is made to be imported with "Network.Socket" like so:---- > import Network.Socket-- > import Network.Socket.ByteString.Lazy-- > import Prelude hiding (getContents)moduleNetwork.Socket.ByteString.Lazy(-- * Send data to a socketsend ,sendAll ,sendWithFds ,-- * Receive data from a socketgetContents ,recv ,)whereimportData.ByteString.Lazy.Internal(ByteString(..),defaultChunkSize,)importNetwork.Socket (ShutdownCmd (..),shutdown )importSystem.IO.Error(catchIOError)importSystem.IO.Unsafe(unsafeInterleaveIO)importSystem.Posix.Types(Fd(..))importPreludehiding(getContents) #if defined(mingw32_HOST_OS) importNetwork.Socket.ByteString.Lazy.Windows(send,sendAll) #else importNetwork.Socket.ByteString.Lazy.Posix (send ,sendAll ) #endif importqualifiedData.ByteStringasSimportqualifiedData.ByteString.LazyasLimportqualifiedNetwork.Socket.ByteString asNimportNetwork.Socket.Imports importNetwork.Socket.Types -- | Send data and file descriptors over a UNIX-domain socket in-- a single system call. This function does not work on Windows.sendWithFds ::Socket -- ^ Socket->ByteString-- ^ Data to send->[Fd]-- ^ File descriptors->IO()sendWithFds :: Socket -> ByteString -> [Fd] -> IO () sendWithFds Socket s ByteString lbs [Fd] fds =Socket -> [ByteString] -> [Fd] -> IO () N.sendManyWithFds Socket s (ByteString -> [ByteString] L.toChunksByteString lbs )[Fd] fds -- ------------------------------------------------------------------------------- Receiving-- | Receive data from the socket. The socket must be in a connected-- state. Data is received on demand, in chunks; each chunk will be-- sized to reflect the amount of data received by individual 'recv'-- calls.---- All remaining data from the socket is consumed. When there is no-- more data to be received, the receiving side of the socket is shut-- down. If there is an error and an exception is thrown, the socket-- is not shut down.getContents ::Socket -- ^ Connected socket->IOByteString-- ^ Data receivedgetContents :: Socket -> IO ByteString getContents Socket s =IO ByteString loop whereloop :: IO ByteString loop =IO ByteString -> IO ByteString forall a. IO a -> IO a unsafeInterleaveIO(IO ByteString -> IO ByteString) -> IO ByteString -> IO ByteString forall a b. (a -> b) -> a -> b $doByteString sbs <-Socket -> Int -> IO ByteString N.recv Socket s Int defaultChunkSizeifByteString -> Bool S.nullByteString sbs thendoSocket -> ShutdownCmd -> IO () shutdown Socket s ShutdownCmd ShutdownReceive IO () -> (IOError -> IO ()) -> IO () forall a. IO a -> (IOError -> IO a) -> IO a `catchIOError`IO () -> IOError -> IO () forall a b. a -> b -> a const(() -> IO () forall a. a -> IO a forall (m :: * -> *) a. Monad m => a -> m a return())ByteString -> IO ByteString forall a. a -> IO a forall (m :: * -> *) a. Monad m => a -> m a returnByteString EmptyelseByteString -> ByteString -> ByteString ChunkByteString sbs (ByteString -> ByteString) -> IO ByteString -> IO ByteString forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$>IO ByteString loop -- | Receive data from the socket. The socket must be in a connected-- state. This function may return fewer bytes than specified. If-- the received data is longer than the specified length, it may be-- discarded depending on the type of socket. This function may block-- until a message arrives.---- If there is no more data to be received, returns an empty 'ByteString'.recv ::Socket -- ^ Connected socket->Int64-- ^ Maximum number of bytes to receive->IOByteString-- ^ Data receivedrecv :: Socket -> Int64 -> IO ByteString recv Socket s Int64 nbytes =ByteString -> ByteString chunk (ByteString -> ByteString) -> IO ByteString -> IO ByteString forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$>Socket -> Int -> IO ByteString N.recv Socket s (Int64 -> Int forall a b. (Integral a, Num b) => a -> b fromIntegralInt64 nbytes )wherechunk :: ByteString -> ByteString chunk ByteString k |ByteString -> Bool S.nullByteString k =ByteString Empty|Bool otherwise=ByteString -> ByteString -> ByteString ChunkByteString k ByteString Empty