How to properly close a socket when program terminates?

I’ve been working on some socket code (I’m just learning) and I need help with how to close the socket when the program terminates unexpectedly.

My code:


		try (
				ServerSocket serverSocket = new ServerSocket(port);
				
				Socket clientSocket = serverSocket.accept();
				
				PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
			) {
			
			out.println("Test to client!");
			
			
		} catch (IOException e) {
			e.printStackTrace();
			System.exit(-1);
		}

As you can see, I’m using a try-with-resource statement to call the close method on my sockets. This works fine if the client connects, and the try finishes normally.
But what if a client never connects, the server is waiting on serverSocket.accept(), and the user closes the server? The try doesn’t finish, and the close method never gets called.

I’ve done some research on this, I’ve seen some people use shutdown hooks, and some just let the OS clean everything up. From what I can see, the OS should do it for you, but there’s a delay on when it closes the port. You can get around this delay by calling ServerSocket.setReuseAddress(true). However, since I’m using a try-with-resource statement, I can’t call that method before the serverSocket.accept() line, since you can’t execute a method in a try-with-resources statement.

I’m just not sure how to proceed, or if I’m going about this the right way. Thanks for your help :wink:

Personally, I’d say just go with the “classic” form of the try/catch block for that section of code. That gives you the option of using the parameterless version of ServerSocket’s constructor which would then allow you to set the reuse address flag before binding the socket. The try with resources form of try/catch can be useful in many situations, but if you find it being more of a hindrance than a help in a situation, don’t be afraid to use the alternate form. I wouldn’t advise trying to call any further methods on a socket that’s been put into an exception state, including close.

Addendum: As for what happens when the server is closed down, the socket will be cleaned up by the JVM as it’s exiting. The connected clients, if any, will throw exceptions on their side.

OK, thanks for the info. Also, is it even necessary to set Reuse Address? Or is it fine to just leave it off.

According to some research, the timeout period of a socket can vary by implementation, so if you want consistency, set the value.