2 % (c) The GRASP/AQUA Project, Glasgow University, 1995, 1996
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
34 import SocketPrim hiding ( accept, socketPort )
35 import qualified SocketPrim ( accept, socketPort )
39 %***************************************************************************
41 \subsection[Socket-Setup]{High Level ``Setup'' functions}
43 %***************************************************************************
45 Calling $connectTo$ creates a client side socket which is
46 connected to the given host and port. The Protocol and socket type is
47 derived from the given port identifier. If a port number is given
48 then the result is always an internet family $Stream$ socket.
50 If the $PortID$ specifies a unix family socket and the $Hostname$
51 differs from that returned by $getHostname$ then an error is
52 raised. Alternatively an empty string may be given to $connectTo$
53 signalling that the current hostname applies.
57 Service String -- Service Name eg "ftp"
58 | PortNumber Int -- User defined Port Number
59 #ifndef cygwin32_TARGET_OS
60 | UnixSocket String -- Unix family socket in file system
63 type Hostname = String
64 -- Maybe consider this alternative.
65 -- data Hostname = Name String | IP Int Int Int Int
68 If more control over the socket type is required then $socketPrim$
69 should be used instead.
72 connectTo :: Hostname -- Hostname
73 -> PortID -- Port Identifier
74 -> IO Handle -- Connected Socket
76 connectTo hostname (Service serv) =
77 getProtocolNumber "tcp" >>= \ proto ->
78 socket AF_INET Stream proto >>= \ sock ->
79 getServicePortNumber serv >>= \ port ->
80 getHostByName hostname >>= \ (HostEntry _ _ _ haddrs) ->
81 connect sock (SockAddrInet port (head haddrs)) >>
82 socketToHandle sock ReadWriteMode >>= \ h ->
84 connectTo hostname (PortNumber port) =
85 getProtocolNumber "tcp" >>= \ proto ->
86 socket AF_INET Stream proto >>= \ sock ->
87 getHostByName hostname >>= \ (HostEntry _ _ _ haddrs) ->
88 connect sock (SockAddrInet port (head haddrs)) >>
89 socketToHandle sock ReadWriteMode
91 #ifndef cygwin32_TARGET_OS
92 connectTo _ (UnixSocket path) =
93 socket AF_UNIX Datagram 0 >>= \ sock ->
94 connect sock (SockAddrUnix path) >>
95 socketToHandle sock ReadWriteMode
100 The dual to the $connectTo$ call. This creates the server side
101 socket which has been bound to the specified port.
104 listenOn :: PortID -- Port Identifier
105 -> IO Socket -- Connected Socket
107 listenOn (Service serv) =
108 getProtocolNumber "tcp" >>= \ proto ->
109 socket AF_INET Stream proto >>= \ sock ->
110 getServicePortNumber serv >>= \ port ->
111 bindSocket sock (SockAddrInet port iNADDR_ANY) >>
112 listen sock maxListenQueue >>
114 listenOn (PortNumber port) =
115 getProtocolNumber "tcp" >>= \ proto ->
116 socket AF_INET Stream proto >>= \ sock ->
117 bindSocket sock (SockAddrInet port iNADDR_ANY) >>
118 listen sock maxListenQueue >>
120 #ifndef cygwin32_TARGET_OS
121 listenOn (UnixSocket path) =
122 socket AF_UNIX Datagram 0 >>= \ sock ->
123 bindSocket sock (SockAddrUnix path) >>
129 accept :: Socket -- Listening Socket
130 -> IO (Handle, -- StdIO Handle for read/write
131 HostName) -- HostName of Peer socket
134 SocketPrim.accept sock >>= \ (sock', (SockAddrInet _ haddr)) ->
135 getHostByAddr AF_INET haddr >>= \ (HostEntry peer _ _ _) ->
136 socketToHandle sock ReadWriteMode >>= \ handle ->
137 return (handle, peer)
140 Send and recived data from/to the given host and port number. These
141 should normally only be used where the socket will not be required for
144 Thse are wrappers around socket, bind, and listen.
147 sendTo :: Hostname -- Hostname
148 -> PortID -- Port Number
149 -> String -- Message to send
152 connectTo h p >>= \ s ->
156 recvFrom :: Hostname -- Hostname
157 -> PortID -- Port Number
158 -> IO String -- Received Data
160 listenOn port >>= \ s ->
163 SocketPrim.accept s >>= \ (s', (SockAddrInet _ haddr)) ->
164 getHostByAddr AF_INET haddr >>= \ (HostEntry peer _ _ _) ->
169 readSocketAll s' >>= \ msg ->
173 waiting >>= \ message ->
178 Access function returning the port type/id of socket.
181 socketPort :: Socket -> IO PortID
183 getSocketName s >>= \ sockaddr ->
184 return (case sockaddr of
185 SockAddrInet port _ ->
187 #ifndef cygwin32_TARGET_OS