Network, sClose

Jon Fairbairn Jon.Fairbairn at
Wed Aug 11 12:29:36 EDT 2004

On 2004-08-11 at 14:19BST Glynn Clements wrote:
> Bayley, Alistair wrote:
> > Is recvFrom meant to be a one-shot function i.e. the socket is only closed
> > when the process exits?
> The implementation is:
> > recvFrom host port = do
> >  ip  <- getHostByName host
> >  let ipHs = hostAddresses ip
> >  s   <- listenOn port
> >  let 
> >   waiting = do
> >      ~(s', SockAddrInet _ haddr)  <-  Socket.accept s
> >      he <- getHostByAddr AF_INET haddr
> >      if not (any (`elem` ipHs) (hostAddresses he))
> >       then do
> >          sClose s'
> >          waiting
> >       else do
> > 	h <- socketToHandle s' ReadMode
> >         msg <- hGetContents h
> >         return msg
> > 
> >  message <- waiting
> >  return message

This is rather more powerful than recvFrom in C, isn't it?
Perhaps it's misnamed: C's recvFrom deals with finite
messages, but with the above I can receive an infinite list,
which is the source of the problem, even if rather cool.

> Note that the listening socket s is passed to accept then
> forgotten about. If it was accessible, it would be
> possible to either accept further connections on it, or to
> close it. As it stands, it will remain open and unused for
> the duration of the calling process.

So the problem is the same as with hGetContents in general,
compounded by the calling programme not having access to the
socket, so it can't close it even if it knows it's finished
with the data.

> Right. If listenOn and accept are in Network, sClose should be in
> there too. That would at least provide an API which is usable for the
> simplest programs.

Agreed, and recvFrom seems to need to be something else,
though the problem could be ameliorated by making
withSocketsDo close
any leftover sockets. You'd then have to use it for both
Linux and Windows.

> OTOH, the core problem with Network.recvFrom is
> essentially that it appears to be a misguided attempt to
> provide a symmetric counterpart to Network.sendTo. While
> the low-level sendTo/recvFrom functions may be roughly
> symmetric, at a higher level, the client and server ends
> of a connection aren't at all symmetric.

Given that, recvFrom could :: HostName -> Socket -> IO
String.  We'd have to call listenOn to get the socket, but
that seems a small hardship compared to losing the use of
the port.

[1] What's the "Do" doing there anyway? You end up writing
withSocketsDo$do, and we could do without the Do$do.

Jón Fairbairn                                 Jon.Fairbairn at

More information about the Glasgow-haskell-users mailing list