import java.net.*;
import java.awt.*;
import java.io.*;
import java.util.*;
import java.awt.event.*;

class TCP extends Frame{

// Version & Autor
//Vorläufer-Version VersionsDatum 	= "06.07.2001";
private static final String VersionsDatum 	= "29.09.2004";
private static final String Autor		= "Manfred Sommer";

private static String Titel = "TCP Verbindungs Test  TCP ";

// TCP/IP Felder
   
   private static String yourIPAdrStr = "137.248.121.186";
   private static int yourPort = 8002;
   private static InetAddress yourIPAdr;
   private static Socket yourSocket;
   private static int myPort = 8002;
   private static ServerSocket myServer;

// Fonts
    private static final Font FontMono           = new Font("Monospaced", Font.PLAIN, 18);
    private static final Font FontSansSerif 	 = new Font("SansSerif", Font.PLAIN, 14);
    private static final Font BigItalicSansSerif = new Font("SansSerif", Font.ITALIC, 16);

     
// Haupt - Fenstergrösse
    private static int XMax =  460;		
    private static int YMax =  390;
	

// Fenster für Meldungen 
    private static TextArea Mdg1 = new TextArea(5,38);
    private static TextArea Mdg2 = new TextArea(5,38);

// Felder, Label und Fenster für Eingaben
    private static Label     EinLabel = new Label("Eingabe Feld", Label.LEFT);
    private static boolean   NeueEingabe = true;
    private static String    EingabeText = "Anfangs-Text";
    private static TextField EingabeFeld = new TextField(EingabeText,38);
       
	
// Beginn Menü 
  	
    private static MenuBar  MainMenuBar = new MenuBar();
    private static Menu     DateiMenu 	= new Menu("Datei");
    private static MenuItem DateiOpen	= new MenuItem("Öffnen...");
    private static Menu     BearbeitenMenu = new Menu("Bearbeiten");
    private static MenuItem TCPVerb  = new MenuItem("TCP-Verbindung aufbauen");
    private static MenuItem PortServer  = new MenuItem("Starte Server");

    private static MenuItem LoeMenu  = new MenuItem("Fenster löschen");
    private static MenuItem Beenden	= new MenuItem("Exit");
    private static Menu     HelpMenu 	= new Menu("Hilfe");
    private static MenuItem AboutBox	= new MenuItem("About");
        
// End Menü 

//// Konstruktor.
 
    TCP () {
	super(Titel);
			
	// Fonts für Menüs
	setFont(FontMono);
	DateiMenu.setFont(FontSansSerif);
	DateiOpen.setFont(FontSansSerif);
	BearbeitenMenu.setFont(FontSansSerif);
	TCPVerb.setFont(FontSansSerif);
	PortServer.setFont(FontSansSerif);
	LoeMenu.setFont(FontSansSerif);
	Beenden.setFont(FontSansSerif);
	HelpMenu.setFont(FontSansSerif);
	AboutBox.setFont(FontSansSerif);
	// Font für Text Bereich
	setFont(new Font("Monospaced", Font.PLAIN, 18));
	
	setLayout(new FlowLayout(FlowLayout.LEADING));
	
	setMenuBar(MainMenuBar);
		
	MainMenuBar.add(DateiMenu);
	DateiMenu.add(DateiOpen);
	DateiMenu.add(Beenden);
	
	MainMenuBar.add(BearbeitenMenu);
	BearbeitenMenu.add(TCPVerb);
	BearbeitenMenu.add(PortServer);
	BearbeitenMenu.add(LoeMenu);
		
	MainMenuBar.add(HelpMenu);
	HelpMenu.add(AboutBox);
	
	add(EinLabel);
	add(EingabeFeld);
	
        Mdg1.setEditable(false);
        add(Mdg1);
        Mdg2.setEditable(false);
        add(Mdg2);
               
           
        
        DateiOpen.addActionListener(new ActionListener(){
	    public void actionPerformed(ActionEvent e){ doOpenFile();}
	   });
	
	TCPVerb.addActionListener(new ActionListener(){
	    public void actionPerformed(ActionEvent e){ doTCPVerb();}
	    });	
	
	PortServer.addActionListener(new ActionListener(){
	    public void actionPerformed(ActionEvent e){ doStartPortServer();}
	    });
	
	EingabeFeld.addActionListener(new ActionListener(){    
             public void actionPerformed(ActionEvent e) { 
             	NeueEingabe = true;
                EingabeText = EingabeFeld.getText();
                }
             });
	
	LoeMenu.addActionListener(new ActionListener(){
	    public void actionPerformed(ActionEvent e){ doLoe();}
	    });
	
		
	Beenden.addActionListener(new ActionListener(){
	    public void actionPerformed(ActionEvent e){ FensterBeenden(); }
		});
		

	AboutBox.addActionListener(new ActionListener(){
		public void actionPerformed(ActionEvent e){ showAboutBox(); }
		});
	    
		
	addWindowListener(new WindowAdapter() {    
	        public void windowClosing(WindowEvent e) { FensterBeenden(); }
		});
		    
	setBackground(Color.lightGray); 
	setSize(XMax, YMax);   
	setVisible(true);
        }

  void FensterBeenden() {	
	        
                dispose();
                System.exit(0);
            }
            
