Netzwerk und Objekte

sence

Bekanntes Mitglied
Hallo Forum,

Ich wollte einen Server und einen client schreiben, welche sich über Object verständigen.
Dazu benutze ich die ObjectOutputStream und ObjectInputStream.

als erstes wollte ich nen Chat damit bauen.
Der Server:
funktion broadcast -> um das Object an alle zu verteilen.
und die readObject funktion um neue Nachrichten zu umpfangen.

der Code:
Code:
package server;


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

public class server implements Runnable
{
	public static final int PORT = 4711;
	protected ServerSocket listen;
	protected Vector connections;
	Thread connect;

	public server()
	{
		try
		{
			listen = new ServerSocket(PORT);
		} catch (IOException e)
		{
			System.err.println("Fehler beim Erzeugen der Sockets: " + e);
			System.exit(1);
		}

		connections = new Vector();

		connect = new Thread(this);
		connect.start();

				
		}


	public void run()
	{
		try
		{
			while(true)
			{
				Socket client=listen.accept();

				connection c = new connection(this, client);
				connections.addElement(c);
			}
		} catch (IOException e)
		{
			System.err.println("Fehler beim Warten auf Verbindungen:"+e);
			System.exit(1);
		}
	}

	public static void main(String[] args)
	{
		new server();
	}

	public void broadcast(Object o) throws IOException
	{
		int i;
		connection you;

		for (i=0; i<connections.size(); i++)
		{
			you = (connection) connections.elementAt(i);
			you.out.writeObject(o);
			you.out.flush();
			
		}
	}
}

Der code für die connection im Server:
Code:
package server;

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



class connection extends Thread
{
	protected Socket client;
	protected ObjectInputStream in;
	protected ObjectOutputStream out;
	protected server server;

	public connection(server server, Socket client)
	{
		this.server=server;
		this.client=client;

		try
		{
			in = new ObjectInputStream(client.getInputStream());
			out = new ObjectOutputStream(client.getOutputStream());
		} catch (IOException e)
		{
			try { 
				client.close(); 
				} catch (IOException e2) {System.out.println(e2);} 
			System.err.println("Fehler beim Erzeugen der Streams in Class 'connection': " + e);
			return;
		}

		this.start();
	}


	public void run()
	{
		Object o;
		
		try
		{
			do {
                o = in.readObject();
                
                System.out.println(this + " received: " );
                server.broadcast(o);               
            } while (o != null);
			
		} catch (IOException e)
		{
			System.out.println("Fehler:" + e);
		} catch (ClassNotFoundException e) {
			System.err.println("Fehler in: in.readObject");
			e.printStackTrace();
		}
	}
}


Der Client:
Code:
package client;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Event;
import java.awt.Font;
import java.awt.Frame;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;

public class JFrameChat extends Frame implements Runnable {

	private static final long serialVersionUID = -9002765186074024965L;
	int PORT = 4711;
	String IP = "10.12.0.5";
	Socket socket;
	ObjectInputStream in;
	ObjectOutputStream out;
	TextField inputfield;
	TextArea outputarea;
	Thread thread;
	
	TextField tf;
	
	
	
	public JFrameChat(String titel) {
		super(titel); // Programm name
		
				
		tf = new TextField("Ihr Name");
		tf.setVisible(true);
		
		
		inputfield = new TextField();
		outputarea = new TextArea();
		outputarea.setFont( new Font("Dialog", Font.PLAIN, 12));
		outputarea.setEditable(false);

		
		this.setLayout(new BorderLayout());
		add("North", tf);
		add("South", inputfield);
		add("Center", outputarea);
		
	    setBackground(Color.lightGray);
		setForeground(Color.black);

		inputfield.setBackground(Color.white);
		outputarea.setBackground(Color.white);
		this.setSize(500, 300);		
		
		addWindowListener(new CMeinWindowLauscher());
		this.setVisible(true);
	}
	// Fenster Schließbar machen
	class CMeinWindowLauscher extends WindowAdapter {
	    public void windowClosing(WindowEvent ev) {
	      
	      System.exit(1);
	    }
	  }
	
