# Habe 2 Probleme: Input eingabe und Multi Socket Server



## Darthzed (12. Mrz 2004)

Hallo,
ich beschäftige mich zurzeit mit der Programmierung eines Java Chats über Socket mit grafischer Oberfläche.
Ich bin eigentlich schon fast fertig aber da sind noch zwei große Probleme, zum einem bekomme ich es nicht hin
die Daten die der Server zum Clint schickt zu einem String umzuwandeln und dann auf einer jTextArea auszugeben. Und zum anderen kann mein Socket Server nur immer an einen Client die Nachricht schicken.
Ich arbeite mit dem Handbuch der Java-Programmierung und habe von dort aus Kapitel 45 die Beispiele vom Server und vom Client genommen und dann verändert.


Hier ist mein versuch mit dem Inputstream. Der Fehler ist weiter unten in dem Thread. Ich bereits eine Funktion gefunden namens getBytes aber die funktioniert nicht richtig und scheint veraltet zu sein:


```
import java.net.*;
import java.io.*;

public class SocketClient
{

	Socket sock;
	InputStream in;
	OutputStream out;
	OutputThread th;

	public void verbinden(String url, Prototype fenster)
	{
		fenster.setStatusAusgabeJTextAreaEingabe("Client gestartet\n");

		try
		{
			sock = new Socket(url, 7);

			in = sock.getInputStream();
			out = sock.getOutputStream();

			th = new OutputThread(in);
		}
		catch (IOException e)
		{
			fenster.setStatusAusgabeJTextAreaEingabe
				("Fehler:\nUngültige URL oder Server antwortet nicht\n");
			th.requestStop();
			fenster.setStatusAusgabeJTextAreaEingabe("Client beendet\n");
			e.printStackTrace();
		}
	}

	/**
	 * Diese Methode trennt die Verbindung zum Server
	 * 
	 */
	public void trennen(Prototype fenster)
	{
		try
		{
			in.close();
			out.close();
			sock.close();
			th.requestStop();
			fenster.setStatusAusgabeJTextAreaEingabe("Client beendet\n");
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}
	
	/**
	 * Diese Methode sendet den eingegebenen Textstring zu Server
	 * 
	 */
	public void senden(String msg)
	{
		try
		{
			out.write(msg.getBytes());
			out.write('\r');
			out.write('\n');

			//Ausgabe abwarten
			th.yield();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}

	}

}

class OutputThread extends Thread
{
	Prototype fenster = null;

	InputStream in;
	boolean stoprequested;

	public OutputThread(InputStream in, Prototype fenster)
	{
		super();
		this.in = in;
		stoprequested = false;
		this.fenster = fenster;
	}

	public OutputThread(InputStream in)
	{
		super();
		this.in = in;
		stoprequested = false;
	}

	public synchronized void requestStop()
	{
		stoprequested = true;
	}

	public void run()
	{
		int len;
		byte[] b = new byte[100];

		try
		{
			while (!stoprequested)
			{
				try
				{
					if ((len = in.read(b)) == -1)
					{
						break;
					}

					String eingabe = null;

					try
					{
						eingabe.getBytes(0, len, b, 0);
					}
					catch (IndexOutOfBoundsException e)
					{
					}
					//eingabe = String.valueOf(out.write(b, 0, len)).stringValue();

--------->					System.out.write(b, 0, len);

					fenster.setNachrichtenAusgabeJTextAreaEingabe(eingabe);
					fenster.setNachrichtenAusgabeJTextAreaEingabe("\n");
				}
				catch (InterruptedIOException e)
				{
					fenster.setStatusAusgabeJTextAreaEingabe(
						"Fehler beim empfangen\n");
				}
			}
		}
		catch (IOException e)
		{
			fenster.setStatusAusgabeJTextAreaEingabe(
				"OutputThread: " + e.toString());
			fenster.setStatusAusgabeJTextAreaEingabe("\n");
		}
	}
}
```

Bei dem Server habe ich versucht mithilfe einer Threadliste die Threads einzutragen damit der Server wenn ein Client eine Nachricht schickt, sie an alle anderen Clients weiter geschickt wird:


