Skip to content
This repository
Newer
Older
100644 468 lines (410 sloc) 15.445 kb
5925e5d2 » bos
2007-04-08 Invoke the preprocessor portably.
1 {-# LANGUAGE CPP #-}
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
2 -----------------------------------------------------------------------------
9b0175d9 » simonmar
2002-06-20 [project @ 2002-06-20 16:12:11 by simonmar]
3 -- |
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
4 -- Module : Network
5 -- Copyright : (c) The University of Glasgow 2001
b95d7abf » panne
2004-03-27 [project @ 2004-03-27 14:20:13 by panne]
6 -- License : BSD-style (see the file libraries/network/LICENSE)
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
7 --
8 -- Maintainer : libraries@haskell.org
9 -- Stability : provisional
10 -- Portability : portable
11 --
f27bd04b » simonmar
2002-06-21 [project @ 2002-06-21 13:53:19 by simonmar]
12 -- The "Network" interface is a \"higher-level\" interface to
13 -- networking facilities, and it is recommended unless you need the
14 -- lower-level interface in "Network.Socket".
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
15 --
16 -----------------------------------------------------------------------------
17
42baeef8 » bos
2007-04-04 Add IPv6 support to Network.
18 #include "HsNetworkConfig.h"
19
bcec0cc7 » Simon Marlow
2007-06-04 Fix further build problems when IPv6 isn't available
20 #ifdef HAVE_GETADDRINFO
42baeef8 » bos
2007-04-04 Add IPv6 support to Network.
21 -- Use IPv6-capable function definitions if the OS supports it.
22 #define IPV6_SOCKET_SUPPORT 1
23 #endif
24
cbdd6205 » tibbe
2010-12-10 Whitespace changes only: harmonize export lists
25 module Network
26 (
03f1a2bc » tibbe
2010-12-10 Whitespace changes only: harmonize export lists some
27 -- * Basic data types
cbdd6205 » tibbe
2010-12-10 Whitespace changes only: harmonize export lists
28 Socket
29 , PortID(..)
30 , HostName
31 , PortNumber
03f1a2bc » tibbe
2010-12-10 Whitespace changes only: harmonize export lists some
32
33 -- * Initialisation
cbdd6205 » tibbe
2010-12-10 Whitespace changes only: harmonize export lists
34 , withSocketsDo
03f1a2bc » tibbe
2010-12-10 Whitespace changes only: harmonize export lists some
35
36 -- * Server-side connections
cbdd6205 » tibbe
2010-12-10 Whitespace changes only: harmonize export lists
37 , listenOn
38 , accept
39 , sClose
03f1a2bc » tibbe
2010-12-10 Whitespace changes only: harmonize export lists some
40
41 -- * Client-side connections
cbdd6205 » tibbe
2010-12-10 Whitespace changes only: harmonize export lists
42 , connectTo
03f1a2bc » tibbe
2010-12-10 Whitespace changes only: harmonize export lists some
43
44 -- * Simple sending and receiving
45 {-$sendrecv-}
cbdd6205 » tibbe
2010-12-10 Whitespace changes only: harmonize export lists
46 , sendTo
47 , recvFrom
03f1a2bc » tibbe
2010-12-10 Whitespace changes only: harmonize export lists some
48
49 -- * Miscellaneous
cbdd6205 » tibbe
2010-12-10 Whitespace changes only: harmonize export lists
50 , socketPort
03f1a2bc » tibbe
2010-12-10 Whitespace changes only: harmonize export lists some
51
52 -- * Networking Issues
53 -- ** Buffering
54 {-$buffering-}
55
56 -- ** Improving I\/O Performance over sockets
57 {-$performance-}
58
59 -- ** @SIGPIPE@
60 {-$sigpipe-}
61 ) where
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
62
42baeef8 » bos
2007-04-04 Add IPv6 support to Network.
63 import Control.Monad (liftM)
d96a931a » bos
2009-05-20 Network.accept: avoid crash if getNameInfo fails
64 import Data.Maybe (fromJust)
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
65 import Network.BSD
ca025e02 » tibbe
2010-12-10 Whitespace changes only: make import lists more consistent
66 import Network.Socket hiding (accept, socketPort, recvFrom, sendTo, PortNumber)
67 import qualified Network.Socket as Socket (accept)
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
68 import System.IO
3af08715 » simonmar
2003-01-09 [project @ 2003-01-09 13:34:35 by simonmar]
69 import Prelude
8918908e » dcoutts
2007-10-18 Compatability with ghc-6.4
70 import qualified Control.Exception as Exception
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
71
72 -- ---------------------------------------------------------------------------
73 -- High Level ``Setup'' functions
74
75 -- If the @PortID@ specifies a unix family socket and the @Hostname@
76 -- differs from that returned by @getHostname@ then an error is
77 -- raised. Alternatively an empty string may be given to @connectTo@
78 -- signalling that the current hostname applies.
79
80 data PortID =
17e1cce7 » tibbe
2010-12-10 Whitespace changes only: use spaces consistently in Network
81 Service String -- Service Name eg "ftp"
82 | PortNumber PortNumber -- User defined Port Number
dfd451a4 » simonmar
2005-01-28 [project @ 2005-01-28 13:36:34 by simonmar]
83 #if !defined(mingw32_HOST_OS) && !defined(cygwin32_HOST_OS) && !defined(_WIN32)
17e1cce7 » tibbe
2010-12-10 Whitespace changes only: use spaces consistently in Network
84 | UnixSocket String -- Unix family socket in file system
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
85 #endif
86
f27bd04b » simonmar
2002-06-21 [project @ 2002-06-21 13:53:19 by simonmar]
87 -- | Calling 'connectTo' creates a client side socket which is
88 -- connected to the given host and port. The Protocol and socket type is
89 -- derived from the given port identifier. If a port number is given
90 -- then the result is always an internet family 'Stream' socket.
91
17e1cce7 » tibbe
2010-12-10 Whitespace changes only: use spaces consistently in Network
92 connectTo :: HostName -- Hostname
93 -> PortID -- Port Identifier
94 -> IO Handle -- Connected Socket
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
95
42baeef8 » bos
2007-04-04 Add IPv6 support to Network.
96 #if defined(IPV6_SOCKET_SUPPORT)
97 -- IPv6 and IPv4.
98
99 connectTo hostname (Service serv) = connect' hostname serv
100
101 connectTo hostname (PortNumber port) = connect' hostname (show port)
102 #else
103 -- IPv4 only.
104
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
105 connectTo hostname (Service serv) = do
3af08715 » simonmar
2003-01-09 [project @ 2003-01-09 13:34:35 by simonmar]
106 proto <- getProtocolNumber "tcp"
8918908e » dcoutts
2007-10-18 Compatability with ghc-6.4
107 bracketOnError
17e1cce7 » tibbe
2010-12-10 Whitespace changes only: use spaces consistently in Network
108 (socket AF_INET Stream proto)
109 (sClose) -- only done if there's an error
110 (\sock -> do
111 port <- getServicePortNumber serv
112 he <- getHostByName hostname
3af08715 » simonmar
2003-01-09 [project @ 2003-01-09 13:34:35 by simonmar]
113 connect sock (SockAddrInet port (hostAddress he))
114 socketToHandle sock ReadWriteMode
17e1cce7 » tibbe
2010-12-10 Whitespace changes only: use spaces consistently in Network
115 )
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
116
117 connectTo hostname (PortNumber port) = do
3af08715 » simonmar
2003-01-09 [project @ 2003-01-09 13:34:35 by simonmar]
118 proto <- getProtocolNumber "tcp"
8918908e » dcoutts
2007-10-18 Compatability with ghc-6.4
119 bracketOnError
17e1cce7 » tibbe
2010-12-10 Whitespace changes only: use spaces consistently in Network
120 (socket AF_INET Stream proto)
121 (sClose) -- only done if there's an error
3af08715 » simonmar
2003-01-09 [project @ 2003-01-09 13:34:35 by simonmar]
122 (\sock -> do
17e1cce7 » tibbe
2010-12-10 Whitespace changes only: use spaces consistently in Network
123 he <- getHostByName hostname
124 connect sock (SockAddrInet port (hostAddress he))
125 socketToHandle sock ReadWriteMode
126 )
42baeef8 » bos
2007-04-04 Add IPv6 support to Network.
127 #endif
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
128
dfd451a4 » simonmar
2005-01-28 [project @ 2005-01-28 13:36:34 by simonmar]
129 #if !defined(mingw32_HOST_OS) && !defined(cygwin32_HOST_OS) && !defined(_WIN32)
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
130 connectTo _ (UnixSocket path) = do
8918908e » dcoutts
2007-10-18 Compatability with ghc-6.4
131 bracketOnError
17e1cce7 » tibbe
2010-12-10 Whitespace changes only: use spaces consistently in Network
132 (socket AF_UNIX Stream 0)
133 (sClose)
134 (\sock -> do
3af08715 » simonmar
2003-01-09 [project @ 2003-01-09 13:34:35 by simonmar]
135 connect sock (SockAddrUnix path)
136 socketToHandle sock ReadWriteMode
17e1cce7 » tibbe
2010-12-10 Whitespace changes only: use spaces consistently in Network
137 )
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
138 #endif
139
42baeef8 » bos
2007-04-04 Add IPv6 support to Network.
140 #if defined(IPV6_SOCKET_SUPPORT)
141 connect' :: HostName -> ServiceName -> IO Handle
142
143 connect' host serv = do
144 proto <- getProtocolNumber "tcp"
145 let hints = defaultHints { addrFlags = [AI_ADDRCONFIG]
146 , addrProtocol = proto
147 , addrSocketType = Stream }
148 addrs <- getAddrInfo (Just hints) (Just host) (Just serv)
2dbde106 » feuerbach
2010-10-28 connectTo: try all addresses in turn rather than the first one
149 firstSuccessful $ map tryToConnect addrs
150 where
151 tryToConnect addr =
8918908e » dcoutts
2007-10-18 Compatability with ghc-6.4
152 bracketOnError
17e1cce7 » tibbe
2010-12-10 Whitespace changes only: use spaces consistently in Network
153 (socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr))
154 (sClose) -- only done if there's an error
155 (\sock -> do
42baeef8 » bos
2007-04-04 Add IPv6 support to Network.
156 connect sock (addrAddress addr)
157 socketToHandle sock ReadWriteMode
17e1cce7 » tibbe
2010-12-10 Whitespace changes only: use spaces consistently in Network
158 )
42baeef8 » bos
2007-04-04 Add IPv6 support to Network.
159 #endif
160
f27bd04b » simonmar
2002-06-21 [project @ 2002-06-21 13:53:19 by simonmar]
161 -- | Creates the server side socket which has been bound to the
51b2c5ae » kazu-yamamoto
2011-09-28 Network.Socket.socket takes care of IPV6_V6ONLY.
162 -- specified port.
f27bd04b » simonmar
2002-06-21 [project @ 2002-06-21 13:53:19 by simonmar]
163 --
164 -- NOTE: To avoid the \"Address already in use\"
165 -- problems popped up several times on the GHC-Users mailing list we
166 -- set the 'ReuseAddr' socket option on the listening socket. If you
167 -- don't want this behaviour, please use the lower level
168 -- 'Network.Socket.listen' instead.
51b2c5ae » kazu-yamamoto
2011-09-28 Network.Socket.socket takes care of IPV6_V6ONLY.
169 --
170 -- If available, the 'IPv6Only' socket option is set to 0
171 -- so that both IPv4 and IPv6 can be accepted with this socket.
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
172
17e1cce7 » tibbe
2010-12-10 Whitespace changes only: use spaces consistently in Network
173 listenOn :: PortID -- ^ Port Identifier
174 -> IO Socket -- ^ Connected Socket
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
175
42baeef8 » bos
2007-04-04 Add IPv6 support to Network.
176 #if defined(IPV6_SOCKET_SUPPORT)
177 -- IPv6 and IPv4.
178
179 listenOn (Service serv) = listen' serv
180
181 listenOn (PortNumber port) = listen' (show port)
182 #else
183 -- IPv4 only.
184
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
185 listenOn (Service serv) = do
3af08715 » simonmar
2003-01-09 [project @ 2003-01-09 13:34:35 by simonmar]
186 proto <- getProtocolNumber "tcp"
8918908e » dcoutts
2007-10-18 Compatability with ghc-6.4
187 bracketOnError
3af08715 » simonmar
2003-01-09 [project @ 2003-01-09 13:34:35 by simonmar]
188 (socket AF_INET Stream proto)
17e1cce7 » tibbe
2010-12-10 Whitespace changes only: use spaces consistently in Network
189 (sClose)
190 (\sock -> do
191 port <- getServicePortNumber serv
192 setSocketOption sock ReuseAddr 1
193 bindSocket sock (SockAddrInet port iNADDR_ANY)
194 listen sock maxListenQueue
195 return sock
196 )
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
197
198 listenOn (PortNumber port) = do
199 proto <- getProtocolNumber "tcp"
8918908e » dcoutts
2007-10-18 Compatability with ghc-6.4
200 bracketOnError
17e1cce7 » tibbe
2010-12-10 Whitespace changes only: use spaces consistently in Network
201 (socket AF_INET Stream proto)
202 (sClose)
203 (\sock -> do
204 setSocketOption sock ReuseAddr 1
205 bindSocket sock (SockAddrInet port iNADDR_ANY)
206 listen sock maxListenQueue
207 return sock
208 )
42baeef8 » bos
2007-04-04 Add IPv6 support to Network.
209 #endif
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
210
dfd451a4 » simonmar
2005-01-28 [project @ 2005-01-28 13:36:34 by simonmar]
211 #if !defined(mingw32_HOST_OS) && !defined(cygwin32_HOST_OS) && !defined(_WIN32)
3af08715 » simonmar
2003-01-09 [project @ 2003-01-09 13:34:35 by simonmar]
212 listenOn (UnixSocket path) =
8918908e » dcoutts
2007-10-18 Compatability with ghc-6.4
213 bracketOnError
17e1cce7 » tibbe
2010-12-10 Whitespace changes only: use spaces consistently in Network
214 (socket AF_UNIX Stream 0)
215 (sClose)
216 (\sock -> do
217 setSocketOption sock ReuseAddr 1
218 bindSocket sock (SockAddrUnix path)
219 listen sock maxListenQueue
220 return sock
221 )
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
222 #endif
223
42baeef8 » bos
2007-04-04 Add IPv6 support to Network.
224 #if defined(IPV6_SOCKET_SUPPORT)
225 listen' :: ServiceName -> IO Socket
226
227 listen' serv = do
228 proto <- getProtocolNumber "tcp"
e211930c » tibbe
2011-04-15 Some versions of eglibc adopted in Ubuntu has a bug in getaddrinfo.
229 -- We should probably specify addrFamily = AF_INET6 and the filter
230 -- code below should be removed. AI_ADDRCONFIG is probably not
231 -- necessary. But this code is well-tested. So, let's keep it.
42baeef8 » bos
2007-04-04 Add IPv6 support to Network.
232 let hints = defaultHints { addrFlags = [AI_ADDRCONFIG, AI_PASSIVE]
671ef211 » iquiw
2008-02-16 Fix listenOn and getNameInfo to work on NetBSD
233 , addrSocketType = Stream
42baeef8 » bos
2007-04-04 Add IPv6 support to Network.
234 , addrProtocol = proto }
235 addrs <- getAddrInfo (Just hints) Nothing (Just serv)
e211930c » tibbe
2011-04-15 Some versions of eglibc adopted in Ubuntu has a bug in getaddrinfo.
236 -- Choose an IPv6 socket if exists. This ensures the socket can
237 -- handle both IPv4 and IPv6 if v6only is false.
238 let addrs' = filter (\x -> addrFamily x == AF_INET6) addrs
239 addr = if null addrs' then head addrs else head addrs'
8918908e » dcoutts
2007-10-18 Compatability with ghc-6.4
240 bracketOnError
42baeef8 » bos
2007-04-04 Add IPv6 support to Network.
241 (socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr))
17e1cce7 » tibbe
2010-12-10 Whitespace changes only: use spaces consistently in Network
242 (sClose)
243 (\sock -> do
244 setSocketOption sock ReuseAddr 1
245 bindSocket sock (addrAddress addr)
246 listen sock maxListenQueue
247 return sock
248 )
42baeef8 » bos
2007-04-04 Add IPv6 support to Network.
249 #endif
250
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
251 -- -----------------------------------------------------------------------------
252 -- accept
253
f27bd04b » simonmar
2002-06-21 [project @ 2002-06-21 13:53:19 by simonmar]
254 -- | Accept a connection on a socket created by 'listenOn'. Normal
ec041a26 » igfoo
2008-03-25 Type (opertaions -> operations)
255 -- I\/O operations (see "System.IO") can be used on the 'Handle'
f27bd04b » simonmar
2002-06-21 [project @ 2002-06-21 13:53:19 by simonmar]
256 -- returned to communicate with the client.
42baeef8 » bos
2007-04-04 Add IPv6 support to Network.
257 -- Notice that although you can pass any Socket to Network.accept,
258 -- only sockets of either AF_UNIX, AF_INET, or AF_INET6 will work
259 -- (this shouldn't be a problem, though). When using AF_UNIX, HostName
260 -- will be set to the path of the socket and PortNumber to -1.
f27bd04b » simonmar
2002-06-21 [project @ 2002-06-21 13:53:19 by simonmar]
261 --
17e1cce7 » tibbe
2010-12-10 Whitespace changes only: use spaces consistently in Network
262 accept :: Socket -- ^ Listening Socket
f27bd04b » simonmar
2002-06-21 [project @ 2002-06-21 13:53:19 by simonmar]
263 -> IO (Handle,
17e1cce7 » tibbe
2010-12-10 Whitespace changes only: use spaces consistently in Network
264 HostName,
265 PortNumber) -- ^ Triple of: read\/write 'Handle' for
266 -- communicating with the client,
267 -- the 'HostName' of the peer socket, and
268 -- the 'PortNumber' of the remote connection.
31f09489 » stolz
2003-01-16 [project @ 2003-01-16 15:46:30 by stolz]
269 accept sock@(MkSocket _ AF_INET _ _ _) = do
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
270 ~(sock', (SockAddrInet port haddr)) <- Socket.accept sock
d25b5bb5 » igfoo
2008-08-05 Make network work with extensible exceptions
271 peer <- catchIO
17e1cce7 » tibbe
2010-12-10 Whitespace changes only: use spaces consistently in Network
272 (do
273 (HostEntry peer _ _ _) <- getHostByAddr AF_INET haddr
274 return peer
275 )
fa353d8f » kfish
2012-02-22 Fix warnings for unused variables
276 (\_e -> inet_ntoa haddr)
17e1cce7 » tibbe
2010-12-10 Whitespace changes only: use spaces consistently in Network
277 -- if getHostByName fails, we fall back to the IP address
da270017 » simonmar
2003-01-13 [project @ 2003-01-13 14:12:23 by simonmar]
278 handle <- socketToHandle sock' ReadWriteMode
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
279 return (handle, peer, port)
42baeef8 » bos
2007-04-04 Add IPv6 support to Network.
280 #if defined(IPV6_SOCKET_SUPPORT)
281 accept sock@(MkSocket _ AF_INET6 _ _ _) = do
282 (sock', addr) <- Socket.accept sock
d96a931a » bos
2009-05-20 Network.accept: avoid crash if getNameInfo fails
283 peer <- catchIO ((fromJust . fst) `liftM` getNameInfo [] True False addr) $
284 \_ -> case addr of
285 SockAddrInet _ a -> inet_ntoa a
286 SockAddrInet6 _ _ a _ -> return (show a)
287 # if !defined(mingw32_HOST_OS) && !defined(cygwin32_HOST_OS) && !defined(_WIN32)
288 SockAddrUnix a -> return a
289 # endif
42baeef8 » bos
2007-04-04 Add IPv6 support to Network.
290 handle <- socketToHandle sock' ReadWriteMode
66cf147a » bos
2009-05-20 Network.accept: return peer port number, not server's
291 let port = case addr of
292 SockAddrInet p _ -> p
293 SockAddrInet6 p _ _ _ -> p
294 _ -> -1
42baeef8 » bos
2007-04-04 Add IPv6 support to Network.
295 return (handle, peer, port)
296 #endif
dfd451a4 » simonmar
2005-01-28 [project @ 2005-01-28 13:36:34 by simonmar]
297 #if !defined(mingw32_HOST_OS) && !defined(cygwin32_HOST_OS) && !defined(_WIN32)
31f09489 » stolz
2003-01-16 [project @ 2003-01-16 15:46:30 by stolz]
298 accept sock@(MkSocket _ AF_UNIX _ _ _) = do
299 ~(sock', (SockAddrUnix path)) <- Socket.accept sock
300 handle <- socketToHandle sock' ReadWriteMode
301 return (handle, path, -1)
c1fa53e2 » sof
2003-01-17 [project @ 2003-01-17 16:34:02 by sof]
302 #endif
fa353d8f » kfish
2012-02-22 Fix warnings for unused variables
303 accept (MkSocket _ family _ _ _) =
31f09489 » stolz
2003-01-16 [project @ 2003-01-16 15:46:30 by stolz]
304 error $ "Sorry, address family " ++ (show family) ++ " is not supported!"
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
305
306 -- -----------------------------------------------------------------------------
307 -- sendTo/recvFrom
308
1711fddd » stolz
2004-08-12 [project @ 2004-08-12 07:22:45 by stolz]
309 {-$sendrecv
310 Send and receive data from\/to the given host and port number. These
311 should normally only be used where the socket will not be required for
312 further calls. Also, note that due to the use of 'hGetContents' in 'recvFrom'
313 the socket will remain open (i.e. not available) even if the function already
314 returned. Their use is strongly discouraged except for small test-applications
315 or invocations from the command line.
316 -}
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
317
17e1cce7 » tibbe
2010-12-10 Whitespace changes only: use spaces consistently in Network
318 sendTo :: HostName -- Hostname
319 -> PortID -- Port Number
320 -> String -- Message to send
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
321 -> IO ()
322 sendTo h p msg = do
323 s <- connectTo h p
324 hPutStr s msg
325 hClose s
326
17e1cce7 » tibbe
2010-12-10 Whitespace changes only: use spaces consistently in Network
327 recvFrom :: HostName -- Hostname
328 -> PortID -- Port Number
329 -> IO String -- Received Data
42baeef8 » bos
2007-04-04 Add IPv6 support to Network.
330
331 #if defined(IPV6_SOCKET_SUPPORT)
332 recvFrom host port = do
333 proto <- getProtocolNumber "tcp"
334 let hints = defaultHints { addrFlags = [AI_ADDRCONFIG]
335 , addrProtocol = proto
336 , addrSocketType = Stream }
337 allowed <- map addrAddress `liftM` getAddrInfo (Just hints) (Just host)
338 Nothing
339 s <- listenOn port
340 let waiting = do
341 (s', addr) <- Socket.accept s
342 if not (addr `oneOf` allowed)
343 then sClose s' >> waiting
344 else socketToHandle s' ReadMode >>= hGetContents
345 waiting
346 where
347 a@(SockAddrInet _ ha) `oneOf` ((SockAddrInet _ hb):bs)
348 | ha == hb = True
349 | otherwise = a `oneOf` bs
350 a@(SockAddrInet6 _ _ ha _) `oneOf` ((SockAddrInet6 _ _ hb _):bs)
351 | ha == hb = True
352 | otherwise = a `oneOf` bs
353 _ `oneOf` _ = False
354 #else
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
355 recvFrom host port = do
459910b1 » simonmar
2002-02-06 [project @ 2002-02-06 15:40:42 by simonmar]
356 ip <- getHostByName host
357 let ipHs = hostAddresses ip
358 s <- listenOn port
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
359 let
360 waiting = do
459910b1 » simonmar
2002-02-06 [project @ 2002-02-06 15:40:42 by simonmar]
361 ~(s', SockAddrInet _ haddr) <- Socket.accept s
362 he <- getHostByAddr AF_INET haddr
363 if not (any (`elem` ipHs) (hostAddresses he))
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
364 then do
365 sClose s'
366 waiting
367 else do
17e1cce7 » tibbe
2010-12-10 Whitespace changes only: use spaces consistently in Network
368 h <- socketToHandle s' ReadMode
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
369 msg <- hGetContents h
370 return msg
371
372 message <- waiting
373 return message
42baeef8 » bos
2007-04-04 Add IPv6 support to Network.
374 #endif
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
375
376 -- ---------------------------------------------------------------------------
377 -- Access function returning the port type/id of socket.
378
f27bd04b » simonmar
2002-06-21 [project @ 2002-06-21 13:53:19 by simonmar]
379 -- | Returns the 'PortID' associated with a given socket.
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
380 socketPort :: Socket -> IO PortID
381 socketPort s = do
382 sockaddr <- getSocketName s
383 return (portID sockaddr)
384 where
385 portID sa =
386 case sa of
42baeef8 » bos
2007-04-04 Add IPv6 support to Network.
387 SockAddrInet port _ -> PortNumber port
388 #if defined(IPV6_SOCKET_SUPPORT)
389 SockAddrInet6 port _ _ _ -> PortNumber port
390 #endif
dfd451a4 » simonmar
2005-01-28 [project @ 2005-01-28 13:36:34 by simonmar]
391 #if !defined(mingw32_HOST_OS) && !defined(cygwin32_HOST_OS) && !defined(_WIN32)
17e1cce7 » tibbe
2010-12-10 Whitespace changes only: use spaces consistently in Network
392 SockAddrUnix path -> UnixSocket path
efb0e791 » simonmar
2001-08-01 [project @ 2001-08-01 13:33:27 by simonmar]
393 #endif
f27bd04b » simonmar
2002-06-21 [project @ 2002-06-21 13:53:19 by simonmar]
394
8918908e » dcoutts
2007-10-18 Compatability with ghc-6.4
395 -- ---------------------------------------------------------------------------
396 -- Utils
397
398 -- Like bracket, but only performs the final action if there was an
399 -- exception raised by the middle bit.
400 bracketOnError
401 :: IO a -- ^ computation to run first (\"acquire resource\")
402 -> (a -> IO b) -- ^ computation to run last (\"release resource\")
403 -> (a -> IO c) -- ^ computation to run in-between
404 -> IO c -- returns the value from the in-between computation
0961a08b » kfish
2012-02-22 Add missing type signatures
405 #if __GLASGOW_HASKELL__ && __GLASGOW_HASKELL__ < 606
8918908e » dcoutts
2007-10-18 Compatability with ghc-6.4
406 bracketOnError before after thing =
407 Exception.block (do
408 a <- before
409 r <- Exception.catch
410 (Exception.unblock (thing a))
411 (\e -> do { after a; Exception.throw e })
412 return r
413 )
414 #else
415 bracketOnError = Exception.bracketOnError
416 #endif
417
f27bd04b » simonmar
2002-06-21 [project @ 2002-06-21 13:53:19 by simonmar]
418 -----------------------------------------------------------------------------
419 -- Extra documentation
420
421 {-$buffering
422
423 The 'Handle' returned by 'connectTo' and 'accept' is block-buffered by
424 default. For an interactive application you may want to set the
425 buffering mode on the 'Handle' to
426 'LineBuffering' or 'NoBuffering', like so:
427
428 > h <- connectTo host port
429 > hSetBuffering h LineBuffering
430 -}
431
432 {-$performance
433
434 For really fast I\/O, it might be worth looking at the 'hGetBuf' and
435 'hPutBuf' family of functions in "System.IO".
436 -}
437
438 {-$sigpipe
439
a2acb2e8 » simonmar
2005-04-28 [project @ 2005-04-28 08:45:41 by simonmar]
440 On Unix, when writing to a socket and the reading end is
f27bd04b » simonmar
2002-06-21 [project @ 2002-06-21 13:53:19 by simonmar]
441 closed by the remote client, the program is normally sent a
442 @SIGPIPE@ signal by the operating system. The
443 default behaviour when a @SIGPIPE@ is received is
444 to terminate the program silently, which can be somewhat confusing
445 if you haven't encountered this before. The solution is to
446 specify that @SIGPIPE@ is to be ignored, using
447 the POSIX library:
448
449 > import Posix
450 > main = do installHandler sigPIPE Ignore Nothing; ...
451 -}
d25b5bb5 » igfoo
2008-08-05 Make network work with extensible exceptions
452
453 catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a
9f06ef8c » Johan Tibell
2010-11-11 Use more exact package dependencies and remove the need for CPP args
454 #if MIN_VERSION_base(4,0,0)
d25b5bb5 » igfoo
2008-08-05 Make network work with extensible exceptions
455 catchIO = Exception.catch
3aa03655 » dcoutts
2008-10-22 Make it work with base 3 or 4
456 #else
457 catchIO = Exception.catchJust Exception.ioErrors
458 #endif
d25b5bb5 » igfoo
2008-08-05 Make network work with extensible exceptions
459
2dbde106 » feuerbach
2010-10-28 connectTo: try all addresses in turn rather than the first one
460 -- Returns the first action from a list which does not throw an exception.
461 -- If all the actions throw exceptions (and the list of actions is not empty),
462 -- the last exception is thrown.
463 firstSuccessful :: [IO a] -> IO a
464 firstSuccessful [] = error "firstSuccessful: empty list"
465 firstSuccessful (p:ps) = catchIO p $ \e ->
466 case ps of
467 [] -> Exception.throw e
468 _ -> firstSuccessful ps
Something went wrong with that request. Please try again.