I am writing a Tomcat app. As part of its functionality, it needs to send out a UDP multicast when certain events happen. Right now my code goes something like this (host and group are fake, exception handling ripped out to save space):
import java.net.*; /* ..... */ DatagramSocket socket = new DatagramSocket(12345); InetAddress group = InetAddress.getByName('111.222.333.444'); DatagramPacket packet = new DatagramPacket(buf, buf.length, group, 12346); socket.send(packet);
This works fine when I install it into tomcat; however, when I try to install a new version of the app (using ‘ant remove; ant install;’), I fail to bind to a socket, and get a java.net.BindException: Address already in use. The only way out is to restart Tomcat every time, which is obviously unacceptable. How do I use sockets in a Tomcat-friendly way?
A couple of clarifications per Pete’s answer:
I don’t close the socket; it lives in a Singleton. Adding a method that can close the socket to the Singleton and calling it in the servlet’s destroy worked, thank you! It’s a bit hacky, I think (exposing a method like that to the world via a public method), but it gets the job done.
Are you closing the socket after you use it via disconnect() / close()? What is the lifecycle on the socket – per request, or a singleton? If it is per request, closing the socket should release it. If a singleton, you’ll need to somehow close it on ‘ant remove’ – if shutting down / restarting Tomcat is not acceptable, then perhaps your ant script can call some secure page, etc. that closes the socket. If you can incur a shutdown restart, then close the socket in the servlet’s destroy() method.