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:
30 import SocketPrim renaming (accept to socketPrim_accept
31 , socketPort to socketPort_prim
35 %***************************************************************************
37 \subsection[Socket-Setup]{High Level ``Setup'' functions}
39 %***************************************************************************
41 Calling $connectTo$ creates a client side socket which is
42 connected to the given host and port. The Protocol and socket type is
43 derived from the given port identifier. If a port number is given
44 then the result is always an internet family $Stream$ socket.
46 If the $PortID$ specifies a unix family socket and the $Hostname$
47 differs from that returned by $getHostname$ then an error is
48 raised. Alternatively an empty string may be given to $connectTo$
49 signalling that the current hostname applies.
53 Service String -- Service Name eg "ftp"
54 | PortNumber Int -- User defined Port Number
55 | UnixSocket String -- Unix family socket in file system
57 type Hostname = String
58 -- Maybe consider this alternative.
59 -- data Hostname = Name String | IP Int Int Int Int
62 If more control over the socket type is required then $socketPrim$
63 should be used instead.
66 connectTo :: Hostname -> -- Hostname
67 PortID -> -- Port Identifier
68 IO Handle -- Connected Socket
70 connectTo hostname (Service serv) =
71 getProtocolNumber "tcp" >>= \ proto ->
72 socket AF_INET Stream proto >>= \ sock ->
73 getServicePortNumber serv >>= \ port ->
74 getHostByName hostname >>= \ (HostEntry _ _ _ haddrs) ->
75 connect sock (SockAddrInet port (head haddrs)) >>
76 socketToHandle sock >>= \ h ->
77 hSetBuffering h NoBuffering >>
79 connectTo hostname (PortNumber port) =
80 getProtocolNumber "tcp" >>= \ proto ->
81 socket AF_INET Stream proto >>= \ sock ->
82 getHostByName hostname >>= \ (HostEntry _ _ _ haddrs) ->
83 connect sock (SockAddrInet port (head haddrs)) >>
85 connectTo _ (UnixSocket path) =
86 socket AF_UNIX Datagram 0 >>= \ sock ->
87 connect sock (SockAddrUnix path) >>
91 The dual to the $connectTo$ call. This creates the server side
92 socket which has been bound to the specified port.
95 listenOn :: PortID -> -- Port Identifier
96 IO Socket -- Connected Socket
98 listenOn (Service serv) =
99 getProtocolNumber "tcp" >>= \ proto ->
100 socket AF_INET Stream proto >>= \ sock ->
101 getServicePortNumber serv >>= \ port ->
102 bindSocket sock (SockAddrInet port iNADDR_ANY) >>
103 listen sock maxListenQueue >>
105 listenOn (PortNumber port) =
106 getProtocolNumber "tcp" >>= \ proto ->
107 socket AF_INET Stream proto >>= \ sock ->
108 bindSocket sock (SockAddrInet port iNADDR_ANY) >>
109 listen sock maxListenQueue >>
111 listeOn (UnixSocket path) =
112 socket AF_UNIX Datagram 0 >>= \ sock ->
113 bindSocket sock (SockAddrUnix path) >>
118 accept :: Socket -> -- Listening Socket
119 IO (Handle, -- StdIO Handle for read/write
120 HostName) -- HostName of Peer socket
123 socketPrim_accept sock >>= \ (sock', (SockAddrInet _ haddr)) ->
124 getHostByAddr AF_INET haddr >>= \ (HostEntry peer _ _ _) ->
125 socketToHandle sock >>= \ handle ->
126 return (handle, peer)
129 Send and recived data from/to the given host and port number. These
130 should normally only be used where the socket will not be required for
133 Thse are wrappers around socket, bind, and listen.
136 sendTo :: Hostname -> -- Hostname
137 PortID-> -- Port Number
138 String -> -- Message to send
142 connectTo h p >>= \ s ->
146 recvFrom :: Hostname -> -- Hostname
147 PortID-> -- Port Number
148 IO String -- Received Data
151 listenOn port >>= \ s ->
154 socketPrim_accept s >>= \ (s', (SockAddrInet _ haddr)) ->
155 getHostByAddr AF_INET haddr >>= \ (HostEntry peer _ _ _) ->
160 readSocketAll s' >>= \ msg ->
164 waiting >>= \ message ->
172 socketPort :: Socket -> IO PortID
175 getSocketName s >>= \ sockaddr ->
176 return (case sockaddr of
177 SockAddrInet port _ ->