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

CLinuxSockets

C Problem Overview


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$ 

C Solutions


Solution 1 - C

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.

Solution 2 - C

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

Solution 3 - C

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

Solution 4 - C

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.

Solution 5 - C

Just type

unlink [SOCKET NAME]

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

Solution 6 - C

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.

Solution 7 - C

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

Solution 8 - C

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: Https://myserver.domain.tld:9090

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDurinView Question on Stackoverflow
Solution 1 - CicfantvView Answer on Stackoverflow
Solution 2 - CSupameeView Answer on Stackoverflow
Solution 3 - ChipeView Answer on Stackoverflow
Solution 4 - CJérôme PouillerView Answer on Stackoverflow
Solution 5 - CprogrammerView Answer on Stackoverflow
Solution 6 - CClock ZHONGView Answer on Stackoverflow
Solution 7 - Cdr_begemotView Answer on Stackoverflow
Solution 8 - CJamesAD-0View Answer on Stackoverflow