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
34 import SocketPrim hiding ( accept, socketPort, recvFrom, sendTo )
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 PortNumber -- 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) = do
77 proto <- getProtocolNumber "tcp"
78 sock <- socket AF_INET Stream proto
79 port <- getServicePortNumber serv
80 he <- getHostByName hostname
81 connect sock (SockAddrInet port (hostAddress he))
82 socketToHandle sock ReadWriteMode
84 connectTo hostname (PortNumber port) = do
85 proto <- getProtocolNumber "tcp"
86 sock <- socket AF_INET Stream proto
87 he <- getHostByName hostname
88 connect sock (SockAddrInet port (hostAddress he))
89 socketToHandle sock ReadWriteMode
91 #ifndef cygwin32_TARGET_OS
92 connectTo _ (UnixSocket path) = do
93 sock <- socket AF_UNIX Datagram 0
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) = do
108 proto <- getProtocolNumber "tcp"
109 sock <- socket AF_INET Stream proto
110 port <- getServicePortNumber serv
111 bindSocket sock (SockAddrInet port iNADDR_ANY)
112 listen sock maxListenQueue
115 listenOn (PortNumber port) = do
116 proto <- getProtocolNumber "tcp"
117 sock <- socket AF_INET Stream proto
118 bindSocket sock (SockAddrInet port iNADDR_ANY)
119 listen sock maxListenQueue
122 #ifndef cygwin32_TARGET_OS
123 listenOn (UnixSocket path) = do
124 sock <- socket AF_UNIX Datagram 0
125 bindSocket sock (SockAddrUnix path)
131 accept :: Socket -- Listening Socket
132 -> IO (Handle, -- StdIO Handle for read/write
133 HostName) -- HostName of Peer socket
135 ~(sock', (SockAddrInet _ haddr)) <- SocketPrim.accept sock
136 (HostEntry peer _ _ _) <- getHostByAddr AF_INET haddr
137 handle <- socketToHandle sock' ReadWriteMode
138 return (handle, peer)
142 Send and recived data from/to the given host and port number. These
143 should normally only be used where the socket will not be required for
146 Thse are wrappers around socket, bind, and listen.
149 sendTo :: Hostname -- Hostname
150 -> PortID -- Port Number
151 -> String -- Message to send
158 recvFrom :: Hostname -- Hostname
159 -> PortID -- Port Number
160 -> IO String -- Received Data
161 recvFrom host port = do
165 ~(s', SockAddrInet _ haddr) <- SocketPrim.accept s
166 (HostEntry peer _ _ _) <- getHostByAddr AF_INET haddr
172 msg <- readSocketAll s'
182 Access function returning the port type/id of socket.
185 socketPort :: Socket -> IO PortID
187 sockaddr <- getSocketName s
188 return (portID sockaddr)
192 SockAddrInet port _ -> PortNumber port
193 #ifndef cygwin32_TARGET_OS
194 SockAddrUnix path -> UnixSocket path