views:

462

answers:

1

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.

+1  A: 

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.

Pete