A common socket programming error I hear about is error 98 (EADDRINUSE) or
10048 (WSAEADDRINUSE) from bind()
.
The Setup
Maybe you are programming a server in C or C++. Your socket code might use a setup like this:
//Cross-platform error code #if defined(_WIN32) #define GETSOCKETERRNO() (WSAGetLastError()) #else #define GETSOCKETERRNO() (errno) #endif //Set port to bind to. struct addrinfo *address; getaddrinfo(0, "8080", &hints, &address); //Create socket. SOCKET socket_listen; socket_listen = socket(address->ai_family, address->ai_socktype, address->ai_protocol); //Bind socket to local port. if (bind(socket_listen, address->ai_addr, address->ai_addrlen)) { fprintf(stderr, "bind() failed. Error: %d\n", GETSOCKETERRNO()); return 1; }
If your call to bind fails, the first thing to do is check the error code. The
error is stored in errno
on Linux, but on Windows you will need to call
WSAGetLastError()
.
If the error returned by bind()
is 98 (Linux) or 10048 (Windows), then it
means the local port you are trying to bind to is already in use.
Getting the Error Message
By the way, you can also get the error message in text form.
On Linux it is just a call to strerror()
. For error 98, that will return
something such as "Address already in use".
Getting the error text on Windows is a bit trickier. There are instructions on getting the Windows error text here. The error message on Windows may be similar to "Only one usage of each socket address (protocol/address/port) is normally permitted."
In any case, now that you know the what the error is, how do you fix it?
What causes "Address already in use error"
Basically, only one program can listen on a given protocol/address/port tuple at any given time. If more than one program were permitted to listen, then the operating system wouldn't know which program to send incoming connections to.
When I hear about this error from readers, there is usually one of three causes.
1. Another program is using that port
The most obvious cause for the error is that another program is using the port you want to listen on. In this case, you can change the port your program listens on, or you can close the other program that is using that port.
On Linux, you can see which other programs are listening for connections using
the netstat -ntlp
command. The ntlp
stands for "numeric tcp listen
programs". In order words, we are asking netstat
to show port numbers
(numeric), to only show TCP sockets, to only show sockets in the listening
state, and to show which programs are using the sockets.
The following screenshot shows using the netstat
command on Linux to find
which program is tying up port 8080.
As you can see above, the program tying up port 8080 is "server1" with a PID of 96939. Knowing the PID, you can easily kill the program if you like. Just please be sure you know what the program is and whether you really need it or not before you go around terminating things willy-nilly.
Windows also has a netstat
command, but the usage is different. On Windows
you can show all listening sockets with the command netstat -nao -p TCP | findstr LISTEN
. Window's netstat
command doesn't have an easy way to filter
only listening sockets, so the findstr
program comes in handy. In any case,
running that command will list each listening TCP socket and show the owner
program's PID for each socket.
The following screenshot shows the usage of netstat
on Windows to see which
program is using port 8080:
As shown in the above screenshot, netstat lists each program's listening
address and PID. You can get more info on a PID with the tasklist
command.
For example, running tasklist | findstr 50396
would get us the program name
for PID 50396 — the process we identified as using port 8080. For example:
The above screenshot shows that the program "server1.exe" has the PID of 50396, and therefore is the program using port 8080.
2. Your program is already running
This is more common than you think. Is your program already running? If it is, then of course the port is already in use!
This also isn't always as easy to determine as you might like. In the server
world, it's very common for programs to run in the background or as daemons. In
any case, if you get a bind()
error or address already in use error, be sure
to check that your program isn't already running.
3. TCP Linger / TIME-WAIT
I've saved the most complicated scenario for last. Suppose your server program is running, and then you terminate it (or it crashes). When you restart it, you get the address in use error (EADDRINUSE or WSAEADDRINUSE). However, if you wait a couple minutes, you are able to start your program without error. What is going on here?
I won't go into too much depth here (read my book for that), but basically when
a socket is closed it can go into a TIME-WAIT state on the end that initiated
the close. This isn't a problem for a client program, since it doesn't use
bind()
anyway (typically). However, this TIME-WAIT state can be a problem
for server applications. It means the operating system is still keeping track
of the closed socket, even after your entire program is closed. This is enough
to cause the "Address already in use" error if you restart your program.
Now, there is an easy way to prevent this error on Linux. You can use the
SO_REUSEADDR
socket option before calling bind()
. It looks like this:
int yes = 1; if (setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, (void*)&yes, sizeof(yes)) < 0) { fprintf(stderr, "setsockopt() failed. Error: %d\n", GETSOCKETERRNO()); }
This option will allow bind()
to succeed even if a few TIME-WAIT connections
are still around. There is very little downside to using the SO_REUSEADDR
on Linux, so
I suggest most server applications use it in that environment.
There is a major drawback to using this option on Windows. When using
SO_REUSEADDR
on Windows, the OS will simply allow multiple programs to bind
to the same port. When an incoming connection is routed, it will only go to one
program. This doesn't mean you shouldn't use SO_REUSEADDR
on Windows, but you
should certainly be aware of this behavior.
In any case, check out Chapter 13 of my book for more information.
Summary
If bind()
causes error 98 (EADDRINUSE) or 10048 (WSAEADDRINUSE), it means
you are trying to bind to a local port that is already in use. This is usually
caused by one of three reasons:
- Another program is already using that port.
- Your program is already running and you've attempted to start it a second time.
- Your program was running recently and some connections are still lingering around in the half-dead TIME-WAIT state.
Cause 1 can be fixed by terminating the program using your port, or having your program use a different port.
Cause 2 can be fixed by only running one instance of your program at a time.
Cause 3 can be fixed by waiting a few minutes or by using the SO_REUSEADDR
socket option on Linux. The SO_REUSEADDR
option has the drawback on Windows
that it will allow multiple programs to listen on the same port, but only one
will actually receive connections.
I hope you found this article helpful. I'd love to hear any feedback you might have. Don't hesitate to get in touch.
You can find the rest of my network programming articles here.