Reclaiming used socket fd or how to close sockets properly

Reclaiming used socket fd or how to close sockets properly

Post by Stev » Wed, 17 May 2000 04:00:00



Hi all,

I have a question on how to reclaim used socket fd's or possibly it is how
to correctly close socket fd's so that they become available to the system
again.

I am running a server and client programs on Intel based PCs running RH
Linux 6.1 (and couple 6.2)

I eventually run out of socket file descriptors on my server program at
about fd = 64, even though I have only a few sockets open on my server at
that time.  I believe I am correctly closing sockets when I am done with
them (which I assume means that the resource would be given back to the
operating system).

My server program has several socket file descriptors open at once ( I use
select() to see if any are available for reading, or if there is a new
connection waiting on the listen socket), and occasionally the clients will
go away for what ever reason, and also new clients can join at any time.  If
a client dies or goes away, either explicitly (read() =0) or due to long
periods of inactivity(I have a tunable keep alive function), the server
calls shutdown(2) on that socket fd.  The argument 2 to shutdown being that
neither sending or receiving is allowed. The reason for using shutdown()
rather than close() was either based on something I read in the Stevens book
or one of the Unix socket FAQ's, don't remember which, having to do with
close only referring to the current thread and shutdown means that everyone
is done with the fd (although my app is a single thread so theoretically
either should work)

If a new client attempts to connect, the socket call returns a new file
descriptor which is always incrementing.  So as clients leave, and new
clients appear, the socket numbers increase until 64 at which time I get an
error which is something like "invalid file descriptor".

I know there is a way to increase the resources available system wide,
although I cant seem to find that reference, so feel free to remind me what
the command/syntax to increase resources is.  But even that is a stop gap
measure, since eventually I will run out of socket file descriptors again.

Based on what I need to do, spawning new processes like an http server, will
not work for me.  The only other solution that I could think of would be to
go to UDP exclusively and that way only one socket would be needed.
Although I would much prefer to figure out a way to make the operating
system recycle the no longer used socket file descriptors.

Any thought, or suggestions would be appreciated.

Thanks,

Steve
--
reply to newsgroup and/or reply to my hotmail address tigerman67

 
 
 

Reclaiming used socket fd or how to close sockets properly

Post by Andrew Giert » Wed, 17 May 2000 04:00:00


 Steve> If a client dies or goes away, either explicitly (read() =0)
 Steve> or due to long periods of inactivity(I have a tunable keep
 Steve> alive function), the server calls shutdown(2) on that socket
 Steve> fd.  The argument 2 to shutdown being that neither sending or
 Steve> receiving is allowed. The reason for using shutdown() rather
 Steve> than close()

shutdown() isn't sufficient on its own, you have to call close() as
well.

 Steve> was either based on something I read in the Stevens book or
 Steve> one of the Unix socket FAQ's, don't remember which, having to
 Steve> do with close only referring to the current thread and
 Steve> shutdown means that everyone is done with the fd (although my
 Steve> app is a single thread so theoretically either should work)

You've misunderstood.

Normally, a socket (or any other object referred to by a file
descriptor for that matter) remains open until all copies of the
descriptor that refer to it have been closed. At that point, the
connection is terminated if the socket is in a connected state.  What
shutdown() does is give you the ability to force the disconnection
(but _not_ the closing of the descriptor) to happen even if there
are multiple descriptors referring to the same socket.

--
Andrew.

comp.unix.programmer FAQ: see <URL: http://www.erlenstar.demon.co.uk/unix/>
                           or <URL: http://www.whitefang.com/unix/>

 
 
 

Reclaiming used socket fd or how to close sockets properly

Post by Barry Margoli » Wed, 17 May 2000 04:00:00




Quote:>You've misunderstood.

>Normally, a socket (or any other object referred to by a file
>descriptor for that matter) remains open until all copies of the
>descriptor that refer to it have been closed. At that point, the
>connection is terminated if the socket is in a connected state.  What
>shutdown() does is give you the ability to force the disconnection
>(but _not_ the closing of the descriptor) to happen even if there
>are multiple descriptors referring to the same socket.

Now *you've* misunderstood.

