Brauche hilfe bei Projekt: Netzwerk Chatprogramm

Status
Nicht offen für weitere Antworten.

jagdfalke

Bekanntes Mitglied
Hi,
ich hab mir mittlerweile mal die Grundlagen der Netzwerkprogrammierung angeeignet und bin gerade dabei in kleines Programm zu schreiben, dass das chatten innerhalb eines Netzwerks (192.168.2.1 bis 192.168.2.254) ermöglicht. Ich mach mal ne kleine beschreibung von dem was ich bis jetzt geschrieben habe:

Zum Server-Teil:
Jeder Rechner lässt einen Server laufen, der per Thread in der Klasse "Server", wenn eine Connection eintrifft, ein ServerConnection-Objekt erzeugt und es in einen Vector hinzufügt. Dieser Vector ist in der Klasse "Server". In der Klasse "ServerConnection" wird dann dir Kommunikation geregelt aber so weit bin ich noch nicht.
An dem Server in ein ServerListener registriert, der von der GUI-Klasse implementiert wird, um in einer JList und einem JLabel den Status des Servers anzeigen zu können.

Server.java hat folgende Methoden: (extends Thread)

public void run();
public void startServer();
public void shutdown();
public int getConnectionCount();
public boolean isOnline();
public void addServerListener();

und einige fireXXXEvent()-Methoden.


Zum Client-Teil:
Auf der GUI kann man eine IP und einen Port eingeben und auf "Connect" klicken, dann wie an die Klasse "Client" die aufforderung gesendet dort hin eine Verbindung aufzubauen, falls nicht schon eine zu dieser Adresse existiert. "Client" speichert vorhandene Verbindungen in Form eines "ClientConnection"-Objekts in einem Vector.
Bald soll man dann der Klasse Client sagen können, sie soll an die IP xxx.xxx.xxx.xxx die Message y senden. Aber das ist noch Zukunft.



Zur GUI:
Die GUI ist relativ uninteressant, da Einzige:
Code:
			this.addWindowListener(new WindowAdapter() {
										public void windowClosing(WindowEvent ev) {
											srv.shutdown();
											client.shutdown();
											dispose();
											System.exit(0);
										}
									});
Beim Schließen des Fensters wird der Server und der Client "heruntergefahren" und alles Connections beendet.



Jetzt zu meinen Fragen:

1) Wie kann ich im Server bzw im Client überwachen lassen, ob eine Verbindung noch besteht, damit die Vektoren aktualisiert werden können?

2) Beim Schließen des Fensters kommt unendlich oft hintereinander
"Server sayed: null" in der Konsole. Das kommt aus der Klasse ClientConnection, deren run-Methode so aussieht:
Code:
	public void run() {
		while(!isInterrupted()) {
			try {
				String input = this.in.readLine();
				System.out.println("Server sayed: " + input);
			} catch(Exception ex) {
				this.interrupt();
			}
		}
	}
Wie kommt das? Wenn "client.shutdown()" ausgeführt wird passiert das hier:
Code:
	private Vector<ClientConnection> connections = new Vector<ClientConnection>();
        ...
        ...
	public void shutdown() {
		for(int i=0; i<=connections.size()-1; i++) {
			connections.get(i).close();
		}
		connections.clear();
	}
Die close()-Methode aus der Klasse "ClientConnection" sieht so aus:
Code:
	public void close() {
		this.interrupt();  //ClientConnection ist auch ein Thread (Der "Gegen-Part" von "ServerConnection")
		try {
			this.socket.close();
		} catch(Exception ex) {}
	}



Falls das nicht reicht um das Problem zu lösen: Hier die Klassen des Servers und des Clients:
(Die Listener-Klassen lass ich weg, sowie die GUI-Klasse)

Server.java
Code:
package server;

import java.net.*;
import java.util.*;
import java.io.*;

public class Server extends Thread{

	private ServerSocket sckServer;
	private Vector<ServerConnection> connections = new Vector<ServerConnection>();
	private Vector<ServerListener> listener = new Vector<ServerListener>();

