protected void finalize() throws Throwable {
   shutdownWorker();
   super.finalize();
 }
  @Override
  public void start(Connection pSocket) {
    synchronized (connectedSockets) {
      connectedSockets.add(pSocket);
    }

    if (mReceiveThread == null) {
      mReceiveThread =
          new Thread() {
            public void run() {
              int tFrameNumber = 0;

              long tStartTime = 0;
              boolean tCleanupNeeded = false;
              byte[] tPacketBuffer = new byte[UDP_READ_BUFFER_SIZE];
              DatagramPacket tPacket = new DatagramPacket(tPacketBuffer, tPacketBuffer.length);

              while (true) {
                if (!mWorkerNeeded) {
                  break;
                }

                int tRcvdBytes = 0;

                try {

                  while (true) {
                    tStartTime = System.currentTimeMillis();

                    mRcvSocket.receive(tPacket);
                    tRcvdBytes = tPacket.getLength();

                    if (tRcvdBytes == 0) {
                      break;
                    }

                    Logging.log(
                        this,
                        "Got audio frame "
                            + ++tFrameNumber
                            + " from "
                            + tPacket.getAddress()
                            + ":"
                            + tPacket.getPort()
                            + " with size of "
                            + tPacket.getLength());

                    // create payload object for delivery towards connected clients
                    byte[] tAudioFrame = Arrays.copyOf(tPacketBuffer, tPacket.getLength());

                    // send payload object to connected clients
                    for (Connection socket : connectedSockets) {
                      if (socket.isConnected()) {
                        socket.write(tAudioFrame);
                      } else {
                        tCleanupNeeded = true;
                      }
                    }

                    Logging.log(
                        this,
                        "Read "
                            + tRcvdBytes
                            + " bytes from UDP (msec="
                            + (System.currentTimeMillis() - tStartTime)
                            + ")");
                  }

                  // remove disconnected socket from list
                  // if there are more of them, the next will
                  // be deleted in the next round.
                  if (tCleanupNeeded) {
                    cleanupSocketList();
                  }
                } catch (Exception tExc) {
                  tExc.printStackTrace();
                }
              }

              mRcvSocket.close();
              ConnectionEndPointUDPAudioProxy.this.stop();

              Logging.log(this, "Audio grabbing thread finished");
            }
          };

      mReceiveThread.start();
    }

    super.start(pSocket);
  }
 @Override
 public void closed() {
   shutdownWorker();
   super.closed();
 }