Proper way to terminate a ServerSocket connection

I am working on a project that involves making ServerSocket connections to the driver station laptop using the Java WebSocket library. Starting a WebSocketServer works fine, but when I open a connection to the DS Laptop and then attempt to deploy new code or restart the robot code, the attempted server starting gives the error

java.net.BindException: Address already in use

. If I restart the robot code after a while or immediately restart the roboRIO, the connection then becomes successful, leading me to believe that the JVM isn’t closing the connection “properly”, or at least in a timely manner.

I’ve tried adding a shutdown hook and using Thread.join() to attempt to close the WebServer when shutdown is detected, but to no avail. Is there any way I should seek to properly close the ServerSocket connections?

Making some educated guesses about what’s going on here. I don’t have much experience with websockets, but I’m pretty sure the problem your experiencing is a general socket issue at the OS level related to the process that owned the bound socket being killed, and another one coming along trying to bind to that same port.

When the code gets deployed I’m pretty sure the Java process that was running gets killed. Unfortunately that leaves the socket you had bound to port ### in a timeout state, waiting to handle more traffic (usually 30 - 120s)

I’m not sure if there’s a hook within the WPI libraries that gets called when a code deploy action is performed. If this does exist, you could call the close method on your session object, which should gracefully close the socket and free the resource for the next bind operation (that will happen after your code gets deployed).

If the above doesn’t exist, there is still hope. There’s a socket option that can be enabled called so_reuseaddr. It allows re-bindong to existing sockets. This isn’t enabled by default, as you might imagine, allowing multiple processes to bind to the same socket on the same computer could lead to problems.

There is a pretty good write up about how reuseaddr here that would be worth reading:

Again I’m not really familiar with the websockets library you’re using, but it seems like they have a method to enable this feature: https://github.com/TooTallNate/Java-WebSocket/blob/c0ad64bb50af6f9080a5c55f929ddbef58b48bd4/src/main/java/org/java_websocket/AbstractWebSocket.java
See the setReuseAddr method.

This option needs to be enabled before the socket is bound.
I’ll try to look at their code and come up with an example of how to do this.

Looks like they have an example on their wiki that should do what you need.


ChatServer s = new ChatServer( port );
s.setReuseAddr( true );.  //<-- you likely just need to add this line
s.start();

Just restart the RIO once after deploying this change so that the reuseaddr option gets set on the first bind. Once it’s up and running, you should be able to redeploy without a problem.

Thanks! As you described, I was looking for some notification of robot code shutdown and/or some way to rebind to an existing socket, and I couldn’t find either. Looks like my Googling skills aren’t up to par.

I added the line, re-deployed and restarted, and lo and behold it worked like a charm. Thanks for the help!