Package p2pradio

Source Code of p2pradio.Radio

/*
* P2P-Radio - Peer to peer streaming system
* Project homepage: http://p2p-radio.sourceforge.net/
* Copyright (C) 2003-2004 Michael Kaufmann <hallo@michael-kaufmann.ch>
*
* ---------------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
* ---------------------------------------------------------------------------
*/

package p2pradio;

import p2pradio.gui.*;
import p2pradio.logging.*;
import p2pradio.sources.*;
import p2pradio.players.*;
import p2pradio.webinterface.*;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.logging.Filter;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
import java.util.logging.Level;


/**
* Starts everything and provides the command-line interface.
* It also manages the message handler for important and
* debug messages.
*
* @author Michael Kaufmann
*/
public class Radio implements Filter
{
  public static final String Name = Messages.getString("Radio.NAME"); //$NON-NLS-1$
  public static final String Version = "2.0"; //$NON-NLS-1$
  public static final String VersionWithoutSpaces = "2.0"; //$NON-NLS-1$
  public static final String NameSlashVersion = Name + "/" + VersionWithoutSpaces; //$NON-NLS-1$
 
  public static final String HOMEPAGE = "http://p2p-radio.sourceforge.net/"; //$NON-NLS-1$
     
  public static boolean displayDebugMessages;
  public static boolean dontStartMediaPlayerInListeningMode = false;
  public static boolean startMediaPlayerInBroadcastingMode = false;
  public static boolean startMinimized = false;
  public static boolean enableMonitor = false;

  public static HttpPlayer httpPlayer;
 
  private Peer peer;
  private RadioGUI radioGUI;
 
  public static void main(String args[])
  {
    try
    {
      new Radio(args);
    }
    catch (Exception e)
    {
      Logger.severe("Radio", "INTERNAL_ERROR", e);    //$NON-NLS-1$ //$NON-NLS-2$
    }
  }
 
  private void printUsageInformation()
  {
    System.out.println(Messages.getString("Radio.USAGE_INFORMATION", new Object[]{new Integer(Peer.DEFAULT_PORT_NR), new Integer(Peer.MAX_NUMBER_OF_CHILDREN)})); //$NON-NLS-1$
    System.out.println();
    System.exit(0);   
  }
 