	public void run() {
		int cnt = 0;
		while(!this.isInterrupted()){
			try {
				//KEEP ACCEPTING CONNECTIONS AND ADD THEM TO VECTOR connections
				Socket sck = sckServer.accept();
				ServerConnection con = new ServerConnection(cnt, sck);
				connections.add(con);
				cnt++;
				this.fireClientConnectedEvent(con);
			} catch(Exception ex) {}
		}	
	}
	
	public void startServer() {
		try {
			sckServer = new ServerSocket(12345);
			this.start();
			this.fireServerStartedEvent();
		} catch(IOException ex) {
			ex.printStackTrace();
		}
	}
	public void shutdown() {
		try {
			this.interrupt();
			sckServer.close();
		} catch(Exception ex) { /*IGNORE*/ }
		for(int i=connections.size()-1; i>=0; i--) {
			connections.get(i).interrupt();
			connections.get(i).close();
			connections.remove(i);
		}
		this.fireServerShutdownEvent();
	}
	public int getConnectionCount() {
		return connections.size();
	}
	public boolean isOnline() {
		return !sckServer.isClosed();
	}

	public void addServerListener(ServerListener l) {
		if(!listener.contains(l)) {
			listener.add(l);
		}
	}
	
	private void fireClientConnectedEvent(ServerConnection th) {
		for(int i=0; i<=listener.size()-1; i++) {
			ServerListener l = (ServerListener)listener.get(i);
			ServerEvent ev = new ServerEvent(this, ServerEvent.CLIENT_CONNECTED);
			ev.setConnectionThread(th);
			l.clientConnected(ev);
		}
	}
	private void fireClientDisconnectedEvent() {
		for(int i=0; i<=listener.size()-1; i++) {
			ServerListener l = (ServerListener)listener.get(i);
			ServerEvent ev = new ServerEvent(this, ServerEvent.CLIENT_DISCONNECTED);
			l.clientDisconnected(ev);
		}
	}
	private void fireServerStartedEvent() {
		for(int i=0; i<=listener.size()-1; i++) {
			ServerListener l = (ServerListener)listener.get(i);
			ServerEvent ev = new ServerEvent(this, ServerEvent.SERVER_STARTED);
			l.serverStarted(ev);
		}
	}
	private void fireServerShutdownEvent() {
		for(int i=0; i<=listener.size()-1; i++) {
			ServerListener l = (ServerListener)listener.get(i);
			ServerEvent ev = new ServerEvent(this, ServerEvent.SERVER_SHUTDOWN);
			l.serverShutdown(ev);
		}
	}
}

ServerConnection.java
Code:
package server;

import java.net.Socket;
import java.io.*;

public class ServerConnection extends Thread{

	private Socket sckClient;
	private int index;
	private String ip;
	private PrintWriter out;
	private BufferedReader in;
	private String nick;
	
	
	public ServerConnection(int index, Socket socket) throws Exception {
		this.index = index;
		this.sckClient = socket;
		this.ip = sckClient.getInetAddress().getHostAddress();
		
		this.out = new PrintWriter(sckClient.getOutputStream());
		this.in = new BufferedReader(new InputStreamReader(sckClient.getInputStream()));
				
		this.start();
		
	}
	
	public void run() {
		while(!isInterrupted()) {
			try {
				String input = this.in.readLine();
				System.out.println("Client said: " + input);
				
			} catch(Exception ex) {
				this.interrupt();
			}
		}
	}
	
	
	public int getIndex() {
		return this.index;
	}
	public String getIP() {
		return this.ip;
	}
	public void close() {
		try {
			sckClient.close();
		} catch(Exception ex) { /*ignore*/ }
	}
	public boolean isConnected() {
		return sckClient.isConnected();
	}

}


Client.java
Code:
package client;

import java.util.Vector;

public class Client {

	private Vector<ClientConnection> connections = new Vector<ClientConnection>();
	
	public Client() {
		
	}
	
	public void connectTo(String ip, int port) throws Exception {
		if(!connectedToIP(ip)) {
			ClientConnection con = new ClientConnection(ip, port);
			connections.add(con);
			System.out.println("connection added");
		} else {
			System.out.println("allready connected to " + ip);
		}
	}
	
