Error: Address already in use while binding socket with address but the port number is shown free by `netstat`
CLinuxSocketsC 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:
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:
-
I had to disable selinux
-
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