UNIX Socket FAQ

A forum for questions and answers about network programming on Linux and all other Unix-like systems

You are not logged in.

#1 2006-09-07 08:05 AM

kiranmai
Member
Registered: 2006-09-07
Posts: 2

Re: Bind() failed: Address already in use

Hi,

I am getting

Bind Failed: Address already in use

I have added

int yes=1;

  if (setsockopt(gTestSocket,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1)
        {
                perror("setsockopt");
                return FALSE;
        }
Still Iam getting the same error.

Offline

#2 2006-09-07 01:15 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,759
Website

Re: Bind() failed: Address already in use

Then, you probably have some other program (maybe another copy of the same
one?) already bound to that port...  Do "netstat -a" and look for it...

Setting SO_REUSEADDR only lets you bind() if there are no other truly active
listening sockets for that port...  Typically, the only real use for it is to be able to
bind() when there are still TIME_WAIT state sockets bound to that port, from a
previous incarnation of the server...  But, it won't let two active apps bind() to the
same port (on the same IP), if that's what you're trying to do...

Offline

#3 2006-09-08 05:21 AM

kiranmai
Member
Registered: 2006-09-07
Posts: 2

Re: Bind() failed: Address already in use

Hi RobSeace

Thanks for your reply.

Actually i have terminated the program abnormally using ctrl+z. So the socket was not closed. Now if I run the program again it gives bind() failed:address already in use.

when i do netstat -a it gives that, that particular socket is connected but not listening.

I think i need to do some clean up to close the socket when the program terminated abnormally..

Is there any unix command that kills or closes the socket from command prompt.

Offline

#4 2006-09-08 01:17 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,759
Website

Re: Bind() failed: Address already in use

Well, in most shells, CTRL-Z doesn't terminate an app, but rather suspends it...
Ie: it's still alive, but just 'stopped', and can be restarted again with "bg" or "fg"...
So, your app is still alive and holding the socket open...  If your app truly terminated,
then the OS would've closed the socket for you automatically...

Is there any unix command that kills or closes the socket from command prompt.

Well, it doesn't make sense to talk about killing a socket...  You can kill the app that
has the socket open, however...  Just use "kill" or "killall" or whatever...  Doing that
will close the socket...

Offline

#5 2007-02-19 04:11 PM

kumar_1122
Member
Registered: 2006-12-29
Posts: 14

Re: Bind() failed: Address already in use

Hi all,

I am also facing similar kind of problem.
Every time i login to new machine, my code is working fine.
If I run second time its giving bind failed.
Could you pls tell me how can I rectify this error.

Thanks in Advance,
kumar

Offline

#6 2007-02-19 04:40 PM

biologz
Administrator
From: Puking on the pavement
Registered: 2005-11-02
Posts: 393

Re: Bind() failed: Address already in use

Hi,

Is the error message "bind failed: adress already in use"?

If yes, so just read what Rob said...You have to close your socket before launching your app a second time or just change the port number.

As Rob already said:

it won't let two active apps bind() to the
same port (on the same IP)


gethostbyintuition() is still a dream of mine

                                                 -- quoted from bash

Offline

#7 2007-02-19 05:18 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,759
Website

Re: Bind() failed: Address already in use

Right...  And, if you truly ARE killing the first app that was bound to that port before
starting the second one, then you probably are simply not setting SO_REUSEADDR
properly...  That's something you pretty much always want to set in server code
for any listening sockets...  Otherwise, old TIME_WAIT sockets from the previous
incarnation of the server can block you from binding...

Offline

#8 2007-02-20 07:47 AM

kumar_1122
Member
Registered: 2006-12-29
Posts: 14

Re: Bind() failed: Address already in use

Thanks for your replies.

My problem is little different. In my case when I run my application for the second time, bind returns -1 and then I am exiting the appliation. I dont know how to close the existing sockets manually so that I can continue my work without rebooting the system.
I am sure first application got closed before running the second time(I ran ps from command line). I was under assumption, that exiting application will close all the sockets.
Moreover I am using UNIX domain sockets. I am using 2 sockets one for control and the other for data. Should I close both sockets if read error occurs in one of the sockets ?

Please help me in this ,...

Thanks in Advance,
kumar

Offline

#9 2007-02-20 01:18 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,759
Website

Re: Bind() failed: Address already in use

Oh, Unix domain sockets...  Why didn't you mention that right from the start??
That's a completely different kettle of fish...  We were discussing TCP sockets...

The problem there then is that you're leaving the socket file still in existence...
You can't bind() to a socket file that already exists...  And, the OS will not automatically
delete your Unix domain socket files for you...  Yes, it will CLOSE your socket FDs,
but Unix domain socket files are a different beast...  They will remain existing in
the filesystem, until you manually unlink() them in your app, which your server
should do before exiting...

Alternatively, if your system allows for abstract Unix domain sockets (those without
a real socket file anywhere in the filesystem), you can use those and not have to
worry about the problem at all...  (Eg: on Linux, set the first byte of "sun_path" to
'\0', then the remainder, for whatever length you specify, becomes the abstract
name of the socket...  You can use it just like any other Unix domain socket, but
there simply is no real on-filesystem socket file associated with it...  When you close
the socket bound to that abstract name, it ceases to exist...)

Offline

#10 2007-02-20 02:54 PM

kumar_1122
Member
Registered: 2006-12-29
Posts: 14

Re: Bind() failed: Address already in use

Thanks a lot RobSeace !!

That problem is solved now after using unlink. I have one more problem.
As per my design, I need to close and open data channel from the client side.
When I open data channel second time from client side, connect returns success. but on server side it gets blocked at accept. when I exit the application on client side, then it is coming out of accept and printing some of the messages from client side. I got struck over this issue over many days. please help me out !!

Offline

#11 2007-02-20 06:11 PM

i3839
Oddministrator
From: Amsterdam
Registered: 2003-06-07
Posts: 2,200

Re: Bind() failed: Address already in use

Post your code, that would make thing much easier to debug. At least the relevant parts anyway, if it's too much.

Offline

#12 2007-02-20 07:50 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,759
Website

Re: Bind() failed: Address already in use

Yeah, without code, all we can do is wildly guess...

So, my wild guess is that the server isn't really blocking in accept() at all, but rather
blocking in read()/recv() or something similar on another socket FD related to that
client, and then when you kill the client, it finally exits that call and gets around to
really doing the accept() finally...

Offline

#13 2007-02-21 07:30 AM

kumar_1122
Member
Registered: 2006-12-29
Posts: 14

Re: Bind() failed: Address already in use

Hi,

I have changed my design a little bit. Now the problem is I am able to open data channel on both sides then writing data from client side. But my server not reading the data. here i have attached my server code.
Please suggest if I need to make any other changes in my code.

Thanks a lot for the help !!

Offline

#14 2007-02-21 10:16 AM

i3839
Oddministrator
From: Amsterdam
Registered: 2003-06-07
Posts: 2,200

Re: Bind() failed: Address already in use

Erm, why are you sending a doc file? Eww!

Offline

#15 2007-02-21 02:12 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,759
Website

Re: Bind() failed: Address already in use

Um, yeah...  I don't do ".DOC"...  So, how about some plain-text ASCII goodness,
if you want any help...  (Can you compile that DOC file?  No...  Then, it's of absolutely
no value whatsoever as far as code is concerned...)

Offline

#16 2007-02-21 02:33 PM

kumar_1122
Member
Registered: 2006-12-29
Posts: 14

Re: Bind() failed: Address already in use

hi,

You want me to post the code here itself ? I didn't understand :(

/* I have opened sock_fd[0] and sock_fd[1] already once. Depending on need I have to close and open sock_fd[1] and transfer/receive bulk of data  */
while (1)
        {
        rset = rset1;
                FD_SET(sock_fd[0],&rset);
        if(sock_fd[1] != -1)
                    FD_SET(sock_fd[1],&rset);
        FD_SET(serv_sock_fd, &rset);
                if(sock_fd[0] > serv_sock_fd)
                    maxfd = sock_fd[0]+1;
                else
                    maxfd = serv_sock_fd+1;

                nready=select(maxfd,&rset,NULL,NULL,NULL);
                memset((void*)data_bytes,0,2048);

        if (FD_ISSET(serv_sock_fd,&rset))
        {
            printf("serv_sock_fd set.......\n");
                    client_len=sizeof(client_addr);
            if((new_sock = accept(serv_sock_fd,(struct sockaddr *)&client_addr,&client_len))<0)
                    {
                        printf("\naccept() failed");
                    exit(1);
                    }
                    printf("                .......connected");
            sock_fd[1] = new_sock;
            FD_SET(sock_fd[1],&rset);
            if (maxfd < sock_fd[1])
                maxfd = sock_fd[1]+1;
                printf("new data channel %d\n", sock_fd[1]);
                if(nready <= 1) continue;
        }

        if(FD_ISSET(sock_fd[0],&rset))
        {
                    msg_data_info sMsgInfo1 = {0};
                    int s1=0;
                    if((s1=read(sock_fd[0],(void *)/*&data_bytes*/&sMsgInfo1, sizeof(sMsgInfo1.data)))<0)
                    {
                            printf("CLIENT RESET\n");
                printf("ctrl Channel closed\n");
                        close(sock_fd[0]);
                exit(1);
                    }
                    memcpy((void*)&sMsgInfo, (void*)&sMsgInfo1, sizeof(msg_data_info));
                    process_command(&sMsgInfo);
        if(nready <= 1) continue;
               
        }

            if(FD_ISSET(sock_fd[1],&rset))
    {             
            printf("data channel set\n");
                msg_data_info sMsgInfo1 = {0};
                    int s=0;
                    if((s=read(sock_fd[1],(void *)&data_bytes/*&sMsgInfo1*/,sizeof(sMsgInfo1.data)))<0)
                        {
                                printf("CLIENT RESET\n");
                printf("Data Channel closed\n");
                close(sock_fd[1]);
                exit(1);
                        }
                                 /* process read message   */

        }
    }

Offline

#17 2007-02-21 03:08 PM

biologz
Administrator
From: Puking on the pavement
Registered: 2005-11-02
Posts: 393

Re: Bind() failed: Address already in use

Before they tell you something, and because i also want to increase my numer of posts,

use code tags aroung any code sample as it is written in bold letters when you post something :-)