	private boolean connectedToIP(String ip) {
		for(int i=0; i<=connections.size()-1; i++) {
			if(connections.get(i).getIP().equals(ip)) {
				return true;
			}
		}
		return false;
	}
	
	public int getConnectionCount() {
		return connections.size();
	}
	
	public void shutdown() {
		for(int i=0; i<=connections.size()-1; i++) {
			connections.get(i).close();
		}
		connections.clear();
	}
	
}

ClientConnection.java
Code:
package client;

import java.net.Socket;
import java.net.UnknownHostException;
import java.io.PrintWriter;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class ClientConnection extends Thread{

	private String ip;
	private int port;
	private Socket socket;
	private PrintWriter out;
	private BufferedReader in;
		
	public ClientConnection(String ip, int port) throws UnknownHostException, IOException {
		this.ip = ip;
		this.port = port;
		this.socket = new Socket(ip, port);
		
		this.out = new PrintWriter(socket.getOutputStream());
		this.in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
				
		this.start();
	}

	public String getIP() {
		return ip;
	}
	public void sendMessage(String text) {
		this.out.println("<message>" + text);
		this.out.flush();
	}
	public void close() {
		this.interrupt();
		try {
			this.socket.close();
		} catch(Exception ex) {}
	}
	
	public void run() {
		while(!isInterrupted()) {
			try {
				String input = this.in.readLine();
				System.out.println("Server said: " + input);
			} catch(Exception ex) {
				this.interrupt();
			}
		}
	}
	
}


Ich hoffe irgendwer kann mir helfen. Wenn ihr das so auch nicht hinbekommt, meldet euch irgendwie, dann kann ich euch das komplette Projekt als .zip-File zuschicken.

mfg
jagdfalke
 

Campino

Top Contributor
also: gegen das "server said: (buh pfui is das mit "sayed"): null" hilft folgenes:
Teste input gegen null, also:
Code:
if(input==null){
   //Server is weg, d.h. du kannst den Vector aktualisieren...die connection closen oder was immer du machen willst...
}
 

jagdfalke

Bekanntes Mitglied
ouch, das tut echt weh so ein Fehler :D Und sowas ist im LK Englisch :D (habs mal editiert)

Ja das stimmt schon, das würde helfen. Aber mich interessiert auch wie dieses null zustande kommt. Was macht der BufferedReader da eigentlich? Der blockiert doch den Thread oder? Aber hat der ein Timeout oder was?

mfg
jagdfalke
 

Campino

Top Contributor
Der BufferedReader ließt eine Zeile (readLine()), wenn keine Zeile gesendet wird, ließt er null. Deine isInterrupted()-Methode gehört zu Thread, weil der Thread aner nicht weiß, dass er was mit dem Bufferedreader zu tun hat, läuft er wieter, wenn der Reader schon nichts mehr (eben null) liefert...

Normalerweise würde man:
Code:
BufferedReader br=nrew BufferedReader(...);
String line;
while((line=br.readLine)!=null){
    //mach was du willst, die gelesene Zeile ist in line...
}

verwenden. Die while()-Schleife wird automatisch verlassen, wenn der BufferedReader nichts mehr ließt.
 

Campino

Top Contributor
Returns:
A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached
Noch einmal für den Englisch-LK:
Rückgabewert:
Ein String der den Inhalt der Zeile enthält, ohne Zeilenumbruchzeichen, oder null wenn das Ende des Streams erreicht ist.

Schlafmangel+Coca-Cola=Gute Laune

Gute Laune->Ich gehe allen auf die Nerven ;p
 

jagdfalke

Bekanntes Mitglied
Meine Fresse, da macht man mal nen Fehler (und noch dazu nichtmal in Java) und schon wird man nurnoch gflamed :D

Ok, mir war nur nicht klar, was "end of the stream" bedeutet. Ob nur die Übertragung vielleicht zu lange dauert oder was auch immer. Aber jetzt isses klar.

Thx
jagdfalke
 

Lim_Dul

Top Contributor
Passiert :)
Ich bin bei Sockets auch schon reingefallen, dass ich dachte, da kommt bestimmt eine IOException - Denkste :)

