Newer
Older
democall3 / src / discovery / server / BroadcastResponder.java
package discovery.server;

import constants.Constants;
import java.net.*;
import java.util.Enumeration;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Mark, and Christopher Frantz
 */
public class BroadcastResponder extends Thread {

   private static final Logger LOG = Logger.getLogger(BroadcastResponder.class.getName());
   private final String lab;

   public BroadcastResponder(final String lab) {
      super();
      super.setDaemon(true);
      this.lab = lab;
   }

   @Override
   public void run() {
      try {
         final MulticastSocket socket = new MulticastSocket(Constants.PORT);
         socket.joinGroup(InetAddress.getByName(Constants.BROADCAST_ADDRESS));

         final int bufferSize = 255;

         while (true) {
            byte[] buffer = new byte[bufferSize]; // NOPMD: need to reset buffer each time
            final DatagramPacket packet = new DatagramPacket(buffer, buffer.length);  // NOPMD: safer to create new packets than try to reuse
            socket.receive(packet);
            final String requestedLab = new String(packet.getData()).trim();  // NOPMD: String.valueOf does not handle byte[] properly...
            if (requestedLab.equalsIgnoreCase(lab)) {
               final String serverIp = this.getServerIp();
               buffer = serverIp.getBytes();
               packet.setData(buffer);
               socket.send(packet);
            }
         }

      } catch (Exception ex) {
         LOG.log(Level.SEVERE, null, ex);
      }

   }

   /**
    * This code comes from Christopher Frantz and seems less likely to pick the
    * loopback IP address than other ways.
    */
   private String getServerIp() {
      try {

         for (final Enumeration<NetworkInterface> en =
            NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {

            final NetworkInterface intf = en.nextElement();

            for (final Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {

               final InetAddress inetAddress = enumIpAddr.nextElement();

               try {

                  // FIXME: Quick hack to ensure we are only getting IPv4 
                  //        addresses - need to test what happens with IPv6
                  //        addresses.
                  //        
                  //        This variable is never used - the cast is to check
                  //        if IPv4 or 6.
                  final Inet4Address testIfIpv4 = (Inet4Address) inetAddress;  // NOPMD: see above comment

                  if (!inetAddress.isLoopbackAddress()) {
                     return inetAddress.getHostAddress().toString();
                  }

               } catch (ClassCastException ignored) {
                  continue;
               }

            }
         }

      } catch (Exception ex) {
         LOG.log(Level.SEVERE, null, ex);
      }
      return null;
   }
}