gethostbyintuition() is still a dream of mine

                                                 -- quoted from bash

Offline

#18 2007-02-21 03:38 PM

i3839
Oddministrator
From: Amsterdam
Registered: 2003-06-07
Posts: 2,200

Re: Bind() failed: Address already in use

Well, using code tags doesn't help much if indentation is missing. Just copy and paste the text you're using to compile the thing, surely it has some whitespace to make it readable?

(Rob: You might like Antiword, a small and fast doc converter. It can spit out ASCII, postscript or pdf. Good enough to handle most doc files when you've no choice.)

Offline

#19 2007-02-21 07:47 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,759
Website

Re: Bind() failed: Address already in use

[Oh, I know there exist various methods of reading DOC files on Linux, but I just
really have no interest in dealing with the beastly things...  And, I just didn't feel
like going out of my way to read it... ;-)  I mean, I just never would've expected to
encounter anyone putting code into DOC format; the very concept melts my brain...]

Kumar, it wasn't that you attached it that was the problem; for big blocks of code,
it's often better to attach them (or post a link to it)...  But, the code should be plain
ASCII text, suitable for compilation (and easy universal reading)...  Preferably with
indentation still intact! ;-)

But, anyway...  Given that posted snippet of code, I see ONE problem, at least,
though I don't know if it's your current (or only) problem:

