Bind () with SO_REUSEADDR error

My task is to implement a two-user game between two computers connected via TCP. One of the requirements is that only the winner gets the choice of the game again or not. If the server wins and decides not to play further, the client must restart as a server and accept new connections.

My approach: If the game is LOST (in client mode), close sockfd and recreate another one. Then use setsockopt to enable reconnection with SO_REUSEADDR and then call bind.

int yes = 1; if ( setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1 ) { perror("setsockopt"); } if ( bind(sockfd, (struct sockaddr*)&svr, sizeof(svr) ) == -1 ) { perror("server: bind"); } 

But still, I get the same "Address already in use" error. I tried to sleep for 150 seconds before recreating the socket, and this method works.

NOTE. I am testing this on the same PC. It can work on two connected computers, but it must be made to work on one PC. Please, help.

+6
source share
3 answers

Since you are using this in one system, it sounds as if you have a race condition. The client tries to bind() socket just before the server closes (assuming that the server and the client set SO_REUSEADDR on their sockets).

You need to implement some kind of handshake that allows the server to inform the client after it has closed the auditory socket - perhaps the server must close the listening socket before it closes the active socket from the last game?

+2
source

SO_REUSEADDR allows you to bind to a more specific address at the same time, that is, the first server listens for INADDR_ANY (all interfaces), and subsequent servers listen for different interface addresses.

The second scenario is that when listening to a TCP socket, a connection is accepted, which is saved, but the listening socket itself closes and then opens again - they say that the parent server process ends and starts again.

In both cases, you always need to set the SO_REUSEADDR parameter to the listening socket before you call bind(2) .

+1
source

Setting this socket option allows reuse of the local address. If you try to bind to a port that was closed but not released, a problem may arise (it may take up to 2 minutes, as determined by TIME_WAIT). Use the SO_REUSEADDR socket option to immediately release the resource and transition from TIME_WAIT state. 0 = disable, 1 = enable.

Allows other sockets to bind () to this port if there is no longer an active listening socket associated with the port. This circumvents these "Address already in use" error messages when trying to restart the server after a failure

0
source

Source: https://habr.com/ru/post/902770/


All Articles