[Python-bugs-list] Re: socket left in FIN_WAIT_2 state (PR#108)
guido@CNRI.Reston.VA.US
guido@CNRI.Reston.VA.US
Tue, 19 Oct 1999 01:01:55 -0400 (EDT)
> > > Using the SocketServer.TCPServer class, the request socket is
> > > being left in FIN_WAIT_2 state. Adding
> > > request.close()
> > > to the end of handle_request fixes it. I would guess this is
> > > actually a deficiency in the __del__ method of the socket object.
> >
> > Can you show a small sample program that exhibits this problem?
> > (How do I see that a socket is left in FIN_WAIT_2 state???)
> >
> > If the problem persists after the Python process has exited,
> > I would surmise that the problem is in the kernel -- sockets
> > are supposed to be closed when the process exits, aren't they?
>
> Hard to show code, but here's a description:
> >>> from socket import *
> >>> s=socket(AF_INET,SOCK_STREAM)
> >>> s.bind('',2001)
> >>> s.listen(5)
> >>> x=s.accept()
> The connection is established. The client now closes his end.
> This puts the server-side socket in FIN_WAIT2 state (this is normal).
> >>> del x
> This has no effect on the socket state.
>
> >>> x=s.accept()
> Establish another connection, and close the client side. Again,
> the socket goes to FIN_WAIT2.
> >>> x[0].close()
> This leaves the socket in normal TIME_WAIT state, the state of a
> closed connection.
I tried to reproduce this, and didn't succeed. The socket is left in
TIME_WAIT state the first time too.
My guess is that you are being fooled by reference counts and the "_"
variable with this example. If you typed x at the >>> prompt just
before you did "del x", the _ builtin variable holds a reference to
the object. This goes away when you display the value of some other
value (e.g. 0, but not None).
> It is true that the kernel will close all of the file descriptors when the
> process exits, but sockets are special because of the TCP protocol, and if
> they are not closed by the user program, they do not go through the
> normal shutdown process.
>
> While sockets in FIN_WAIT2 don't hurt the system (they'll go away eventually),
> the reason I thought this is a library problem is that it seems to me that
> since the SocketServer code 'created' the socket -- via the accept() --
> it should probably close it also when the connection handler returns. I
> imagine there's room for conflicting opinions there, but that seems normal
> to me. It is not mentioned in the documentation whether the handler has
> the reponsibility of closing the connection.
>
> I mentioned the __del__ method because it seems that a reclaimed open
> socket should have close() applied to it like a function does. I
> see PySocketSock_dealloc() in socketmodule.c, which I would have thought
> is the deletion function, does call close(); that should make the above
> two cases the same (unless that's not the deletion function). But somehow
> the explicit Python-level close() call is causing a normal shutdown.
That is indeed the correct function.
The question now remains, why do you observe this behavior in
SocketServer? I still want to see the code you are actually using --
maybe there's a clue there. If not, I'll have to close this PR as
irreproducible...
--Guido van Rossum (home page: http://www.python.org/~guido/)