  // show about box
	void showAboutBox(){
		final Frame 	f 	= new Frame("About Box");
		final Button 	Ok 	= new Button("Ok");
	
		f.addWindowListener(new WindowAdapter() {
		    public void windowClosing(WindowEvent e) {
				f.dispose();
			}
		});
		    
		Ok.addActionListener(new ActionListener(){
	        public void actionPerformed(ActionEvent e) {
				f.dispose();
			}
		});
		
		f.setFont	(BigItalicSansSerif);
		f.setLayout	(new GridLayout(0, 1));
	
		f.add(new Label(" ", Label.CENTER));
		f.add(new Label(Titel, Label.CENTER));
		f.add(new Label("Datum der letzten Änderung: " + VersionsDatum, Label.CENTER));
		f.add(new Label("Autor: Manfred Sommer", Label.CENTER));
		f.add(new Label(" ", Label.CENTER));
		
		f.add(Ok);
		f.pack(); 
		f.setVisible(true);
	}
	
	

  
    void doOpenFile(){
    Mdg1.append("Dummy für: Datei - öffnen.\n");
    }    


  void doTCPVerb(){
    if (yourSocket != null){
    	Mdg1.append("TCP Verbindung besteht bereits ...\n");
    	return;
    	}	
    if (yourIPAdr == null){
        Mdg1.append("IP Adresse von " + yourIPAdrStr + " ermitteln...\n");
        try { yourIPAdr = InetAddress.getByName(yourIPAdrStr); }
        catch (UnknownHostException e) {
            Mdg1.append("IP-Adresse nicht gefunden.\n");
            return;
            }	
        }
    Mdg1.append("TCP Verbindung aufbauen...\n");
    yourSocket = null;
    try { yourSocket = new Socket(yourIPAdr, yourPort); }
    catch (IOException e) {
      Mdg1.append("Konnte keine TCP Verbindung herstellen ... " + e + "\n");
      return;
      }
    Mdg1.append("TCP Verbindung steht!\n");
    ClientVerbindung sv = new ClientVerbindung(yourSocket);
    sv.start();
    }

 void doStartPortServer(){
    if (myServer != null){
    	Mdg1.append("Server für Port " + myPort + " besteht bereits ...\n");
    	return;
    	}
    Mdg1.append("Server für Port " + myPort + " konstruieren...\n");  
    try { myServer = new ServerSocket(myPort); } 
    catch (IOException e) { 
      Mdg1.append("Server konstruieren - Fehler " + e +"\n");
      return;
      }	
    ServerAccept sa = new ServerAccept(myServer);
    sa.start();	 
    }

  void doLoe(){ Mdg1.setText(""); }  

  public static void main(String args[]) {
    new TCP();
    }

   class ClientVerbindung extends Thread{
  
   Socket Socke;
   PrintWriter SockeOut;
   BufferedReader SockeIn;
   
   ClientVerbindung(Socket s){
     Socke = s;
     try { // Input/Output Streams verbinden
        SockeOut = new PrintWriter(Socke.getOutputStream(), true);
        SockeIn  = new BufferedReader(new InputStreamReader(Socke.getInputStream()));
       } 
     catch (IOException e) {
        Mdg2.append("Input/Output Streams verbinden - Fehler " + e +"\n");
        }
     }

  public void run(){
    try {// try Read
      String Gelesen;
      while(true){
        while(!SockeIn.ready()){
          yield();
          try {sleep(100);}catch(InterruptedException ci){}; 
          }
        while (SockeIn.ready()){ 
         Gelesen = SockeIn.readLine();
         if (Gelesen == null) break; 	
         else Mdg2.append("Von " + yourIPAdrStr + ": " + Gelesen + "\n");
         }
        }
      }  // end try Read
    catch (IOException e) { Mdg2.append("Lese Fehler von Socket" + e + "\n");}
    try {Socke.close();} catch(IOException e) {}
  }  

} // inner class ClientVerbindung

class ServerAccept extends Thread{
   ServerSocket thisServer;  
   ServerAccept(ServerSocket s){ thisServer = s; }

  public void run(){
    try { // to serve the Port
       while (true){
          Mdg1.append("Ich lausche ...\n");
          Socket Verbindung = thisServer.accept(); // Warte auf eine Verbindung
          ServerVerbindung sv = new ServerVerbindung(Verbindung);
          sv.start();
          }
       } 
    catch (IOException e) {
       Mdg1.append("Fehler bei Server.accept" + e +"\n");
       }
    } // to serve the Port 
 } // inner class ServerAccept

class ServerVerbindung extends Thread{
  
   Socket Socke;
   PrintWriter SockeOut;
   BufferedReader SockeIn;
   
   ServerVerbindung(Socket s){
     Socke = s;
     try { // Input/Output Streams verbinden
        SockeOut = new PrintWriter(Socke.getOutputStream(), true);
        SockeIn  = new BufferedReader(new InputStreamReader(Socke.getInputStream()));
       } 
     catch (IOException e) {
        Mdg2.append("Input/Output Streams verbinden - Fehler " + e +"\n");
        }
     }

  public void run(){
    while (true){
    	while (! NeueEingabe) {
    	   yield(); // Nix zu tun ?
    	   try {sleep(100);}catch(InterruptedException ci){};
    	   }
    	SockeOut.println(EingabeText); // Übertragen
    	NeueEingabe = false;
    	}
     }  
 } // inner class ServerVerbindung

}// class TCP
	
 