Durin
Durin

Reputation: 2150

Error: Address already in use while binding socket with address but the port number is shown free by `netstat`

I tried to bind my socket(server socket) at port number 8000. It worked and did the job for me. At the end of the code I close the socket as well. The very next instant I run my code again and it shows me that the address is already in use. I have printed the meaning of error values strerror(errno); to see if my code working properly at each point. To check if the port is free I checked it using netstat but it shows that port number 8000 is free. It has happened with me a lot of times. Every time I then wait for a few more secs and then it starts working again. I am using c language. So what is he reason for this behavior by my OS.

After a few more secs I run the code and then it works.

anirudh@anirudh-Aspire-5920:~/Desktop/testing$ sudo ./a.out 
Socket Creation: Success
File open: Success
Socket Bind: Address already in use
Socket Listen: Address already in use
^C
anirudh@anirudh-Aspire-5920:~/Desktop/testing$ sudo netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1348/lighttpd   
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      984/sshd        
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      1131/cupsd      
tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN      1211/mysqld     
tcp6       0      0 :::22                   :::*                    LISTEN      984/sshd        
tcp6       0      0 ::1:631                 :::*                    LISTEN      1131/cupsd      
anirudh@anirudh-Aspire-5920:~/Desktop/testing$ sudo ./a.out 
Socket Creation: Success
File open: Success
Socket Bind: Address already in use
Socket Listen: Address already in use
^C
anirudh@anirudh-Aspire-5920:~/Desktop/testing$ 

Upvotes: 81

Views: 232945

Answers (8)

icfantv
icfantv

Reputation: 4643

I've run into that same issue as well. It's because you're closing your connection to the socket, but not the socket itself. The socket can enter a TIME_WAIT state (to ensure all data has been transmitted, TCP guarantees delivery if possible) and take up to 4 minutes to release.

or, for a REALLY detailed/technical explanation, check this link

It's certainly annoying, but it's not a bug. See the comment from @Vereb on this answer below on the use of SO_REUSEADDR.

Upvotes: 87

dr_begemot
dr_begemot

Reputation: 153

For AF_UNIX you can use call unlink (path); after close() socket in "server" app

Upvotes: 0

James Danforth
James Danforth

Reputation: 827

the error i received was:

cockpit.socket: Failed to listen on sockets: Address already in use

the fix I discovered is:

  1. I had to disable selinux
  2. in /usr/lib/systemd/system/cockpit service i changed the line :

    #ExecStartPre=/usr/sbin/remotectl certificate --ensure --user=root --group=cockpit-ws --selinux-type=etc_t
    

    to:

    #ExecStartPre=/usr/sbin/remotectl certificate --ensure --user=root --group=cockpit-ws 
    

so as you can see i took out the argument about selinux then i ran:

systemctl daemon-reload
systemctl start cockpit.service

then I browsed to:

I accepted the self-signed certificate and was able to login successfully to cockpit and use it normally.

this is all on a fedora25 machine. the 9090 port had already been added using firewall-cmd

Upvotes: -4

Jérôme Pouiller
Jérôme Pouiller

Reputation: 10267

As already said, your socket probably enter in TIME_WAIT state. This issue is well described by Thomas A. Fine here.

To summary, socket closing process follow diagram below:

Socket closing process

Thomas says:

Looking at the diagram above, it is clear that TIME_WAIT can be avoided if the remote end initiates the closure. So the server can avoid problems by letting the client close first. The application protocol must be designed so that the client knows when to close. The server can safely close in response to an EOF from the client, however it will also need to set a timeout when it is expecting an EOF in case the client has left the network ungracefully. In many cases simply waiting a few seconds before the server closes will be adequate.

Using SO_REUSEADDR is commonly suggested on internet, but Thomas add:

Oddly, using SO_REUSEADDR can actually lead to more difficult "address already in use" errors. SO_REUSADDR permits you to use a port that is stuck in TIME_WAIT, but you still can not use that port to establish a connection to the last place it connected to. What? Suppose I pick local port 1010, and connect to foobar.com port 300, and then close locally, leaving that port in TIME_WAIT. I can reuse local port 1010 right away to connect to anywhere except for foobar.com port 300.

Upvotes: 19

Supamee
Supamee

Reputation: 635

I know its been a while since the question was asked but I was able to find a solution:

int sockfd;
int option = 1;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));

This set the socket able to be reused immediately.

I apologize if this is "wrong". I'm not very experienced with sockets

Upvotes: 37

programmer
programmer

Reputation: 127

Just type

unlink [SOCKET NAME]

in the terminal, then the error should no longer exist.

Upvotes: 10

Clock ZHONG
Clock ZHONG

Reputation: 1000

Even icfantv's answer to this question is already perfect, I still have more findings in my test.

As a server socket in listening status, if it only in listening status, and even it accepts request and getting data from the client side, but without any data sending action. We still could restart the server at once after it's stopped. But if any data sending action happens in the server side to the client, the same service(same port) restart will have this error: (Address already in use).

I think this is caused by the TCP/IP design principles. When the server send the data back to client, it must ensure the data sending succeed, in order to do this, the OS(Linux) need monitor the connection even the server application closed this socket. But I still believe kernel socket designer could improve this issue.

Upvotes: 2

hipe
hipe

Reputation: 822

Try netstat like this: netstat -ntp, without the -l. It will show tcp connection in TIME_WAIT state.

Upvotes: 27

Related Questions