1) Wie kann ich im Server bzw im Client überwachen lassen, ob eine Verbindung noch besteht, damit die Vektoren aktualisiert werden können?
Regelmässig einen Ping an die Clients senden. Beim Senden gibt es nämlich eine IOException, wenn die Verbindung nicht mehr aktiv ist ;)
 

jagdfalke

Bekanntes Mitglied
Ich weiß jetzt nicht ob meine Methode "idiotensicher" ist haber ich habs jetzt so gemacht mit der Überwachung ob die Verbindung noch besteht: Ich lese vom BufferedReader und wenn null dabei raus kommt lasse ich den Socket schließen und ein Event feuern, damit auch alle nötigen Klassen darüber bescheid wissen.
Ist das so ok? Also beim Testen bis jetzt hats geklappt.

mfg
jagdfalke
 

Campino

Top Contributor
Lim_Dul hat gesagt.:
Müsste auch funktionieren.

Was liefert der BufferedReader den, wenn nichts gesendet wird? Sperrt er dann den Thread? Sieht ja in der Schleifenvariante so aus...

jagdfalke:
für fehler in Java würde ich dich nicht flamen, da hätte ich hier ja nurnoch Feinde :bae: :D
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
T Brauche Hilfe beim GET-String für HttpURLConnection Netzwerkprogrammierung 4
E RMI RMI - Brauche Hilfe? Netzwerkprogrammierung 7
André B. Brauche Hilfe bei Chat Netzwerkprogrammierung 6
O Ich brauche RIP- und OSPF-Quellcodes? Netzwerkprogrammierung 3
I Welche IP/Addresse brauche ich ? Netzwerkprogrammierung 9
P Was brauche ich alles / wo sollte ich einen Blick drauf werfen? Netzwerkprogrammierung 17
J Objekt mit RSA und AES verschlüsseln und entschlüsseln HILFE Netzwerkprogrammierung 4
platofan23 Socket Hilfe mit Socket Thread und ArrayList Netzwerkprogrammierung 6
V Kann man mit Hilfe eines Java-Programms den Zugriff auf bestimmte Internetseiten verhinden? Netzwerkprogrammierung 3
C JSON, API ... Anfänger braucht eure Hilfe Netzwerkprogrammierung 10
KingSquizzi3 Website parsen mit Hilfe von jsoup funktioniert nicht Netzwerkprogrammierung 3
J Hilfe beim programmiern einer App zur Anmeldung im Wlan-Netzwerk Netzwerkprogrammierung 0
B JKS erstellen bitte um hilfe Netzwerkprogrammierung 1
R Hilfe bei FTP Netzwerkprogrammierung 7
D HTTP Bräuchte hilfe mit Http Requests Netzwerkprogrammierung 6
R Benötige Hilfe bei Routereinstellungen Netzwerkprogrammierung 7
xDarkSunx Hilfe Chat Login Netzwerkprogrammierung 7
K Datenübertragung UDP Hilfe ????? Netzwerkprogrammierung 5
H Hilfe bei multiplen Clients Netzwerkprogrammierung 7
N Client - Server kurze Hilfe bitte Netzwerkprogrammierung 2
T IP Adresse mit Hilfe der MAC Adresse ermitteln Netzwerkprogrammierung 3
D Hilfe ich komme bei meinem UDP chat Server nicht mehr weiter Netzwerkprogrammierung 9
D Hilfe, meine HttpURLConnection hängt manchmal. Netzwerkprogrammierung 9
eQui Hilfe bei Chatprogramm Netzwerkprogrammierung 3
TRunKX Hilfe beim senden und empfangen Netzwerkprogrammierung 2
D Netzwerk Game, bitte hilfe. Netzwerkprogrammierung 2
N JMS Newbie braucht hilfe Netzwerkprogrammierung 6
S Noob braucht dringend hilfe bei ftp-client Netzwerkprogrammierung 2
S persistence.xml in JFX Projekt einbinden Netzwerkprogrammierung 2
M JSP wird im gesamten Projekt nicht neugeladen Netzwerkprogrammierung 3
W RMI funktioniert nur wenn ich im selben Eclipse Projekt bin Netzwerkprogrammierung 3
S Idee für Projekt auf Agentenbasis Netzwerkprogrammierung 8

Ähnliche Java Themen

Neue Themen


Oben