2 % (c) The GRASP/AQUA Project, Glasgow University, 1995-98
4 % Last Modified: Fri Jul 21 15:53:32 1995
5 % Darren J Moffat <moffatd@dcs.gla.ac.uk>
7 % Further hacked on by Sigbjorn Finne <sof@dcs.gla.ac.uk>
9 \section[Socket]{Haskell 1.3 Socket bindings}
13 {-# OPTIONS -#include "cbits/ghcSockets.h" #-}
21 connectTo, -- :: Hostname -> PortID -> IO Handle
22 listenOn, -- :: PortID -> IO Socket
24 accept, -- :: Socket -> IO (Handle, HostName)
26 sendTo, -- :: Hostname -> PortID -> String -> IO ()
27 recvFrom, -- :: Hostname -> PortID -> IO String
29 socketPort, -- :: Socket -> IO PortID
31 withSocketsDo, -- :: IO a -> IO a
34 mkPortNumber -- :: Int -> PortNumber
39 import SocketPrim hiding ( accept, socketPort, recvFrom, sendTo )
40 import qualified SocketPrim ( accept, socketPort )
44 %***************************************************************************
46 \subsection[Socket-Setup]{High Level ``Setup'' functions}
48 %***************************************************************************
50 Calling @connectTo@ creates a client side socket which is
51 connected to the given host and port. The Protocol and socket type is
52 derived from the given port identifier. If a port number is given
53 then the result is always an internet family @Stream@ socket.
55 If the @PortID@ specifies a unix family socket and the @Hostname@
56 differs from that returned by @getHostname@ then an error is
57 raised. Alternatively an empty string may be given to @connectTo@
58 signalling that the current hostname applies.
62 Service String -- Service Name eg "ftp"
63 | PortNumber PortNumber -- User defined Port Number
65 | UnixSocket String -- Unix family socket in file system
68 type Hostname = String
69 -- Maybe consider this alternative.
70 -- data Hostname = Name String | IP Int Int Int Int
73 If more control over the socket type is required then $socketPrim$
74 should be used instead.
77 connectTo :: Hostname -- Hostname
78 -> PortID -- Port Identifier
79 -> IO Handle -- Connected Socket
81 connectTo hostname (Service serv) = do
82 proto <- getProtocolNumber "tcp"
83 sock <- socket AF_INET Stream proto
84 port <- getServicePortNumber serv
85 he <- getHostByName hostname
86 connect sock (SockAddrInet port (hostAddress he))
87 socketToHandle sock ReadWriteMode
89 connectTo hostname (PortNumber port) = do
90 proto <- getProtocolNumber "tcp"
91 sock <- socket AF_INET Stream proto
92 he <- getHostByName hostname
93 connect sock (SockAddrInet port (hostAddress he))
94 socketToHandle sock ReadWriteMode
97 connectTo _ (UnixSocket path) = do
98 sock <- socket AF_UNIX Datagram 0
99 connect sock (SockAddrUnix path)
100 socketToHandle sock ReadWriteMode
105 The dual to the @connectTo@ call. This creates the server side
106 socket which has been bound to the specified port.
109 listenOn :: PortID -- Port Identifier
110 -> IO Socket -- Connected Socket
112 listenOn (Service serv) = do
113 proto <- getProtocolNumber "tcp"
114 sock <- socket AF_INET Stream proto
115 port <- getServicePortNumber serv
116 bindSocket sock (SockAddrInet port iNADDR_ANY)
117 listen sock maxListenQueue
120 listenOn (PortNumber port) = do
121 proto <- getProtocolNumber "tcp"
122 sock <- socket AF_INET Stream proto
123 bindSocket sock (SockAddrInet port iNADDR_ANY)
124 listen sock maxListenQueue
128 listenOn (UnixSocket path) = do
129 sock <- socket AF_UNIX Datagram 0
130 bindSocket sock (SockAddrUnix path)
136 accept :: Socket -- Listening Socket
137 -> IO (Handle, -- StdIO Handle for read/write
138 HostName) -- HostName of Peer socket
140 ~(sock', (SockAddrInet _ haddr)) <- SocketPrim.accept sock
141 (HostEntry peer _ _ _) <- getHostByAddr AF_INET haddr
142 handle <- socketToHandle sock' ReadWriteMode
143 return (handle, peer)
147 Send and recived data from/to the given host and port number. These
148 should normally only be used where the socket will not be required for
151 Thse are wrappers around socket, bind, and listen.
154 sendTo :: Hostname -- Hostname
155 -> PortID -- Port Number
156 -> String -- Message to send
163 recvFrom :: Hostname -- Hostname
164 -> PortID -- Port Number
165 -> IO String -- Received Data
166 recvFrom host port = do
170 ~(s', SockAddrInet _ haddr) <- SocketPrim.accept s
171 (HostEntry peer _ _ _) <- getHostByAddr AF_INET haddr
177 msg <- readSocketAll s'
187 Access function returning the port type/id of socket.
190 socketPort :: Socket -> IO PortID
192 sockaddr <- getSocketName s
193 return (portID sockaddr)
197 SockAddrInet port _ -> PortNumber port
199 SockAddrUnix path -> UnixSocket path