The purpose of shutdown() is to allow you to shut down a single direction
without closing the descriptor completely.  In particular, shutdown(fd, 1)
will send a FIN on the socket, so that the correspondent will read EOF;
this is useful in protocols where the server reads everything until EOF and
then sends a reply back over the same connection (if you used close() to
send the EOF, then you wouldn't be able to read the reply).

Although shutdown option 2 allows you to shut down both directions, I can't
think of a good use for this offhand (although I think I've read that
WinSock expects applications to call shutdown() before close() for some
reason).

--

Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

 
 
 

Reclaiming used socket fd or how to close sockets properly

Post by Andrew Giert » Wed, 17 May 2000 04:00:00


 >> Normally, a socket (or any other object referred to by a file
 >> descriptor for that matter) remains open until all copies of the
 >> descriptor that refer to it have been closed. At that point, the
 >> connection is terminated if the socket is in a connected state.  What
 >> shutdown() does is give you the ability to force the disconnection
 >> (but _not_ the closing of the descriptor) to happen even if there
 >> are multiple descriptors referring to the same socket.

 Barry> Now *you've* misunderstood.

Not so.

Please read my comment in the context of the original post, and with
reference to the information that he was recalling (somewhat
confusedly) about the effect of descriptor sharing (see for example
p.160 of Stevens UNP vol 1).

 Barry> The purpose of shutdown() is to allow you to shut down a
 Barry> single direction without closing the descriptor completely.

That is _one_ purpose of shutdown().

close() has two specific weaknesses as applied to sockets; the first
is that it can only affect both directions at once, the second is that
only the _last_ close has any effect at all, and if the descriptor has
been copied (either by dup(), descriptor passing, or inheritance by
another process) then a close() call has no effect. shutdown() gives
you the ability, if you need it, to initiate a disconnection in spite
of the presence of additional descriptors referring to the socket;
this should not often be an issue though.

--
Andrew.

comp.unix.programmer FAQ: see <URL: http://www.erlenstar.demon.co.uk/unix/>
                           or <URL: http://www.whitefang.com/unix/>

 
 
 

Reclaiming used socket fd or how to close sockets properly

Post by Kaz Kylhe » Wed, 17 May 2000 04:00:00





>>You've misunderstood.

>>Normally, a socket (or any other object referred to by a file
>>descriptor for that matter) remains open until all copies of the
>>descriptor that refer to it have been closed. At that point, the
>>connection is terminated if the socket is in a connected state.  What
>>shutdown() does is give you the ability to force the disconnection
>>(but _not_ the closing of the descriptor) to happen even if there
>>are multiple descriptors referring to the same socket.

>Now *you've* misunderstood.

>The purpose of shutdown() is to allow you to shut down a single direction
>without closing the descriptor completely.

In other words:

The shutdown function operates on the underlying communication protocol
to bring about a half-close.

The close function operates on the descriptor object to destroy it.

These are two fundamentally distinct opeations. One has to do with the
semantics of the communication, and the other has to do with local resource
management.

Note that close() does not imply the termination of the TCP connection. It's
possible for the connection to persist for some time, waiting for data to drain
to the other side. This is known as lingering, and can be controlled by
the SO_LINGER socket option.

--
#exclude <windows.h>

 
 
 

Reclaiming used socket fd or how to close sockets properly

Post by Barry Margoli » Wed, 17 May 2000 04:00:00




>Note that close() does not imply the termination of the TCP connection. It's
>possible for the connection to persist for some time, waiting for data to drain
>to the other side. This is known as lingering, and can be controlled by
>the SO_LINGER socket option.

However, when the connection is in this state, it's not using up a
descriptor in the caller's process.  Once close() returns, the descriptor
is available for reuse.  The socket is lingering anonymously in the kernel.

--

Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

 
 
 

Reclaiming used socket fd or how to close sockets properly

Post by emc.. » Wed, 17 May 2000 04:00:00


[close()d, but not shutdown(), sockets and lingering]

Quote:> However, when the connection is in this state, it's not using up a
> descriptor in the caller's process.  Once close() returns, the descriptor
> is available for reuse.  The socket is lingering anonymously in the kernel.

Is it possible to reclaim a lingering socket and reassociate it with a
file descriptor, or is it truly anonymous?

--

non-combatant, n.  A dead Quaker.
        - Ambrose Bierce, _The Devil's Dictionary_

 
 
 

Reclaiming used socket fd or how to close sockets properly

Post by Kaz Kylhe » Wed, 17 May 2000 04:00:00





>[close()d, but not shutdown(), sockets and lingering]

>> However, when the connection is in this state, it's not using up a
>> descriptor in the caller's process.  Once close() returns, the descriptor
>> is available for reuse.  The socket is lingering anonymously in the kernel.

>Is it possible to reclaim a lingering socket and reassociate it with a
>file descriptor, or is it truly anonymous?

What is lingering is a TCP connection object in the kernel, not a socket.
The term ``socket'' is not interchangeable with ``TCP connection''.

There is no means in the Berkeley socket interface to reopen a new socket
that is attached to an existing connection.

--
#exclude <windows.h>

 
 
 

Reclaiming used socket fd or how to close sockets properly

Post by Rich Gra » Thu, 18 May 2000 04:00:00





> >Note that close() does not imply the termination of the TCP connection. It's
> >possible for the connection to persist for some time, waiting for data to drain
> >to the other side. This is known as lingering, and can be controlled by
> >the SO_LINGER socket option.

> However, when the connection is in this state, it's not using up a
> descriptor in the caller's process.  Once close() returns, the descriptor
> is available for reuse.  The socket is lingering anonymously in the kernel.

> --

> Genuity, Burlington, MA
> *** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
> Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

And this can be a costly situation if you are in an on-demand (dial-up)
router environment to a long distance host.  The app is long gone, but
the TCP-connection is still there, so the line stays up.  That 5 minute
data squirt just became an all weekend long distance call!   Setting the
linger option is the way to guarantee the TCP-connection does terminate,
right?
 
 
 

1. When call shutdown(), how is socket fd closed?

I have read the source code about the system calls: close() and shutdown()
for closing a socket fd.  In sys_close(), __put_unused_fd() will be
called.  But sys_shutdown() function is :
                err=sock->ops->shutdown(sock, how);
                sockfd_put(sock);

socketfd_put() only calls fput(sock->file).

I can't find how to put unused fd.  I think that shutdown should do it.
May anyone tell me how shutdown() close the socket fd.

2. Help poor newbie with removable drive question

3. Closing socket fd

4. Solaris librairies

5. why parent close socket fd before child finish?

6. Vitrual Hosts with different access method

7. How do I properly close a socket connection?

8. DAC960PD Initialization Problem

9. JServ 1.1 sockets do not close properly

10. How do I properly close a socket connection?

11. help: close(socket) leaves socket bound ?

12. Sockets: server close leaves socket bound?

13. Sockets sockets and more sockets