if(sock_fd[0] > serv_sock_fd)
maxfd = sock_fd[0]+1;
else
maxfd = serv_sock_fd+1;

I don't see any consideration of "sock_fd[1]" there, despite the fact that you MIGHT
have added it to the fd_set...  Do you inherently know that "sock_fd[1]" will always
be of lesser value than "sock_fd[0]"?  If not, that could certainly be a problem...
Ah, lower down when you do the accept(), I see you TRY to consider this case, but
the problem is that at the top of your loop, you wipe out the value of "maxfd" with
the above code again, so you're losing that consideration of "sock_fd[1]"...

Also, it looks like you assume your read()'s will always read a full message in a
single try, but that's not necessarily the case...  TCP is a stream protocol not a
datagram protocol...  Any given read() might read part or all of the requested amount,
and return values less than the requested amount are quite common (especially if
dealing with amounts larger than your current MSS)...

Also, this isn't a problem at all, but just one of my pet-peeves: There's no need to
cast to "void*"!  That's one of the main bloody POINTS of "void*": to be auto-casting
to/from any type of pointer!

Offline

#20 2007-02-22 11:43 AM

kumar_1122
Member
Registered: 2006-12-29
Posts: 14

Re: Bind() failed: Address already in use

Hi Rob,

Thanks a lot for the help !!

