/**
  * Closes the socket and stops the listener thread.
  *
  * @throws IOException
  */
 public void close() throws IOException {
   boolean interrupted = false;
   WorkerTask l = listener;
   if (l != null) {
     l.terminate();
     l.interrupt();
     if (socketTimeout > 0) {
       try {
         l.join();
       } catch (InterruptedException ex) {
         interrupted = true;
         logger.warn(ex);
       }
     }
     listener = null;
   }
   DatagramSocket closingSocket = socket;
   if ((closingSocket != null) && (!closingSocket.isClosed())) {
     closingSocket.close();
   }
   socket = null;
   if (interrupted) {
     Thread.currentThread().interrupt();
   }
 }
 /**
  * Starts the listener thread that accepts incoming messages. The thread is started in daemon mode
  * and thus it will not block application terminated. Nevertheless, the {@link #close()} method
  * should be called to stop the listen thread gracefully and free associated ressources.
  *
  * @throws IOException
  */
 public synchronized void listen() throws IOException {
   if (listener != null) {
     throw new SocketException("Port already listening");
   }
   ensureSocket();
   listenerThread = new ListenThread();
   listener =
       SNMP4JSettings.getThreadFactory()
           .createWorkerThread("DefaultUDPTransportMapping_" + getAddress(), listenerThread, true);
   listener.run();
 }