	public void start() {
		try
		{
			say("Verbindung wird hergestellt... " + IP + ":" + PORT);
			socket = new Socket(IP, PORT);				
			say("Verbindung zum Server aufgenommen...");
		} catch (IOException e)
		{
			String Error = e.toString();
			say("Verbindung zum Server fehlgeschlagen! \n" + Error);
			say("IP ADRESSE: " + IP + " PORT: " + PORT);
			
		}

		

		if (thread == null)
		{
			thread = new Thread(this);
			thread.setPriority(Thread.MIN_PRIORITY);
			thread.start();
		}
	}
	
	
	
	public void run() {
		
		try {
		in = new ObjectInputStream(socket.getInputStream());
        System.out.println("lese inpustream");
        Object receivedObject = null;
        tcpContent tC;
        do {
        	receivedObject = in.readObject();
            tC = (tcpContent) receivedObject;
            System.out.println(this + " received: " + tC.getChatText());
            outputarea.appendText(tC.getChatText() + '\n' );
        } while (receivedObject != null);
					
			}
		 catch (IOException e) {
			 say("Verbindung zum Server abgebrochen"); } catch (Exception e) {
			// TODO Auto-generated catch block
			 System.out.println("Fehler bei in.Readobject: ");
			 e.printStackTrace();
		}
	}

    // aus Application Actionevent auslesen ob herkunft von inputfeld kommt
	public boolean action(Event e, Object what)	{ 
		if (e.target==inputfield)
		{
			String inp = (String) e.arg;
			Date now = new Date();
			SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
			tcpContent tC = new tcpContent();
			
			String tmp_chat = (tf.getText() + " [" + sdf.format(now) + "]: " + inp);
			tC.setChatText(tmp_chat);
			tC.setUsername("name");
			
			try {
				out = new ObjectOutputStream(socket.getOutputStream());
				out.writeObject(tC);
				out.flush();
			} catch (IOException e1) {
				System.out.println("fehler in der Ausgabe von out");
				e1.printStackTrace();
			}
			inputfield.setText("");
			return true;
		}

		return false;
	}

	

	
	public void say(String msg)
	{
		outputarea.appendText("*** "+msg+" ***\n");
	}
	
	
	public void destroy()
	{
		try
		{
			socket.close();
		} catch (IOException e)
		{
			System.out.println(e.toString());
		}

		if ((thread !=null) && thread.isAlive())
		{
			thread.stop();
			thread = null;
		}
	}
	public static void main(String[] args) {
		
		JFrameChat jfc = new JFrameChat("www.Systemhaus-Schuth.de - Communication Software");
		jfc.pack();
		jfc.setSize(500, 300);
		jfc.start();
		
	}
}

die Klasse tcpContent (inhalt -> object)
Code:
import java.io.Serializable;


public class tcpContent implements Serializable {

	private static final long serialVersionUID = -3933058717055994310L;

	public tcpContent() {
		
	}
	
	String chatText;
	String username;
	
	// Getter and Setter CHATTEXT
	public void setChatText(String a) {
		this.chatText = a;
	}
	public String getChatText() {
		return this.chatText;
	}
	// Getter and Setter USERNAME
	public void setUsername(String n) {
		this.username = n;
	}
	public String getUsername() {
		return this.username;
	}
	
}


Mein fehler ist folgender:

die Nachricht wird nur beim ersten mal ausgeliefert, mehr oder weniger...

dann kommt:
Fehler:java.io.StreamCorruptedException: invalid type code: AC
Fehler:java.io.StreamCorruptedException: invalid type code: AC

wo liegt mein Fehler :/

danke
 

Kr0e

Gesperrter Benutzer
Wenn ich mich richtig errinnere liegt der Fehler darin, dass du nicht abwartest, dass das gesamte Object wirklich verfügbar ist...
Sprich grad über Internet kann es sein, dass ein Array z.b. zerhackstückelt eintrifft....
Teste es doch einfahc mal... Schreibe mit einem ObjectOutputStream und ByteArrayOutputStream ein Object in ein array...
Dann schickst du zuerst die Länge des Arrays... Auf der anderen Seite empfängst du zuerst die Länge und wartest dann bis ein Array entsprechender Größe angekommen ist... Danach mit einem ObjectInputStream wieder deserialisieren....
Geht vlt iwie noch einfacher... (Vlt. kannste den BufferedOutputStread/BufferedInputStream) irgendwie clever koppeln mit einem ObjectInput/OutputStream...