sorry for attaching .doc  :(

I tried with your suggestions. considering sock_fd[1] for maxfd and removed void*. Now it is working for 2nd, 3rd and sometimes upto 4th cycle. not more than that. It is not working for the first time. when I close and open data channel from client, then it starts working for the second and third cycles.

I am posting here both server and client code

One more doubt is when i close the socket on client side, do I need to close it on sever side as well ?

Offline

#21 2007-02-22 11:55 AM

kumar_1122
Member
Registered: 2006-12-29
Posts: 14

Re: Bind() failed: Address already in use

FD_ZERO(&rset1);
        while (1)
        {
        rset = rset1;
                         FD_SET(sock_fd[0],&rset);
        if(sock_fd[1] != -1)
                          FD_SET(sock_fd[1],&rset);
        FD_SET(serv_sock_fd, &rset);
                         if(sock_fd[0] > serv_sock_fd)
                              maxfd = sock_fd[0]+1;
                         else
                              maxfd = serv_sock_fd+1;
        if(sock_fd[1] > maxfd)
            maxfd = sock_fd[1]+1;

                         nready=select(maxfd,&rset,NULL,NULL,NULL);
                         memset(data_bytes,0,2048);
        if (FD_ISSET(serv_sock_fd,&rset))
        {
            printf("serv_sock_fd set.......\n");
                             client_len=sizeof(client_addr);
                             if((new_sock = accept(serv_sock_fd,(struct sockaddr*)&client_addr,&client_len))<0)
                            {
                                     printf("\naccept() failed");
                    exit(1);
                            }
                             printf("                .......connected");
            sock_fd[1] = new_sock;
            FD_SET(sock_fd[1],&rset);
            if (maxfd < sock_fd[1])
                maxfd = sock_fd[1]+1;
            printf("new data channel %d\n", sock_fd[1]);
            if(nready <= 1) continue;
        }

        if(FD_ISSET(sock_fd[0],&rset))
        {
                                 msg_data_info sMsgInfo1 = {0};
                                 int s1=0;
                                 if((s1=read(sock_fd[0],/*&data_bytes*/&sMsgInfo1,                         sizeof(sMsgInfo1.data)))<0)
                                {
                                     printf("CLIENT RESET\n");
                printf("ctrl Channel closed\n");
                                 close(sock_fd[0]);
                exit(1);
                                }
                                     /* process data read  */
            if(nready <= 1) continue;
               
        }

            if(FD_ISSET(sock_fd[1],&rset))
        {             
            printf("data channel set\n");
                              msg_data_info sMsgInfo1 = {0};
                                      int s=0;
                   if((s=read(sock_fd[1],&data_bytes/*&sMsgInfo1*/,
                    sizeof(sMsgInfo1.data)))<0)
                                       {
                                     printf("CLIENT RESET\n");
                printf("Data Channel closed\n");
                close(sock_fd[1]);
                exit(1);
                                }
            printf("no of b read : %d\n", s);
       
            /*process data read */               
            }
}

Offline

#22 2007-02-22 12:25 PM

kumar_1122
Member
Registered: 2006-12-29
Posts: 14

Re: Bind() failed: Address already in use

Hi Rob,

I have attached server and client code here.

Thanks,
kumar

Offline

#23 2007-02-22 03:15 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,759
Website

Re: Bind() failed: Address already in use

Well, that's better, in that at least it's readable plain text...  But, is there some reason
to only post little snippets of the code, rather than the whole thing?  Oftentimes, you
might find that the root of a problem is in bits of code that you least expect, so just
posting the bits of code you think are problematic may not reveal the real problem
(or, at least, all real problems)...

Your "maxfd" calculation still isn't right:

if(sock_fd[0] > serv_sock_fd)
                maxfd = sock_fd[0]+1;
            else
                maxfd = serv_sock_fd+1;
            if(sock_fd[1] > maxfd)
                maxfd = sock_fd[1]+1;

That last ">" needs to be ">=", because you're storing a value of FD+1 in there...
(Which makes the name highly misleading, BTW...  I would personally just store the
actual value of the highest FD in "maxfd", and then pass a value of "maxfd + 1" to
select()...  But, whatever...)

I don't see anything else wrong (that I haven't already commented on) in that
particular bit of code...  (Well, there's stuff like you not checking the return value
from select() for failure...  But, nothing SERIOUSLY wrong, which would likely be
responsible for your problems, anyway...)  But, like I say, the problem may very well
lie in the rest of the code you haven't posted...  (Unless it's really just that "maxfd"
problem causing everything... *shrug*)

