2 % (c) The GRASP/AQUA Project, Glasgow University, 1995
4 % Last Modified: Fri Jul 21 15:53:32 1995
5 % Darren J Moffat <moffatd@dcs.gla.ac.uk>
6 \section[Socket]{Haskell 1.3 Socket bindings}
15 connectTo, -- :: Hostname -> PortID -> IO Handle
16 listenOn, -- :: PortID -> IO Socket
18 accept, -- :: Socket -> IO (Handle, HostName)
20 sendTo, -- :: Hostname -> PortID -> String -> IO ()
21 recvFrom, -- :: Hostname -> PortID -> IO String
23 socketPort, -- :: Socket -> IO PortID
25 -- make interface self-sufficient:
31 import SocketPrim renaming (accept to socketPrim_accept
32 , socketPort to socketPort_prim
40 %***************************************************************************
42 \subsection[Socket-Setup]{High Level "Setup" functions}
44 %***************************************************************************
46 Calling $connectTo$ creates a client side socket which is
47 connected to the given host and port. The Protocol and socket type is
48 derived from the given port identifier. If a port number is given
49 then the result is always an internet family $Stream$ socket.
51 If the $PortID$ specifies a unix family socket and the $Hostname$
52 differs from that returned by $getHostname$ then an error is
53 raised. Alternatively an empty string may be given to $connectTo$
54 signalling that the current hostname applies.
58 Service String -- Service Name eg "ftp"
59 | PortNumber Int -- User defined Port Number
60 | UnixSocket String -- Unix family socket in file system
62 type Hostname = String
63 -- Maybe consider this alternative.
64 -- data Hostname = Name String | IP Int Int Int Int
69 If more control over the socket type is required then $socketPrim$
70 should be used instead.
75 connectTo :: Hostname -> -- Hostname
76 PortID -> -- Port Identifier
77 IO Handle -- Connected Socket
78 connectTo hostname (Service serv) =
79 getProtocolNumber "tcp" >>= \ proto ->
80 socket AF_INET Stream proto >>= \ sock ->
81 getServicePortNumber serv >>= \ port ->
82 getHostByName hostname >>= \ (HostEntry _ _ _ haddrs) ->
83 connect sock (SockAddrInet port (head haddrs)) >>
85 connectTo hostname (PortNumber port) =
86 getProtocolNumber "tcp" >>= \ proto ->
87 socket AF_INET Stream proto >>= \ sock ->
88 getHostByName hostname >>= \ (HostEntry _ _ _ haddrs) ->
89 connect sock (SockAddrInet port (head haddrs)) >>
91 connectTo _ (UnixSocket path) =
92 socket AF_UNIX Datagram 0 >>= \ sock ->
93 connect sock (SockAddrUnix path) >>
98 The dual to the $connectTo$ call. This creates the server side
99 socket which has been bound to the specified port.
102 listenOn :: PortID -> -- Port Identifier
103 IO Socket -- Connected Socket
104 listenOn (Service serv) =
105 getProtocolNumber "tcp" >>= \ proto ->
106 socket AF_INET Stream proto >>= \ sock ->
107 getServicePortNumber serv >>= \ port ->
108 bindSocket sock (SockAddrInet port iNADDR_ANY) >>
109 listen sock maxListenQueue >>
111 listenOn (PortNumber port) =
112 getProtocolNumber "tcp" >>= \ proto ->
113 socket AF_INET Stream proto >>= \ sock ->
114 bindSocket sock (SockAddrInet port iNADDR_ANY) >>
115 listen sock maxListenQueue >>
117 listeOn (UnixSocket path) =
118 socket AF_UNIX Datagram 0 >>= \ sock ->
119 bindSocket sock (SockAddrUnix path) >>
124 accept :: Socket -> -- Listening Socket
125 IO (Handle, -- StdIO Handle for read/write
126 HostName) -- HostName of Peer socket
128 socketPrim_accept sock >>= \ (sock', (SockAddrInet _ haddr)) ->
129 getHostByAddr AF_INET haddr >>= \ (HostEntry peer _ _ _) ->
130 socketToHandle sock >>= \ handle ->
131 return (handle, peer)
134 Send and recived data from/to the given host and port number. These
135 should normally only be used where the socket will not be required for
138 Thse are wrappers around socket, bind, and listen.
141 sendTo :: Hostname -> -- Hostname
142 PortID-> -- Port Number
143 String -> -- Message to send
146 connectTo h p >>= \ s ->
153 recvFrom :: Hostname -> -- Hostname
154 PortID-> -- Port Number
155 IO String -- Received Data
157 listenOn port >>= \ s ->
160 socketPrim_accept s >>= \ (s', (SockAddrInet _ haddr)) ->
161 getHostByAddr AF_INET haddr >>= \ (HostEntry peer _ _ _) ->
166 readSocketAll s' >>= \ msg ->
170 waiting >>= \ message ->
179 socketPort :: Socket -> IO PortID
181 getSocketName s >>= \ sockaddr ->
182 return (case sockaddr of
183 SockAddrInet port _ ->