Die Fehlermeldun besagt übrigens, dass die Daten zum deserialisren nicht ausreichen... Das kann mehrere Gründe haben...
Aber versuch das einfahc mal, was ich geschrieben hab, vlt wars das ja...

Gruß Chris
 

Michael...

Top Contributor
Ist schon eine Weile her, dass ich mich mit Serialisierung auseinander gesetzt habe, aber ich vermute die Ursache liegt an dem serialisierten Objekt bzw. an dem ObjectOutputStream.
Der ObjectOutputStream hat die Eigenschaft, dass er sich merkt, welche Objekte er bereits gesendet hat. Ändern sich Objekte und werden ein weiteres mal gesendet, wird nicht das gesamte Objekt sondern nur die geänderten Attribute nachgesendet.

Für Deinem Fall sollte beim ersten Senden noch alles funktionieren, aber beim zweiten Absenden glaubt der OutputStream, dass ein bereits gesendetes Objekt vor sich hat und da er den Inhalt von username gesendet hat sendet er nur noch den chatText. Da ist es - was meiner Vermutung nach - auf der Empfängerseite Probleme macht.

Lange Rede kurzer Sinn: Probier mal im Client nach jedem Versenden eines Nachrichtenobjekts ein reset() auf den OutputStream aufzurufen - reset() löscht das "Gedächtnis" des Streams.
 

Kr0e

Gesperrter Benutzer
Hmm, ich denke nicht, dass das sein Problem ist... Er bekommt doch eine StreamCorruptedException...
Da muss schon iwas größeres passiert sein...

Gruß,
Chris
 
S

SlaterB

Gast
im der JFrame-Klasse des Clients in der action-Methode wird der OutputStream für jede Nachricht neu erstellt,
so geht das nicht,
wenn der alte vom GarbageCollector aufgeräumt wird, ist hoffentlich die Verbindung ganz weg,
ansonsten hat man immer noch das Problem, dass der neue Stream seine Meta-Informationen wie 'Beginn der Übertragung' usw. reinschreibt,
während die Gegenseite auf mittlere Informationen wartet, jedenfalls nicht mit einem Neuanfang rechnet, daher versteht sie das Token 'AC' nicht

Streams immer nur einmal erzeugen,
if (out == null) {
out = new ObjectOutputStream(socket.getOutputStream());
}
statt
out = new ObjectOutputStream(socket.getOutputStream());
in action() funktioniert vorerst, generell aber lieber aufgeräumt, beim Server klappt das ja ganz gut,

Klassen groß schreiben!
 

sence

Bekanntes Mitglied
Habe mich noch bis in die Nacht damit beschäftigt.
Vielen Dank erstmal für eure Hilfestellungen!

habe meine Antwort in einem Example gefunden mit dem selben Hinweiß von SlaterB.

Der Outputstream darf nur einmal erzeugt werden :O)

Nun hab ich ein schönes Objektorientiertes TCP/IP Grundgerüst um darauf aufzubauen.
(und Ihr auch *g*)

Der OutputStream muss im Client mit in der run() Methode definiert sein, nicht an anderer Stelle.

Vielen Dank :- )

UPDATE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ???:L