One more doubt is when i close the socket on client side, do I need to close it on sever side as well ?

Um, yes, of course you do...  Otherwise, the server would leak file descriptors...

Offline

#24 2007-02-22 03:49 PM

kumar_1122
Member
Registered: 2006-12-29
Posts: 14

Re: Bind() failed: Address already in use

Hi RobSeace,

Its really gr8. you have magic eyes.
One more issue resolved. Now it is working for the first cycle also and running upto 5 cycles.

For the other query, how do server know that client has closed the socket ? Is it only when read returns -1. In my case read returns 0 continuously for some time when client closes the socket.  Is it correct to close socket when it returns 0. Could you pls throw some light in this area

Regarding posting complete code, it is too big. I will try to put more code tomorrow. Now i am rushing to home.
Thank you once again for gr8 help :)

Offline

#25 2007-02-22 07:27 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,759
Website

Re: Bind() failed: Address already in use

Yes, a return value of 0 from read()/recv() indicates normal closure of the socket by
the remote peer...  A return value of -1 indicates some error, which may mean an
abnormal closure of the socket (eg: due to network errors)...  (But, you have to check
errno in the case of negative return values, because it might be an expected soft
'error', such as EINTR or EAGAIN/EWOULDBLOCK...)  In either case (zero or a
negative return value with errno set to a non-expected hard error), you should close()
your socket FD...

Note: you also probably want to ignore SIGPIPE and check for errors on any
write()/send() you do, and close the socket in that case, as well...  (Ignoring SIGPIPE
is necessary, because otherwise your write()/send() might cause you to terminate,
because by default writing down a closed pipe or socket will cause you to be hit with
SIGPIPE...)

Offline

Board footer

Powered by FluxBB