curl-library
RE: Running out of sockets
Date: Fri, 3 Dec 2004 11:42:44 -0800
From: Goswin von Brederlow [mailto:brederlo_at_informatik.uni-tuebingen.de]
>> My application needs to send data (via FTP) to multiple machines (500+).
>> Once we got to the 500+ mark we started getting an "Failed to upload file
>> 'x' couldn't create socket" error. Looking into my application I found
that
>500 uploads mean 500 control connections and 500 data connections. The
>usual limit of filedescriptors is 1024 and there is also stdin, stdout
>and stderr. So, the 511th upload should already fail.
> If you mus increas the number of filedescriptors you may use. But I
> would change to another protocol, ftp is evil.
>> using libCURL to make this FTP transaction results in 4 sockets. Other
>> actions being taken by my application take this socket count up to 13 per
>> machine being transferred to, not counting other overhead sockets that
are
>> used for database and http connections. Now each transfer takes less
than 1
>> second and I'm setup to distribute to 8 machines at a time (forked
>> processes).
> Are all those sockets alive or just lingering around harmlessly for
> their reuse timeout?
To answer your question the socket are only in use (in the scenario where we
encountered the problem) for about 1 second and are then in a TIME_WAIT
state for about 1 minute. These connections are only used to push the data,
we don't expect anything back from the receiving machine, and the receiving
machine gets rebooted as soon as the transfer completes.
>> Looking at my network statistics I see my sockets end up hanging around
for
>> approximately 1 minute from the time of release. What I want to know is,
is
>> there a way to force my operating system (Linux - Red Hat) to release
those
>> connections as soon as I'm done with them? I'm sure this isn't really a
>> libCURL issue, but I thought this would be the best place to get an
answer.
> Set the socket to be reused after closing: (translating to C left for
> the reader)
> void Socket::reuse() { // Reuse address
> unsigned int one = 1;
> if (::setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) ==
-1) {
> int err = errno;
> fprintf(stderr, "Socket::Socket: setsockopt SO_REUSEADDR failed:
%m\n");
> throw err;
> }
> }
What exactly will be happening behind the scenes with your example. Will
the next (or some subsequent) connection use that socket instead of creating
a new one? Doesn't reusing a socket usually have to do with connecting to
the same address at the other end? The standard usage of this code is to
distribute to 8 units at a time and then reboot them, if we can have the
sockets for those 8 units only exist while they are in use that would be
ideal. Is that what the example you supplied would make happen?
Thanks,
Rob
Received on 2004-12-03