Soweit funktioniert alles, jedoch ist dort noch nen Fehler.
Sobald ein Client offline geht, will der chat nicht mehr :O
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
I Objekte über das Netzwerk Netzwerkprogrammierung 5
P Serialialiserte Objekte übers Netzwerk verschicken Netzwerkprogrammierung 9
I ActiveMQ-Messages übers Netzwerk Netzwerkprogrammierung 13
M Socket Netzwerk Übertragung zwischen 4 Clients Netzwerkprogrammierung 2
temi (Netzwerk-) Kommunikation zwischen Anwendungen. Wie? Netzwerkprogrammierung 5
W Das Netzwerk entfernen mit Wifi Manager Netzwerkprogrammierung 1
F Neuronales Netzwerk - Genetischer Algorithmus Netzwerkprogrammierung 0
windl Sporadische Aussetzer im Netzwerk Netzwerkprogrammierung 10
T Broadcast-message über spez. Netzwerk-Schnittstelle Netzwerkprogrammierung 1
MaxG. Netzwerk Ping falsches ergebnis Netzwerkprogrammierung 7
T Netzwerk Login Felder ansprechen Netzwerkprogrammierung 1
B Netzwerk - Fernsteuerung Netzwerkprogrammierung 1
S Netzwerk-Framework gesucht Netzwerkprogrammierung 6
J Hilfe beim programmiern einer App zur Anmeldung im Wlan-Netzwerk Netzwerkprogrammierung 0
C Netzwerk Portzuweisungsproblem Netzwerkprogrammierung 0
I PingPong Spiel übers Netzwerk Netzwerkprogrammierung 1
M Verbindung zwischen zwei Pc in dem Selben Netzwerk Netzwerkprogrammierung 8
M PongSpiel Netzwerk Netzwerkprogrammierung 1
D Geräte im Lokalen netzwerk auflisten Netzwerkprogrammierung 1
fLooojava Daten an ein Arduino im selben Netzwerk senden Netzwerkprogrammierung 1
I Netzwerk FileShare Program Netzwerkprogrammierung 2
K ByteArray über Netzwerk senden klappt nicht Netzwerkprogrammierung 5
D Ermitteln ob WLAN-Netzwerk UDP unterstützt Netzwerkprogrammierung 1
O 4Gewinnt Multiplayer - Netzwerk Problem (TCP) Netzwerkprogrammierung 1
B WebSocket Verbindungsaufbau aus localen Netzwerk Netzwerkprogrammierung 2
S Bilder durch's Netzwerk usw ... Netzwerkprogrammierung 10
Kr0e Dezentrales Soziales Netzwerk Netzwerkprogrammierung 48
G Klassen über Netzwerk kommunizieren lassen Netzwerkprogrammierung 6
vandread Zugriff auf Soziales Netzwerk mittels Java? Netzwerkprogrammierung 4
P Automatische Host suche im Netzwerk Netzwerkprogrammierung 3
D Socket Class über Netzwerk verschicken Netzwerkprogrammierung 2
S Netzwerk Verbindungsproblem mit Cajo Netzwerkprogrammierung 5
c_sidi90 ideale Lösung, Screen Capture über Netzwerk Netzwerkprogrammierung 3
J Komplexes Netzwerk-Spiel im Internet Netzwerkprogrammierung 13
J ObjectInputStream im Netzwerk Netzwerkprogrammierung 8
T ArrayList über Netzwerk senden! Netzwerkprogrammierung 5
A java im netzwerk anderen rechner runterfahren Netzwerkprogrammierung 3
U Datei über das Netzwerk einlesen und speichern Netzwerkprogrammierung 8
M Netzwerk Programmierung Netzwerkprogrammierung 2
F Netzwerk-Designkonzept Netzwerkprogrammierung 2
D Ring-Netzwerk - wie fange ich an? Netzwerkprogrammierung 3
X Password übers Netzwerk schicken jPasswordField Netzwerkprogrammierung 2
M Socket Bilder über das Netzwerk übertragen Netzwerkprogrammierung 4
c_sidi90 Alle Rechner im Netzwerk ermitteln Netzwerkprogrammierung 17
D Netzwerk-To-Do-Liste Netzwerkprogrammierung 5
Semox Socket Selbstgeschriebenen Webserver im lokalen Netzwerk publizieren? Netzwerkprogrammierung 4
S Socket nach anderen clients im netzwerk suchen Netzwerkprogrammierung 3
T Netzwerk-Dateiübertragung optimieren Netzwerkprogrammierung 15
G Netzwerk Speed checken Netzwerkprogrammierung 3
L Socket Socketverbindung nur im lokalen Netzwerk Netzwerkprogrammierung 12
F Char über Netzwerk senden Netzwerkprogrammierung 6
P SocketServer im lokalen netzwerk suchen Netzwerkprogrammierung 2
B RMI RMI, Callback und Netzwerk Netzwerkprogrammierung 6
agent47 IP Adressen im Lokalen Netzwerk Scannen Netzwerkprogrammierung 7
G Netzwerk IP Frage Netzwerkprogrammierung 4
Akrillo Datei per Netzwerk senden Netzwerkprogrammierung 10
W funktionen übers netzwerk nutzen Netzwerkprogrammierung 4
Kr0e Versenden von Daten übers Netzwerk Netzwerkprogrammierung 30
M upnp Device-Discovery im Netzwerk Netzwerkprogrammierung 5
T Administration von Software auf Clients im Netzwerk Netzwerkprogrammierung 6
H MySQL übers Netzwerk Netzwerkprogrammierung 9
A Probleme mit kleinem Netzwerk Programm Netzwerkprogrammierung 30
T Pfadangabe beim kopieren übers Netzwerk Netzwerkprogrammierung 5
G Verschlüsselte Strings über Netzwerk verschicken Netzwerkprogrammierung 19
D robustes Netzwerk Netzwerkprogrammierung 2
N HTML-Übertragung im lokalen Netzwerk mit Java - wie? Netzwerkprogrammierung 6
G Datei performant im Netzwerk verschieben Netzwerkprogrammierung 4
D BufferedImage über das Netzwerk senden Netzwerkprogrammierung 2
E Netzwerk Fehlererkennung Netzwerkprogrammierung 11
M Pc's im Netzwerk auflisten Netzwerkprogrammierung 2
T Welches Netzwerk ist am bestern für. Netzwerkprogrammierung 2
ModellbahnerTT Problem feste String ins Netzwerk zu geben Netzwerkprogrammierung 5
A IRC-Server für das lokale Netzwerk? Netzwerkprogrammierung 12
TheJavaKid Anzahl der Server im Netzwerk Netzwerkprogrammierung 7
R Spiel auf Netzwerk auslegen? Netzwerkprogrammierung 10
R Applet & Netzwerk Netzwerkprogrammierung 4
K netzwerk durchsuchen Netzwerkprogrammierung 10
A array übers netzwerk (anfänger) Netzwerkprogrammierung 8
T Möglichkeit über das Netzwerk eine Funktion zu starten? Netzwerkprogrammierung 2
flashfactor Dateien im Netzwerk kopieren Netzwerkprogrammierung 2
R File chooser übers Netzwerk Netzwerkprogrammierung 3
A Betriebssystem über Netzwerk ermitteln Netzwerkprogrammierung 11
B Netzwerk-IP´s sammeln Netzwerkprogrammierung 16
S Netzwerk übers Internet Netzwerkprogrammierung 30
J Brauche hilfe bei Projekt: Netzwerk Chatprogramm Netzwerkprogrammierung 12
M anpingen, liste aller IPs im netzwerk erhalten Netzwerkprogrammierung 5
S Spiel über Netzwerk. Netzwerkprogrammierung 7
O wie schnell kann java netzwerk sein? Netzwerkprogrammierung 7
D Netzwerk Betrachtung mit vielen Clients Netzwerkprogrammierung 2
D Netzwerk Game, bitte hilfe. Netzwerkprogrammierung 2
L netzwerk mit thread Netzwerkprogrammierung 3
B Netzwerk simulieren Netzwerkprogrammierung 2
8 ByteArray per Netzwerk verschicken Netzwerkprogrammierung 6
T Client-Authorisierung-Netzwerk Netzwerkprogrammierung 4
G Verzeichnis eines Rechners übers Netzwerk auslesen Netzwerkprogrammierung 5
B Netzwerk Dokumentation Netzwerkprogrammierung 2
G MySQL über Netzwerk --> Problem Netzwerkprogrammierung 13
M Netzwerk spiel??? Netzwerkprogrammierung 9
B Nachrichten über das Netzwerk verschicken Netzwerkprogrammierung 3
T JSON-Objekte richtig parsen Netzwerkprogrammierung 8

Ähnliche Java Themen


Oben