Network, sClose

Glynn Clements glynn.clements at virgin.net
Wed Aug 11 09:19:07 EDT 2004


Bayley, Alistair wrote:

> > However, even if sClose was exported, that wouldn't be of any 
> > help in Jon's case, as neither of the sockets which recvFrom 
> > creates are visible outside of recvFrom.
> 
> Ahh, OK. I haven't used recvFrom/sendTo yet... (trying it now) ... When I
> try Jon's example with 6.2.1 (Win XP) I don't get the same error; it works
> twice and then hangs (my networking code would hang if I tried to re-use a
> socket that hadn't been properly closed).

Odd.

> 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

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.

A subsequent call to recvFrom would call listenOn again, attempting to
create another listening socket on the same address and port. 
Obviously, that should fail so long as the original socket still
exists (the kernel doesn't know that the original socket can't ever be
used again).

> Jon's second example uses listenOn/accept and handles, which is also what I
> used:
> 
> >    do sock <- listenOn$PortNumber 7607; (hdl,host,port)<- accept sock; 
> > s<-IO.hGetContents hdl; putStr$s; IO.hClose hdl; Network.Socket.sClose 
> > sock
> 
> Network.Socket.sClose is obviously useful here, so don't you think it would
> be a good idea to put it in Network? I don't see why including sClose would
> imply that you should start exposing other low-level stuff. AFAICT, it is
> the one little thing that's missing from Network that makes writing simple
> networking code possible.
> 
> There's a lack of symmetry (closure?): you can create a socket with
> Network.listenOn, but there is no corresponding close function in Network.

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.

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.

-- 
Glynn Clements <glynn.clements at virgin.net>


More information about the Glasgow-haskell-users mailing list