This is the mail archive of the cygwin@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: data in socketpair() channel lost if writer closes or exits without shutting down


>  Date: Mon, 16 Jul 2001 09:52:58 +0200
>  From: Corinna Vinschen <cygwin@cygwin.com>
>  
>  Thanks for figuring that out. I would be very interested in this
>  piece of documentation. Could you give me a pointer?

The MSDN page documenting the "closesocket" function says, "Note: To
assure that all data is sent and received on a connection, an
application should call shutdown before calling closesocket."

I believe you're right that the default SO_DONTLINGER behavior will do
the right thing *if the process that called closesocket() stays
running until all the data has been received by the other end of the
connection*.  The problem is that much of the time, a process closes
its sockets when it's cleaning up and about to exit, i.e., it doesn't
hang around afterwards for long enough for the data to be received at
the other end.

The reason why things are different if the process exits is because
Winsock runs in user space.  Windows can't leave something around
finishing up with data transmission after the process exits.  On Unix,
on the other hand, sockets are handled in the kernel, and the kernel
will happily maintain that state and finish transmitting the data even
after the process which sent it is gone.

When I was investigating this, I should have paid more attention to
SO_LINGER and SO_DONTLINGER.  I suppose that another potential fix to
this problem, independent of calling shutdown as I previously
suggested, is to set the SO_LINGER option with a nonzero timeout, to
give the other end time to read the data before closesocket returns.
Of course, there are obvious problems with this -- the program calling
close will hang while closesocket is waiting for the data to finish
transmitting, and there's no way to pick a timeout which is (a) not
too large and (b) guaranteed to always allow data to finish being
transmitted when there's someone at the other end to receive it.

Perhaps as a compromise we could set SO_LINGER on all new sockets with
a short timeout, say a few seconds, to give data time to flush.

Or, slightly more complex but slightly more correct, keep track of
whether or not a socket was at some point shared between multiple
processes (either as a result of a fork or as a result of sending a
file descriptor between processes (does Cygwin support that?)).  When
a socket is first shared, we can set SO_LINGER as I described above.
Then, when a socket is closed, check if it was ever shared and call
shutdown if it wasn't.

>  The problem is, from what I read so far (which is basically the MSDN)
>  the default behaviour on closing a socket is to perform a graceful
>  shutdown with immediate return of the `closesocket' function (linger
>  "off"). I just have that page "Graceful Shutdown, Linger Options, and
>  Socket Closure" inside of MSDN, that's all.

Amusingly enough, the link to that page on the "closesocket" page is
invalid.

  jik

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]