77

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$ 
Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
Durin
  • 2,070
  • 5
  • 23
  • 37
  • Do you also carefully close all connections that were made to the server while it was running? – rogerdpack Oct 11 '18 at 19:45
  • Crosslink: Related question on Server Fault: [linux - How to forcibly close a socket in TIME_WAIT? - Server Fault](https://serverfault.com/questions/329845/how-to-forcibly-close-a-socket-in-time-wait) – user202729 Dec 22 '22 at 08:44

8 Answers8

81

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.

icfantv
  • 4,523
  • 7
  • 36
  • 53
  • 18
    there is a possible solution on the page you linked. You can use the SO_REUSEADDR option for the socket. see setsockopt here: http://linux.die.net/man/3/setsockopt – Vereb Jan 27 '13 at 14:30
36

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

Supamee
  • 615
  • 5
  • 15
  • 2
    I like how you put `wrong` in quotes, implying that anyone who disagrees with you is wrong. – byxor Feb 08 '17 at 11:29
  • 17
    the quotes were more of an "if it works it's not wrong" kind of thing. I realize that probably not the preferred way and if anyone knows the "correct" way I would be interested to hear. – Supamee Mar 27 '17 at 14:30
  • 4
    what does the 1 mean? – Moritz Schmidt Aug 13 '18 at 07:22
  • 3
    It was a while ago so if I'm wrong please correct me, but I believe that's used because when you want the socket to not linger that must be "non-zero". I couldn't find anything concrete but you can read more about it at : https://www.ibm.com/support/knowledgecenter/en/SSB23S_1.1.0.15/gtpc2/cpp_setsockopt.html – Supamee Aug 13 '18 at 14:01
26

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

hipe
  • 802
  • 6
  • 8
16

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.

Jérôme Pouiller
  • 9,249
  • 5
  • 39
  • 47
10

Just type

unlink [SOCKET NAME]

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

Falko
  • 17,076
  • 13
  • 60
  • 105
programmer
  • 127
  • 1
  • 4
1

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.

Clock ZHONG
  • 875
  • 9
  • 23
0

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

dr_begemot
  • 133
  • 1
  • 2
  • 7
-3

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

sebix
  • 2,943
  • 2
  • 28
  • 43
James Danforth
  • 781
  • 7
  • 7