I have an application which frequently fails to start with the message:
"Could not bind socket. Address and port are already in use."
This happens (for no apparent reason) often enough that it is time for me to
start investigating it.
When I got to my computer this morning, my Anti-Virus program (AVG) had a
message up that said my computer needed to restart to complete the update
process. But I wanted to check email and a few other things before
rebooting, so one of the first things I did was run the application, and
BOOM, I get the error. The application had not been running for at least a
day, and no other server applications use the same port. I have checked
"netstat -a" for any indication that the port is in use, but am never able
to find anything. Whenever this happens, I am forced to reboot the compute
to clear the cause (whatever it is) so I can run the application.
What the heck is going on, and is there anything I can do to fix it? Or is
it the operating system's fault?
I am using a recent snapshot of Indy9 with BCB6 on XP sp2.
Can anyone offer a solution or a path toward a solution?
Thank you,
- Dennis
If it helps to see some code, here is the code that I use to start the
server:
void TMyServer::Start()
{
if ( !TCPServer->Active )
{
TCPServer->ThreadClass = __classid(TMyPeerThread);
TCPServer->OnExecute = TCPServerExecute;
TCPServer->OnConnect = TCPClientConnect;
TCPServer->OnDisconnect = TCPClientDisconnect;
TCPServer->DefaultPort = FPort;
// Set up the bindings:
TCPServer->Bindings->Clear();
TIdSocketHandle *NewBinding = TCPServer->Bindings->Add();
NewBinding->IP = FHostAddress;
AnsiString HostAddress( "All Adapters" );
if ( !FHostAddress.IsEmpty() )
{
HostAddress = FHostAddress;
}
LogMsg( AnsiString().sprintf( "Starting server on <%s:%d>",
HostAddress.c_str(), FPort ) );
TCPServer->Active = true;
LogMsg( AnsiString().sprintf( "Started server on <%s:%d>",
HostAddress.c_str(), FPort ) );
}
}
- Dennis
> I have an application which frequently fails to start with the message:
>
> "Could not bind socket. Address and port are already in use."
That happens when you specify a local IP/Port to bind the socket to before
opening it, but the IP/Port is already in use by another socket.
> The application had not been running for at least a day, and no
> other server applications use the same port.
So this error is happening for a server socket and not a clien socket? Is
there anotehr instance of the app already running?
> I have checked "netstat -a" for any indication that the port is in
> use, but am never able to find anything.
Why not?
Gambit
Right, I am pretty sure I understand what the error means, I just don't
understand *why* I am getting it.
>> The application had not been running for at least a day, and no
>> other server applications use the same port.
>
> So this error is happening for a server socket and not a clien socket? Is
> there anotehr instance of the app already running?
Yes, that is correct, it is a server socket. But no, there are no other
instances of the application running, which is why the I'm asking the
question. (the application uses a mutex to prevent multiple instances)
>> I have checked "netstat -a" for any indication that the port is in
>> use, but am never able to find anything.
>
> Why not?
If I knew the answer to that, I wouldn't be asking the question in the first
place!! That's the whole point..."netstat -a" does not show any application
instances that reference the port number I am trying to open in my server.
So if netstat does *not* show the port is in use, why would the server
socket complain that it *is* in use? That's the essence of my question. I
can find no indication whatsoever that the port is in use, yet the server
complains. How can that be?
- Dennis
>>> I have checked "netstat -a" for any indication that the port is in
>>> use, but am never able to find anything.
>>
>> Why not?
>
> If I knew the answer to that, I wouldn't be asking the question in the
> first place!! That's the whole point..."netstat -a" does not show any
> application instances that reference the port number I am trying to open
> in my server. So if netstat does *not* show the port is in use, why would
> the server socket complain that it *is* in use? That's the essence of my
> question. I can find no indication whatsoever that the port is in use,
> yet the server complains. How can that be?
Oh, by the way, when the application is running normally, I *can* find the
port number listed with "netstat -a". So it is only strange cases when the
application gives the error and I cannot find the port number listed with
"netstat -a" that I am trying to understand.
- Dennis
> Right, I am pretty sure I understand what the error means,
> I just don't understand *why* I am getting it.
Well, there is only one reason *why* it happens - the IP/Port is already in
use somewhere else on the machine :-) *Why* the IP/Port is already in use
is a different issue.
> Yes, that is correct, it is a server socket.
Ok. Then you (or someone else) opened that IP/Port and didn't close it
before you tried to activate a new server on it.
> there are no other instances of the application running, which
> is why the I'm asking the question. (the application uses a
> mutex to prevent multiple instances)
That doesn't negate the possibility of the IP/Port being in use by a
previous instance, though. Maybe the previous instance crashed. Maybe it
didn't close its socket correctly.
> If I knew the answer to that, I wouldn't be asking the question
> in the first place!!
They way you worded your question did not explain why you couldn't find the
information.
> "netstat -a" does not show any application instances that
> reference the port number I am trying to open in my server.
No, but "netstat -b" will. Both "-a" and "-b" show socket statuses, though.
If you start your server on port 12345, and you see Port 12345 listed, then
you know that socket is in use, and what state it is in.
Something else to keep in mind - when a socket is closed, it is not FULLY
closed right away. The OS keeps it alive for an extra period of time in
order to ensure any pending data gets handled at the network layer. netstat
will show such sockets in the TIME_WAIT state. You can't bind a new socket
to the same IP/Port until the previous socket is completely closed and
released (which will take a few minutes), unless you use setsockopt() to
enable the SO_REUSEADDR flag on the new socket before binding it.
TIdTCPServer has a ReuseSocket property that you can set to rsTrue for that,
if you are trying to reactivate your server too quickly.
> So if netstat does *not* show the port is in use
It will, otherwise you would not be getting the error.
> why would the server socket complain that it *is* in use?
It wouldn't, if it is not in netstat's listing.
Gambit
But that's just it...I didn't!
> Something else to keep in mind - when a socket is closed, it is not FULLY
> closed right away. The OS keeps it alive for an extra period of time in
> order to ensure any pending data gets handled at the network layer.
Yes, I am aware of that. That is actually the reason I mentioned that it
was the first time I had run the app in over a day -- because that would
have been more than enough time for the OS to close the socket.
>> So if netstat does *not* show the port is in use
>
> It will, otherwise you would not be getting the error.
>
>> why would the server socket complain that it *is* in use?
>
> It wouldn't, if it is not in netstat's listing.
So you keep saying. And in fact, that is exactly the reason I checked
netstat in the first place. I assumed netstat would be accurate (but maybe
it's not). The fact that netstat does not show the port in use is the only
reason I asked the question to begin with. If netstat had listed the port,
it would have been obvious that there was a problem with closing the socket
and I wouldn't have bothered posting here!
The only potential cause that I can think of is if I happened to forcibly
close the application yesterday (via the integrated debugger, for instance,
using Ctrl+F2), though I have no recollection of doing that (I don't even
remember running the app yseterday). But even if I did, that still does not
explain why "netstat -a" does not show the port number in use!
So, being certain that netstat does not show the port in use, and being
certain that the app is not already running, what would you suggest I do the
next time this occurs? I'd really like to get to the bottom of this because
rebooting the machine when it happens is a real nuisance.
- Dennis
> But that's just it...I didn't!
Like I said, you *or something else on the machine* had to have done it.
"Address and port are already in use" does not occur if the IP/Port was not
previously bound to a socket.
> Yes, I am aware of that. That is actually the reason I mentioned
> that it was the first time I had run the app in over a day -- because
> that would have been more than enough time for the OS to close
> the socket.
Another socket on the machine is using the same IP/Port that you want to
use. Either your previous server instance is still active, or another
program has created its own socket, or a local firewall is blocking the
binding. Those are the only possibilities for that particular error to
occur.
> So you keep saying. And in fact, that is exactly the reason I checked
> netstat in the first place. I assumed netstat would be accurate (but
> maybe it's not).
It is.
> The fact that netstat does not show the port in use is the only reason I
> asked the question to begin with. If netstat had listed
> the port, it would have been obvious that there was a problem
> with closing the socket and I wouldn't have bothered posting here!
Are you sure you are looking for the port that you are actually using in
your code? What exactly are you setting for the IP/Port of your server?
Please show your actual code.
> So, being certain that netstat does not show the port in use, and
> being certain that the app is not already running, what would you
> suggest I do the next time this occurs?
The error is not possible under those conditions. Bound sockets can't hide
from netstat. They are either bound or they are not.
Gambit
> Are you sure you are looking for the port that you are actually using in
> your code?
Of course.
> What exactly are you setting for the IP/Port of your server?
The address is "" (an empty string). In this particular case, the port
number was 5018.
> Please show your actual code.
I *did* show my actual code -- see my second post in this thread.
>> So, being certain that netstat does not show the port in use, and
>> being certain that the app is not already running, what would you
>> suggest I do the next time this occurs?
>
> The error is not possible under those conditions. Bound sockets can't
> hide from netstat.
So you say, but there are only two possibilities:
1) The port number is listed but I fail to see it every single time I look
for it
2) The port number is not listed
I don't know which it is, but it's not #1! :-)
The next time this happens (I'll try to induce it), I'll post netstat's
output for you.
- Dennis
> The address is "" (an empty string).
That will bind the server to all available IP addresses on the machine.
> In this particular case, the port number was 5018.
And port 5018 does not appear anywhere in netstat -a or -b for any IP
address or hostname while the error is occuring?
Gambit
Yes, because that's exactly what I want. The application allows the user to
choose from one or more specific adapters (if desired), or "Any Available"
adapter, in which case "" (empty string) is used to allow client connections
from any adapter, regardless of its IP address.
>> In this particular case, the port number was 5018.
>
> And port 5018 does not appear anywhere in netstat -a or -b for any IP
> address or hostname while the error is occuring?
Yes, that is correct. That's what's so frustrating about the whole thing.
If netstat -a showed me that the port was in use, then at least I would know
where to start looking. But since it doesn't, I don't know if the problem
is due to my application (failing to close the socket correctly in some
unusual circumstance), or the OS doing something funky, or if it is
something else entirely.
It seems reasonable that it could be caused by me killing the application
since I do that on occasion via the debugger, but the error usually occurs
when there has been such a long period of time since I last ran the
application, that any memory of what I was doing at the time (or of how I
closed it) has long since been forgotten.
I guess all I can do now is wait until it happens again and then see if I
can find some way to figure out what's causing it. Any suggestions on how
to go about doing would be most welcome. In the meantime, do you know of
any way to clear the socket so that the IP/port can be used without having
to reboot the machine?
Thanks for your time, Remy.
- Dennis
I have taken some code from a Code Project
article (i think) and adapted it for C++ Builder 6.
What this code does is enumerates all networking
applications and what port they are using and how.
What I do with it is auto assign ports to my application
instances using ports NOT in the list.
Also, under Win 2000, you cannot get the application
names, however 2003 Server and Win XP allows you
to see what application is using what port (and how).
NOT SUPPORTED IN 98/95.
Check the Attachments group.
Here is a code sample of a grid and edit box
on a form.
//-------------------------------------------------
// form with a StringGrid (renamed Grid1)
// and an Edit box
//-------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
TNetstatX * NetstatX = new TNetstatX;
int n=0;
Grid1->Cells[n++][0] = "Type";
Grid1->Cells[n++][0] = "State";
Grid1->Cells[n++][0] = "Local Address";
Grid1->Cells[n++][0] = "Local Port";
Grid1->Cells[n++][0] = "Remote Address";
Grid1->Cells[n++][0] = "Remote Port";
Grid1->Cells[n++][0] = "pid";
Grid1->Cells[n++][0] = "Process";
NetstatX->Enumerate();
Grid1->RowCount = NetstatX->ENCPQty+1;
for (int i=0; i<NetstatX->ENCPQty; i++)
{
int n=0;
Grid1->Cells[n++][i+1] = NetstatX->ShowIfTCP(NetstatX->ENCP[i].IsTCP);
Grid1->Cells[n++][i+1] =
NetstatX->ShowTCPState(NetstatX->ENCP[i].State);
Grid1->Cells[n++][i+1] = NetstatX->ENCP[i].LocalAddr;
Grid1->Cells[n++][i+1] = NetstatX->ENCP[i].LocalPort;
Grid1->Cells[n++][i+1] = NetstatX->ENCP[i].RemoteAddr;
Grid1->Cells[n++][i+1] = NetstatX->ENCP[i].RemotePort;
Grid1->Cells[n++][i+1] = NetstatX->ENCP[i].pid;
Grid1->Cells[n++][i+1] = NetstatX->ENCP[i].ProcessName;
}
Edit1->Text = NetstatX->UsedTCPPorts();
delete NetstatX;
> do you know of any way to clear the socket
You can't. It is under the OS's control.
> so that the IP/port can be used without having to reboot the machine?
I answered that several replies ago - set the server's ReuseSocket property
to rsTrue.
Gambit
Oh, yes, I saw that. Will that work even if the socket had been closed
incorrectly/abnormally?
- Dennis
> Will that work even if the socket had been closed incorrectly/abnormally?
I don't know. I never tried reusing a socket that was in an incorrect state
before.
Gambit
> Also, under Win 2000, you cannot get the
> application names
TCPView from SysInternals
(http://www.microsoft.com/technet/sysinternals/Networking/TcpView.mspx) is
able to do that (even before Microsoft took over SysInternals), and can do
so all the way back to NT4. So it is technically possible to do.
Gambit
Also isn't it a bummer Uncle Microsoft removed
the sysInternals Code, just when was getting
interested in it.
Also I did save me some code from the old sites
and IMHO I think some of their code contributed
to rootkit development.
The application will start again and we will have 2 instances as proccesses
globaly...
Lets say the one has a TServer socket listening (active) in a port...
By switching user and trying to run the app again we will have THAT
SYMPTOM...
There is an article by myself at http://bcbjournal.com, in this month's
issue I hope, using that for a global single instance of an application in a
windows PC...
Usually a crashed application with a TServer socket active has allready
released the port, if not after the first attempt and *crash* or catching of
the exception raised the next time will work properly....
A simple way to find out if a port is in use is to try to connect a TClient
socket to that port using "localhost" as the host name...
George Tokas.
>>> In this particular case, the port number was 5018.
>>
>> And port 5018 does not appear anywhere in netstat -a or -b for any IP
>> address or hostname while the error is occuring?
>
> Yes, that is correct. That's what's so frustrating about the whole thing.
> If netstat -a showed me that the port was in use, then at least I would
> know where to start looking. But since it doesn't, I don't know if the
> problem is due to my application (failing to close the socket correctly in
> some unusual circumstance), or the OS doing something funky, or if it is
> something else entirely.
>
> I guess all I can do now is wait until it happens again and then see if I
> can find some way to figure out what's causing it. Any suggestions on how
> to go about doing would be most welcome. In the meantime, do you know of
> any way to clear the socket so that the IP/port can be used without having
> to reboot the machine?
Okay, it happened again. My application failed to open a socket on port
5018. I immediately went to a command prompt and invoked "netstat -a".
Here is the output (some identifying address information has been blocked
out). You will note that there is no entry for port 5018 anywhere in the
list, and yet I get "Could not bind socket. Address and port are already in
use." I also checked all of the named ports to discver their numeric
equivelent. None of them are port 5018.
Active Connections
Proto Local Address Foreign Address State
TCP djones_xp:epmap djones_xp:0 LISTENING
TCP djones_xp:microsoft-ds djones_xp:0 LISTENING
TCP djones_xp:902 djones_xp:0 LISTENING
TCP djones_xp:912 djones_xp:0 LISTENING
TCP djones_xp:1030 djones_xp:0 LISTENING
TCP djones_xp:2401 djones_xp:0 LISTENING
TCP djones_xp:3389 djones_xp:0 LISTENING
TCP djones_xp:8222 djones_xp:0 LISTENING
TCP djones_xp:8333 djones_xp:0 LISTENING
TCP djones_xp:1066 djones_xp:0 LISTENING
TCP djones_xp:2402 djones_xp:0 LISTENING
TCP djones_xp:3690 djones_xp:0 LISTENING
TCP djones_xp:4564 localhost:4565 ESTABLISHED
TCP djones_xp:4565 localhost:4564 ESTABLISHED
TCP djones_xp:4566 localhost:4567 ESTABLISHED
TCP djones_xp:4567 localhost:4566 ESTABLISHED
TCP djones_xp:10025 djones_xp:0 LISTENING
TCP djones_xp:10110 djones_xp:0 LISTENING
TCP djones_xp:10110 localhost:1419 TIME_WAIT
TCP djones_xp:10110 localhost:1421 TIME_WAIT
TCP djones_xp:10110 localhost:1423 TIME_WAIT
TCP djones_xp:10110 localhost:1425 TIME_WAIT
TCP djones_xp:10110 localhost:1427 TIME_WAIT
TCP djones_xp:10110 localhost:1430 TIME_WAIT
TCP djones_xp:10110 localhost:1432 TIME_WAIT
TCP djones_xp:10110 localhost:1436 TIME_WAIT
TCP djones_xp:10110 localhost:1438 TIME_WAIT
TCP djones_xp:10110 localhost:1440 TIME_WAIT
TCP djones_xp:62332 djones_xp:0 LISTENING
TCP djones_xp:netbios-ssn djones_xp:0 LISTENING
TCP djones_xp:netbios-ssn 192.168.1.50:3572 ESTABLISHED
TCP djones_xp:1025 192.168.1.2:microsoft-ds ESTABLISHED
TCP djones_xp:1027 neutron:microsoft-ds ESTABLISHED
TCP djones_xp:1037 207.224.24.86:2108 ESTABLISHED
TCP djones_xp:1069 cs21.msg.dcn.yahoo.com:5050 ESTABLISHED
TCP djones_xp:1071 by1msg3145602.phx.gbl:1863 ESTABLISHED
TCP djones_xp:1073 205.188.9.108:5190 ESTABLISHED
TCP djones_xp:1076 oam-d19c.blue.aol.com:5190 ESTABLISHED
TCP djones_xp:1396 by2msg1262105.phx.gbl:1863 ESTABLISHED
TCP djones_xp:1420 incoming.verizon.net:pop3 TIME_WAIT
TCP djones_xp:1422
static-xx-xxx-xxx-xx.ptldor.fios.verizon.net:pop3 TIME_WAIT
TCP djones_xp:1424
static-xx-xxx-xxx-xx.ptldor.fios.verizon.net:pop3 TIME_WAIT
TCP djones_xp:1426
static-xx-xxx-xxx-xx.ptldor.fios.verizon.net:pop3 TIME_WAIT
TCP djones_xp:1428
static-xx-xxx-xxx-xx.ptldor.fios.verizon.net:pop3 TIME_WAIT
TCP djones_xp:1429 209.213.221.138:4050 TIME_WAIT
TCP djones_xp:1431 incoming.verizon.net:pop3 TIME_WAIT
TCP djones_xp:1437
static-xx-xxx-xxx-xx.ptldor.fios.verizon.net:pop3 TIME_WAIT
TCP djones_xp:1439
static-xx-xxx-xxx-xx.ptldor.fios.verizon.net:pop3 TIME_WAIT
TCP djones_xp:1441
static-xx-xxx-xxx-xx.ptldor.fios.verizon.net:pop3 TIME_WAIT
TCP djones_xp:2315 neutron:2324 ESTABLISHED
TCP djones_xp:3243 soft-gems.net:nntp ESTABLISHED
TCP djones_xp:3978 aqaserver.automatedqa.com:nntp ESTABLISHED
TCP djones_xp:4025 nexusdb.com:nntp ESTABLISHED
TCP djones_xp:4265 207.105.83.62:563 ESTABLISHED
TCP djones_xp:4605 qb-in-f99.google.com:http CLOSE_WAIT
TCP djones_xp:4686 192.168.1.2:5900 ESTABLISHED
UDP djones_xp:epmap *:*
UDP djones_xp:microsoft-ds *:*
UDP djones_xp:isakmp *:*
UDP djones_xp:1029 *:*
UDP djones_xp:1035 *:*
UDP djones_xp:1494 *:*
UDP djones_xp:2241 *:*
UDP djones_xp:3343 *:*
UDP djones_xp:3456 *:*
UDP djones_xp:4500 *:*
UDP djones_xp:5353 *:*
UDP djones_xp:ntp *:*
UDP djones_xp:1900 *:*
UDP djones_xp:2636 *:*
UDP djones_xp:4373 *:*
UDP djones_xp:ntp *:*
UDP djones_xp:netbios-ns *:*
UDP djones_xp:netbios-dgm *:*
UDP djones_xp:ntp *:*
UDP djones_xp:1900 *:*
- Dennis