```
import java.net.*;
import java.io.*;

public class SocketServer
{
	int cnt = 0;

	public static void main(String[] args)
	{
		SocketServer ss = new SocketServer();
		ss.starteServer();
	}

	int getCounter()
	{
		return cnt;
	}

	public void starteServer()
	{
		Socket clientList[] = new Socket[5];

		try
		{
			System.out.println("Warte auf Verbindungen auf Port 7...");
			ServerSocket echod = new ServerSocket(7);
			while (true)
			{
				Socket socket = echod.accept();
				clientList[cnt] = socket;
				cnt++;
				EchoClientThread ect=new EchoClientThread(this, clientList);
				ect.start();
			}
		}
		catch (IOException e)
		{
			System.err.println(e.toString());
			System.exit(1);
		}
	}
}

class EchoClientThread extends Thread
{
	private SocketServer ss;
	private Socket[] clientList;

	public EchoClientThread(SocketServer ss, Socket[] socket)
	{
		this.ss = ss;
		this.clientList = socket;
	}

	public void run()
	{
		String msg = "EchoServer: Verbindung " + ss.getCounter();
		System.out.println(msg + " hergestellt");
		try
		{
			InputStream in = clientList[0].getInputStream();
			//OutputStream out = socket.getOutputStream();
			// out.write((msg + "\r\n").getBytes());
			int c;
			while ((c = in.read()) != -1)
			{
				for (int i = 0; i < ss.getCounter(); i++)
				{
					Socket socket = clientList[i];
//					InputStream in = socket.getInputStream();
					OutputStream out = socket.getOutputStream();
					out.write((char) c);
					System.out.print((char) c);
//					socket.close();
				}
			}
			System.out.println("Verbindung " + ss.getCounter() + " wird beendet");
			//			socket.close();
		}
		catch (IOException e)
		{
			System.err.println(e.toString());
		}
	}
}
```

Der funktionierende Server der allerdings nur an einen Client eine nachreicht schicken kann sieht so aus:


```
import java.net.*;
import java.io.*;

public class EchoServer
{
	public static void main(String[] args)
	{
		SocketServer ss = new SocketServer();
		ss.starteServer();
	}

	public void starteServer()
	{
		int cnt = 0;
		Socket clientList[] = new Socket[5];

		try
		{
			System.out.println("Warte auf Verbindungen auf Port 7...");
			ServerSocket echod = new ServerSocket(7);
			while (true)
			{
				Socket socket = echod.accept();
				(new EchoClientThread1(++cnt, socket)).start();
			}
		}
		catch (IOException e)
		{
			System.err.println(e.toString());
			System.exit(1);
		}
	}
}

class EchoClientThread1 extends Thread
{
	private int name;
	private Socket socket;

	public EchoClientThread1(int name, Socket socket)
	{
		this.name = name;
		this.socket = socket;
	}

	public void run()
	{
		String msg = "EchoServer: Verbindung " + name;
		System.out.println(msg + " hergestellt");
		try
		{
			InputStream in = socket.getInputStream();
			OutputStream out = socket.getOutputStream();
			out.write((msg + "\r\n").getBytes());
			int c;
			while ((c = in.read()) != -1)
			{
				out.write((char) c);
				System.out.print((char) c);
			}
			System.out.println("Verbindung " + name + " wird beendet");
			socket.close();
		}
		catch (IOException e)
		{
			System.err.println(e.toString());
		}
	}
}
```

Ich habe schon überall nach einer lösung für die beiden probleme gesucht aber nichts brauchbares gefunden.

Vielen dank für jede Hilfe


----------



## Darthzed (16. Mrz 2004)

Mein erstes Problem konnte ich so lösen:

```
public void run()
{
    int zeichen;
    int stringLaenge;
    int counter = 0;
    String eingabe;´
    StringBuffer buchstaben = new StringBuffer();
       
    try
    {
        while ((zeichen = in.read()) != -1)
        {
            //System.out.print((char) zeichen);
            buchstaben.append((char) zeichen);
            counter++;

            if (zeichen <= 31)
            {
                eingabe = buchstaben.toString();
                fenster.setNachrichtenAusgabeJTextAreaEingabe(eingabe);

                stringLaenge = buchstaben.length();
                buchstaben.delete(0, stringLaenge);
                eingabe = null;
            }
        }
    }
    catch (InterruptedIOException e)
    {
    }
    catch (IOException e)
    {
    }
}
```


----------



## Darthzed (26. Mrz 2004)

Kommt Zeit kommt Rat,
jedenfalls konnte ich das Problem mit dem Server selbst lösen.
Falls es jemanden interessiert hier ist der Quellcode:


```
import java.net.*;
import java.io.*;

public class SocketServer
{

	public static String textSpeicher = "0";
	public static int neueDaten = 0;

	/**
	 * Diese Methode Speichert einen empfangenen Text von einem Thread.
	 * Sie ist Synchronisiert damit die Threads abwechselnd drauf zugreifen können
	 * 
	 */
	public synchronized void setTextSpeicher(String textZwischenSpeicher)
	{
		textSpeicher = textZwischenSpeicher;
	}

	/**
	 * Diese Methode gibt den gespeicherten Text wieder zurück.
	 * Sie ist Synchronisiert damit die Threads abwechselnd drauf zugreifen können
	 * 
	 */
	public synchronized String getTextSpeicher()
	{
		return textSpeicher;
	}

	/**
	 * In Diese Methode wird der Integer + 1 gerechnet, 
	 * wenn was neues im textSpeicher steht
	 * Sie ist Synchronisiert damit die Threads abwechselnd drauf zugreifen können
	 * 
	 */
	public synchronized void setNeueDaten(int neu)
	{
		SocketServer sock = new SocketServer();
		sock.neueDaten = neu;
	}

	/**
	 * Diese Methode gibt an, wenn etwas neues im textSpeicher ist
	 * Sie ist Synchronisiert damit die Threads abwechselnd drauf zugreifen können
	 * 
	 */
	public synchronized int getNeueDaten()
	{
		SocketServer sock = new SocketServer();
		return sock.neueDaten;
	}

	public static void main(String[] args)
	{
		int cnt = 0;

		try
		{
			System.out.println("Warte auf Verbindungen auf Port 10\n");

			SocketServer server = new SocketServer();

			ServerSocket senden = new ServerSocket(11);
			ServerSocket empfangen = new ServerSocket(10);

			while (true)
			{
				Socket ssocket = senden.accept();
				Socket esocket = empfangen.accept();

				SendeClientThread clientThread =
					new SendeClientThread(++cnt, ssocket, server);
				clientThread.start();

				(new EmpfangsClientThread(cnt, esocket, clientThread, server))
					.start();

				try
				{
					Thread.sleep(50);
				}
				catch (InterruptedException e)
				{
				}

				System.out.println("\nClient " + cnt + ":");
				System.out.println("Sende    Socket " + senden);
				System.out.println("Empfangs Socket " + empfangen + "\n");
			}
		}
		catch (IOException e)
		{
			System.err.println(e.toString());
			System.exit(1);
		}
	}
}

class EmpfangsClientThread extends Thread
{
	private int name;
	private Socket socket;
	private SocketServer server;

	SendeClientThread clientThread;

	int zeichen;
	int oldZeichen;
	int counter = 0;
	int stringLaenge;
	
	StringBuffer buchstaben = new StringBuffer();
	String eingabe;

	public EmpfangsClientThread(
		int name,
		Socket socket,
		SendeClientThread clientThread,
		SocketServer server)
	{
		this.name = name;
		this.socket = socket;
		this.server = server;
		this.clientThread = clientThread;
	}

	public void run()
	{
		try
		{
			InputStream in = socket.getInputStream();

			while ((zeichen = in.read()) != -1)
			{
				buchstaben.append((char) zeichen);

				if (zeichen == '\n')
				{
					eingabe = buchstaben.toString();

					System.out.print(eingabe);

					stringLaenge = buchstaben.length();
					buchstaben.delete(0, stringLaenge);

					server.setTextSpeicher(eingabe);

					counter = server.getNeueDaten();
					counter = counter + 1;
					server.setNeueDaten(counter);
					eingabe = null;
				}
			}
			System.out.println("Verbindung " + name + " wird beendet\n");
			clientThread.stop();
			socket.close();
		}
		catch (IOException e)
		{
			System.err.println(e.toString());
		}
	}
}

class SendeClientThread extends Thread
{
	private int name;
	private Socket socket;
	private SocketServer server;

	public SendeClientThread(int name, Socket socket, SocketServer server)
	{
		this.name = name;
		this.socket = socket;
		this.server = server;
	}

	public void run()
	{
		try
		{
			OutputStream out = socket.getOutputStream();

			int counter = 0;
			
			String msg = "Chat Server: Verbindung " + name;
			System.out.println(msg + " hergestellt");

			out.write((msg + "\n").getBytes());

			msg = "0";

			try
			{
				while (true)
				{
					try
					{
						Thread.sleep(10);
					}
					catch (InterruptedException e)
					{
					}

					if (server.getNeueDaten() != counter)
					{
						msg = server.getTextSpeicher();
						out.write(msg.getBytes());
						counter = server.getNeueDaten();
					}
				}
			}
			catch (IOException e)
			{
				System.err.println(e.toString());
			}
			socket.close();
		}

		catch (IOException e)
		{
			System.err.println(e.toString());
		}
	}
}
```

Es werden pro Client der sich beim Server einloggt, zwei Sockets geöffnet. Einer zum senden und einer zum empfangen.


----------

