Tag Archives: Advanced programming in a Unix environment

What should be paid attention to in socket programming — bind socket error: address already in use

When programming Linux networks, you often encounter the following usage errors every time you modify the source code and compile it again:

Bind error: Address already in use

Although the process was forced to end with Ctrl+C, the error still exists. We can still see the process “forced to end” with Ctrl+C with netstat -an |grep 5120 and ps aux |grep 5120. The port is still in use, so we have to kill the process with kill every time, which is very troublesome. Last night, I happened to browse an article titled “5 Hidden Dangers in Linux Socket Programming” on THE IBM website. I suddenly realized that I had a try today and solved the problem as expected. I hereby express my thanks and hope that more coder can read this article and avoid making mistakes.

The main codes are:

int on;

on = 1;
ret = setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, & on, sizeof(on) );
now every time I force the process to end with Ctrl+C, I can still see the port in use with netstat and ps, but the running program will not have the error of “Address already in use”, so the port is reused.

 

Here is the third pitfall in this article — incorrect address usage

Address usage error (EADDRINUSE)

You can use the Bind API function to bind an address (an interface and a port) to a socket endpoint. You can use this function in your server Settings to limit the interfaces that may have a connection coming. You can also use this function in client Settings to limit the interfaces that should be used for outgoing connections. The most common use of BIND is to associate a port number with a server and use a wildcard address (INADDR_ANY), which allows any interface to be used for incoming connections.

A common problem with BIND is trying to bind to a port that is already in use. The trap is that no active socket may exist, but the binding port is still disabled (bind returns EADDRINUSE), which is caused by the TCP socket state TIME_WAIT. This state remains for about 2 to 4 minutes after the socket is closed. After the TIME_WAIT state exits, the socket is deleted and the address can be rebound without problems.

Waiting for TIME_WAIT to end can be annoying, especially if you’re developing a socket server and need to stop the server to make some changes, and then restart. Fortunately, there is a way to get around the TIME_WAIT state. You can apply the SO_REUSEADDR socket option to the socket so that the port can be reused immediately.

Consider the example in Listing 3. Before binding the address, I call setsockopt with the SO_REUSEADDR option. To allow address reuse, I set the integer parameter (on) to 1 (otherwise, I can set it to 0 to prohibit address reuse).

use the SO_REUSEADDR socket option to avoid address usage errors

 

int sock, ret, on;
struct sockaddr_in servaddr;
/* Create a new stream (TCP) socket */
sock = socket( AF_INET, SOCK_STREAM, 0 ):
/* Enable address reuse */
on = 1;
ret = setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, & on, sizeof(on) );
/* Allow connections to port 8080 from any available interface */
memset( & servaddr, 0, sizeof(servaddr) );
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl( INADDR_ANY );
servaddr.sin_port = htons( 45000 );
/* Bind to the address (interface/port) */
ret = bind( sock, (struct sockaddr *)& servaddr, sizeof(servaddr) );
after the SO_REUSEADDR option is applied, the bind API function allows immediate reuse of the address.

 

Five pitfalls in Linux socket programming
http://www.ibm.com/developerworks/cn/linux/l-sockpit/