The Socket interface is a ``higher-level'' interface to sockets, and it is what we recommend. Please tell us if the facilities it offers are inadequate to your task! The interface is relatively modest:
data Socket -- instance of: Eq, Show data PortID = Service String -- Service Name eg "ftp" | PortNumber PortNumber -- User defined Port Number | UnixSocket String -- Unix family socket in file system, -- not available con Cygwin/Mingw connectTo :: BSD.HostName -> PortID -> IO Handle listenOn :: PortID -> IO Socket accept :: Socket -> IO (Handle, HostName, PortNumber) sendTo :: BSD.HostName -> PortID -> String -> IO () recvFrom :: BSD.HostName -> PortID -> IO String socketPort :: Socket -> IO PortID withSocketsDo :: IO a -> IO a data PortNumber -- instance of Eq, Ord, Enum, Num, Real, Integral, Show |
The Handle returned by connectTo and accept is block-buffered by default. For an interactive application you may want to set the buffering mode on the Handle to LineBuffering or NoBuffering, like so:
h <- connectTo host port hSetBuffering h LineBuffering |
For really fast I/O, it might be worth looking at the hGetBuf and hPutBuf family of functions in IOExts (see Section 5.20).
On Unix, when reading from a socket and the writing end is closed by the remote client, the program is normally sent a SIGPIPE signal by the operating system. The default behaviour when a SIGPIPE is received is to terminate the program silently, which can be somewhat confusing if you haven't encountered this before. The solution is to specify that SIGPIPE is to be ignored, using the POSIX library (Section 8.2):
On Windows, you need to initialise WinSock before trying to use sockets, i.e.
main = withSocketsDo $ do {...} |