> On 2001-07-27 00:59:12 -0700, David Schwartz wrote:
> > > IIRC, close() never blocks. Unlike open(), connect(), and so on,
> > > there is on special handling for close() when O_NDELAY/O_NONBLOCK is
> > > set. Scary warnings in the close() man page aside, close() is
> > > probably the most benign of all I/O calls.
> > Since close is the last system call you normally use to access a
> > socket, it is the underlying network protocol implementation's last
> > chance to tell you if you have succeeded or failed. As a result, there
> > are many circumstances under which the 'close' system call will block
> > until the underlying network protocol can receive acknowledgements for
> > all outstanding buffered data and shutdown the underlying connection.
> > It is generally considered good practice to use the 'shutdown' system
> > call to shutdown the underlying network connection under program
> > control. The 'close' system call should be used to deallocate the file
> > descriptor.
> This is an interesting theory, but in practice close() on a socket (at
> least, on a SOCK_STREAM) does not wait for for the session to breakdown,
> unless you have requested it by setting the linger socket option. I've
> been programming Unix TCP networks for a while now (8 years or so), and
> this is simply a non-issue.
What is a non-issue? And how many operating systems have you programmed on?
There are _definitely_ operating systems where failure to cleanly shutdown a
network connection can cause problems with the data that was pending when
you called 'close'.
> But don't take my word for it - you can try the attached program. It
> connects to the specified port, sleeps, then sends some data and calls
> close(). What I did was connect to a local web server, pull my network
> cable, and watch it complete. *No errors were reported by any system
> calls, even with linger enabled.* The close() did delay 10 seconds (as
> requested by the linger parameter), but then happily returned "no
> error".
That's because you called 'close' before you shutdown the underlying
network connection. As I said, it's good practice to call 'shutdown', then
continue to attempt to read on the network connection until 'read' returns
zero or an error. Once the underlying network transport is shut down, you
call 'close'.
> If you either remove the write() or the setsockopt(), then it will
> always return immediately.
> Now, I ran this on a Linux system (it's the box on my desk, so testing
> is easy), so the semantics *might* vary on other platforms. But I doubt
> it. Again I say unto you, just close() those sockets! ;)
It definitely does. For example, note this excerpt from the Winsock FAQ:
"
2.10 - What's the proper way to close a TCP socket?
The proper sequence for closing a TCP connection is:
Finish sending data.
Call shutdown() with the how parameter set to 1.
Loop on recv() until it returns 0.
Call closesocket().
Skipping the first and third steps above can cause data loss.
Nonblocking or asynchronous sockets complicate the first and third steps.
You can either build 'finish sending/receiving' logic into your normal I/O
loop, or you can temporarily put the socket in blocking mode and do the last
bits of I/O that way. The proper choice depends on your program's
architecture and requirements.
"
Do you want to write portable code that always works or not?
DS
______________________________________________________________________
GNU Portable Threads (Pth) http://www.gnu.org/software/pth/
User Support Mailing List [EMAIL PROTECTED]
Automated List Manager (Majordomo) [EMAIL PROTECTED]