  private void printIntroduction(int port, boolean consoleUI)
  {
    System.out.println();
    System.out.println(Messages.getString("Radio.WELCOME", Name)); //$NON-NLS-1$
    System.out.println();
   
    try
    {
      System.out.println(Messages.getString("Radio.IP_ADDRESS", InetAddress.getLocalHost().getHostAddress())); //$NON-NLS-1$
    }
    catch (UnknownHostException e)
    {
    }
   
    System.out.println(Messages.getString("Radio.PORT_NUMBER", new Integer(port))); //$NON-NLS-1$
    System.out.println(Messages.getString("Radio.MP3_STREAM_PORT_NUMBER", new Integer(port + Peer.STREAM_PORT_OFFSET))); //$NON-NLS-1$
    System.out.println(Messages.getString("Radio.WEB_SERVER_PORT_NUMBER", new Integer(port + Peer.WEBINTERFACE_PORT_OFFSET))); //$NON-NLS-1$
    System.out.println();
   
    if (consoleUI)
    {
      System.out.println(Messages.getString("Radio.CONSOLE_MODE_HELP", Name)); //$NON-NLS-1$
      System.out.println();
   
  }
 
  protected Radio(String argsString[])
  {
    // Handler zuerst sowohl f�r Kommandozeilen- als auch
    // f�r GUI-Bedienung aktivieren, damit man alle Fehler
    // w�hrend dem Starten sieht
    Handler logHandler = new ConsoleLogHandler();
    logHandler.setFilter(this);
    logHandler.setFormatter(new LogFormatter());
    Logger.getLogger().addHandler(logHandler);
   
    // Parameter in einen Vektor kopieren
    Vector args = new Vector();
   
    for (int i=0; i < argsString.length; i++)
    {
      args.add(argsString[i]);
    }
   
    // Debug-Nachrichten anzeigen?
    displayDebugMessages = parseBooleanArg(args, "debug", false); //$NON-NLS-1$
   
    // Keine grafische Oberfl�che?
    boolean noGUI = parseBooleanArg(args, "nogui", false); //$NON-NLS-1$
   
    boolean consoleUI = parseBooleanArg(args, "consoleui", false); //$NON-NLS-1$
   
    // Keine grafische Oberfl�che bei Konsolenbedienung anzeigen
    if (consoleUI)
    {
      noGUI = true;
    }
   
    // Portnummern lesen
    int port = -1;
    boolean portSet = false;
   
    try
    {
      port = parseIntArg(args, "port", port); //$NON-NLS-1$
      portSet = (port != -1);
    }
    catch (IllegalArgumentException e)
    {
      exit(Messages.getString("Radio.INVALID_PORT_NUMBER"), noGUI); //$NON-NLS-1$
    }
   
    // Maximale Bandbreite lesen
    int maxUploadBandwidth = 0;
    boolean maxUploadBandwidthSet = false;
     
    try
    {
      maxUploadBandwidth = parseIntArg(args, "maxbandwidth", maxUploadBandwidth); //$NON-NLS-1$
      maxUploadBandwidthSet = (maxUploadBandwidth != 0);
    }
    catch (IllegalArgumentException e)
    {
      exit(Messages.getString("Radio.INVALID_BANDWIDTH_LIMIT"), noGUI); //$NON-NLS-1$
    }
   
    // Logdatei gew�nscht?
    String logFileName = null;
    logFileName = parseStringArg(args, "logfile", null); //$NON-NLS-1$
    if (logFileName != null)
    {
      try
      {
        Handler logfileHandler = new FileLogHandler(logFileName);
        logfileHandler.setFilter(this);
        logfileHandler.setFormatter(new LogFormatter());
        Logger.getLogger().addHandler(logfileHandler);
      }
      catch (IOException e)
      {
        exit(Messages.getString("Radio.INVALID_LOGFILE_NAME"), noGUI); //$NON-NLS-1$
      }
    }

    // Den Strom signieren?
    Peer.signStreamPackets = parseBooleanArg(args, "sign", Peer.signStreamPackets); //$NON-NLS-1$
    Peer.signStreamPackets = !parseBooleanArg(args, "dontsign", !Peer.signStreamPackets); //$NON-NLS-1$

    // Authentizit�t des Stroms �berpr�fen?
    Peer.verifyStreamPackets = parseBooleanArg(args, "verify", Peer.verifyStreamPackets); //$NON-NLS-1$
    Peer.verifyStreamPackets = !parseBooleanArg(args, "dontverify", !Peer.verifyStreamPackets); //$NON-NLS-1$

    // Media Player starten?
    startMediaPlayerInBroadcastingMode = parseBooleanArg(args, "startmediaplayer", startMediaPlayerInBroadcastingMode); //$NON-NLS-1$
    dontStartMediaPlayerInListeningMode = parseBooleanArg(args, "dontstartmediaplayer", dontStartMediaPlayerInListeningMode); //$NON-NLS-1$

    // Minimiert starten?
    startMinimized = parseBooleanArg(args, "startminimized", startMinimized); //$NON-NLS-1$
   
    // Monitor unterst�tzen?
    enableMonitor = parseBooleanArg(args, "enablemonitor", enableMonitor); //$NON-NLS-1$
    enableMonitor = !parseBooleanArg(args, "disablemonitor", !enableMonitor); //$NON-NLS-1$

    if ((args.size() == 0) && !noGUI)
    {
      // Grafische Oberfl�che anzeigen und
      // Fragen stellen
      radioGUI = new RadioGUI(portSet, port, maxUploadBandwidthSet, maxUploadBandwidth, logHandler);
      return;
    }
   
    if (args.size() < 2)
    {
      // Zuwenige Parameter angegeben
      printUsageInformation();
    }
   
   
    // Entweder grafische Oberfl�che ohne Fragen oder
    // nur Kommandozeile
   
    if (((String)args.get(0)).toLowerCase().equals("server")) //$NON-NLS-1$
    {
      URL playlist = null;
       
      try
      {
        playlist = new URL((String)args.get(1));
      }
      catch (MalformedURLException e)
      {
        exit(Messages.getString("INVALID_PLAYLIST_ADDRESS"), noGUI); //$NON-NLS-1$
      }
     
      InetSocketAddress monitorAddress = null;
       
      // Monitoradresse lesen   
      if (args.size() >= 3)
      {
        if (!enableMonitor)
        {
          System.out.println(Messages.getString("Radio.MONITOR_DEACTIVATED_ADDRESS_IGNORED")); //$NON-NLS-1$
        }
        else
        {
          String addr = (String)args.get(2);
          String remoteHost;
          int remotePort;
          int pos;
       
          if ((pos = addr.indexOf(":")) == -1) //$NON-NLS-1$
          {
            remoteHost = addr;
            remotePort = Peer.MONITOR_PORT;
          }
          else
          {
            try
            {
              remoteHost = addr.substring(0, pos);
              remotePort = Integer.parseInt(addr.substring(pos+1, addr.length()));
            }
            catch (NumberFormatException e)
            {
              remoteHost = addr;
              remotePort = Peer.MONITOR_PORT;
            }
          }
 
          try
          {
            monitorAddress = new InetSocketAddress(remoteHost, remotePort);
           
            if (monitorAddress.getAddress() == null)
            {
               throw new IllegalArgumentException();
            }
          }
          catch (Exception e)
          {
            System.out.println(Messages.getString("INVALID_MONITOR_ADDRESS")); //$NON-NLS-1$
          }
         
          if (monitorAddress.getAddress().isLoopbackAddress())
          {
            System.out.println(Messages.getString("Radio.LOCAL_MONITOR_ADDRESS", addr)); //$NON-NLS-1$
          }
        }
      }
     
      if (!portSet)
      {
        port = Radio.getBestPortNumber();
      }
           
      if (noGUI)
      {
        printIntroduction(port, consoleUI);
      }
     
      try
      {
        peer = new Peer(port, maxUploadBandwidth, monitorAddress);
      }
      catch (PeerException e)
      {
        exit(e.getMessage(), noGUI);
      }
       
      Logger.finer("Radio", "I_AM_THE_SERVER", peer); //$NON-NLS-1$ //$NON-NLS-2$
     
      HttpSource source = new HttpSource(peer.getBroadcastBuffer(), playlist);
     
      Logger.info("Radio", "CONNECTING_TO_SERVER"); //$NON-NLS-1$ //$NON-NLS-2$
     
      if (!source.connect())
      {
        Logger.info("Radio", "COULD_NOT_CONNECT_TO_SERVER"); //$NON-NLS-1$ //$NON-NLS-2$
        exitWithLogger(Messages.getString("COULD_NOT_CONNECT_TO_SERVER"), noGUI); //$NON-NLS-1$
      }
     
      source.start();
    }
    else if (((String)args.get(0)).toLowerCase().equals("client")) //$NON-NLS-1$
    {
      // Serveradresse lesen
     
      String addr = removePrefix((String)args.get(1));
      String remoteHost;
      int remotePort;
      int pos;
     
      if ((pos = addr.indexOf(":")) == -1) //$NON-NLS-1$
      {
        remoteHost = addr;
        remotePort = Peer.DEFAULT_PORT_NR;
      }
      else
      {
        try
        {
          remoteHost = addr.substring(0, pos);
          remotePort = Integer.parseInt(addr.substring(pos+1, addr.length()));
        }
        catch (NumberFormatException e)
        {
          remoteHost = addr;
          remotePort = Peer.DEFAULT_PORT_NR;
        }
      }
     
           
      // Die Adresse des Servers
      InetSocketAddress serverAddress = null;
   
      try
      {
        serverAddress = new InetSocketAddress(remoteHost, remotePort);
       
        if (serverAddress.getAddress() == null)
        {
          throw new IllegalArgumentException();
        }
      }
      catch (Exception e)
      {
        exit(Messages.getString("INVALID_SERVER_ADDRESS"), noGUI); //$NON-NLS-1$
      }
     
      if (!portSet)
      {
        port = Radio.getBestPortNumber();
      }
     
      if (noGUI)
      {
        printIntroduction(port, consoleUI);
      }
     
      try
      {
        peer = new Peer(new RemotePeer(serverAddress), port, maxUploadBandwidth);
      }
      catch (PeerException e)
      {
        exit(e.getMessage(), noGUI);
      }
     
      Logger.finer("Radio", "I_AM_A_CLIENT", peer); //$NON-NLS-1$ //$NON-NLS-2$
    }
    else
    {
      printUsageInformation();
    }
   
    httpPlayer = new HttpPlayer(peer.getBuffer(), peer.getSocketAddress().getPort() + Peer.STREAM_PORT_OFFSET);
    httpPlayer.start();
    new WebServer(peer, httpPlayer).start();
   
    if (!noGUI)
    {
      // Grafische Oberfl�che ab jetzt anzeigen
      radioGUI = new RadioGUI(logHandler);
     
      // Die Bandbreite ist so wichtig, dass sie unbedingt noch
      // abgefragt werden muss
      if (peer.isServer() && !maxUploadBandwidthSet)
      {
        peer.setMaxUploadBandwidth(radioGUI.inputMaxUploadBandwidth());
      }
    }
   
    // Media Player nur automatisch starten, falls der Peer
    // kein Server ist
    if ((peer.isServer() && Radio.startMediaPlayerInBroadcastingMode) || (!peer.isServer() && !Radio.dontStartMediaPlayerInListeningMode))
    {
      new MediaPlayerLauncher(peer.getListenBuffer(), httpPlayer).start();
    }
   
    if (!noGUI)
    {
      radioGUI.setPeer(peer);
    }
    else
    {
      if (consoleUI)
      {
        // Befehle entgegennehmen
     
        BufferedReader commandLine = new BufferedReader(new InputStreamReader(System.in));
       
        while (true)
        {
          String command = null;
       
          try
          {
            command = commandLine.readLine();
          }
          catch (Exception e)
          {
            Logger.severe("Radio", "INTERNAL_ERROR", e); //$NON-NLS-1$ //$NON-NLS-2$
            exitWithLogger(Messages.getString("INTERNAL_ERROR"), noGUI); //$NON-NLS-1$
          }
         
          if (command == null)
          {
            // Ctrl-C
            peer.leave();
            System.exit(0);
          }
       
          if (command.equals("help") || command.equals("?")) //$NON-NLS-1$ //$NON-NLS-2$
          {
            printIntroduction(peer.getSocketAddress().getPort(), consoleUI);
          }
          else if (command.equals("exit")) //$NON-NLS-1$
          {
            peer.leave();
            System.exit(0);
          }
          else if (command.equals("join")) //$NON-NLS-1$
          {
            peer.join();
          }
          else if (command.equals("change")) //$NON-NLS-1$
          {
            peer.changeSupplier(true, false);
          }
          else if (command.equals("leave")) //$NON-NLS-1$
          {
            peer.leave();
          }
          else if (command.equals("debug")) //$NON-NLS-1$
          {
            displayDebugMessages = !displayDebugMessages;
          }
          else
          {
            System.out.println(Messages.getString("Radio.UNKNOWN_COMMAND")); //$NON-NLS-1$
          }
        }
      }
      else
      {
        while(true)
        {
          try
          {
            Thread.sleep(100000);
          }
          catch (InterruptedException e)
          {
          }
        }
      }
    }
  }
   
  public static int getBestPortNumber()
  {
    if (isPortNrOK(Peer.DEFAULT_PORT_NR))
    {
      return Peer.DEFAULT_PORT_NR;
    }
    else
    {
      return getRandomPortNumber();
    }
  } 
 
  /**
   * Returns a random non-privileged (bigger than 1023) port number. This method checks that
   * the returned port number and the two following port numbers are free for both TCP and UDP.
   */
  private static int getRandomPortNumber()
  {
    // Drei Portnummern nacheinander m�ssen frei sein
    // (es wird sowohl TCP als auch UDP getestet)
   
    Random random = new Random();
    int portNr = 1024 + random.nextInt((65535 - 2) - 1024);
   
    if (!isPortNrOK(portNr)) return getRandomPortNumber();
    if (!isPortNrOK(portNr+1)) return getRandomPortNumber();
    if (!isPortNrOK(portNr+2)) return getRandomPortNumber();
   
    // portNr ist OK
    return portNr;
  }
 
  private static boolean isPortNrOK(int portNr)
  {
    try
    {
      ServerSocket serverSocket = new ServerSocket(portNr);
      serverSocket.close();
    }
    catch(IOException e)
    {
      return false;
    }
   
    try
    {
      DatagramSocket datagramSocket = new DatagramSocket(portNr);
      datagramSocket.close();
    }
    catch(IOException e)
    {
      return false;
    }
   
    return true;
  }
 
  protected static final boolean parseBooleanArg(Vector args, String parameter, boolean defaultValue)
  {
    for (int i=0; i < args.size(); i++)
    {
      String arg = ((String)args.get(i)).toLowerCase();
      if (arg.equals("-" + parameter.toLowerCase()) || arg.equals("--" + parameter.toLowerCase()) || arg.equals("/" + parameter.toLowerCase())) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
      {
        args.remove(i);
        return true;
      }
    }
   
    return defaultValue;
  }
 
  protected static final int parseIntArg(Vector args, String parameter, int defaultValue)
  {
    for (int i=0; i < args.size(); i++)
    {
      String arg = ((String)args.get(i)).toLowerCase();
      if (arg.equals("-" + parameter.toLowerCase()) || arg.equals("--" + parameter.toLowerCase()) || arg.equals("/" + parameter.toLowerCase())) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
      {
        try
        {
          int result = Integer.parseInt((String)args.get(i+1));
          args.remove(i+1);
          args.remove(i);
         
          return result;
        }
        catch (NumberFormatException e)
        {
          throw new IllegalArgumentException();
        }
      }
    }
   
    return defaultValue;
  }
 
  protected static final String parseStringArg(Vector args, String parameter, String defaultValue)
  {
    for (int i = 0; i < args.size(); i++)
    {
      String arg = ((String)args.get(i)).toLowerCase();
      if (arg.equals("-" + parameter.toLowerCase()) || arg.equals("--" + parameter.toLowerCase()) || arg.equals("/" + parameter.toLowerCase())) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
      {
        String result = (String)args.get(i+1);
        args.remove(i+1);
        args.remove(i);
        return result;
      }
    }
    return defaultValue;
  }
 
  public boolean isLoggable(LogRecord record)
  {
    if (record.getLevel().intValue() < Level.INFO.intValue())
    {
      return displayDebugMessages;
    }
    else
    {
      return true;
    }
  }
 
  public static String removePrefix(String url)
  {
    // Remove the "p2p-radio://" prefix
 
 
    if (url.toLowerCase().startsWith("p2p-radio:")) //$NON-NLS-1$
    {
      url = url.substring(10, url.length());
    }
   
    if (url.startsWith("//")) //$NON-NLS-1$
    {
      url = url.substring(2, url.length());
    }
    else if (url.startsWith("/")) //$NON-NLS-1$
    {
      url = url.substring(1, url.length());
    }
   
    if (url.endsWith("/")) //$NON-NLS-1$
    {
      url = url.substring(0, url.length() - 1);
    }
 
    return url;
  }
 
  private void exit(String message, boolean noGUI)
  {
    if (message != null)
    {
      System.out.println(message);
     
      if (!noGUI)
      {
        RadioGUI.setLookAndFeel();
        javax.swing.JOptionPane.showMessageDialog(null, message, Messages.getString("GENERAL_ERROR"), javax.swing.JOptionPane.ERROR_MESSAGE, null); //$NON-NLS-1$
      }
    }
   
    System.exit(1);
  }
 
  private void exitWithLogger(String message, boolean noGUI)
  {
    if (message != null)
    {
      if (!noGUI)
      {
        RadioGUI.setLookAndFeel();
        javax.swing.JOptionPane.showMessageDialog(null, message, Messages.getString("GENERAL_ERROR"), javax.swing.JOptionPane.ERROR_MESSAGE, null); //$NON-NLS-1$
      }
    }
   
    System.exit(1);
 
}
TOP

Related Classes of p2pradio.Radio

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.