Seltsames Verhalten beim Empfangen von Daten über DataInputStream

skappler

Aktives Mitglied
Hallo Leute.
Ich schreibe gerade einen kleinen Netzwerk Chat mit Client und Server Application. Beide funktionieren im Prinzip gleich, nur das der eine einen Server hostet und der andere connectet.
Das Grundgerüst steht soweit und funktioniert auch, nur empfängt der Client keine Daten. Wenn ich vom Server aus eine Nachricht sende wird sie vom Client nicht gelesen. Andersrum allerdings schon. Das wundert mich, da der Code zum empfangen von nachrichten bei beiden identisch ist.
Was aber WIRKLICH seltsam ist, ist dass im Debug Modus von Eclipse alles reibungslos läuft. Wenn ich den Client debugge empfängt er alle Nachrichten vom Server korrekt.

Hier der Code der fürs empfangen verantwortlich ist :
Java:
DataInputStream in = in = new DataInputStream(serverCon.getInputStream());
PrintStream out = new PrintStream(serverCon.getOutputStream());

...

public void listenForInput(){

		while(true){
			

			try {
				String text = in.readLine();
				outputDevice.append("Partner: "+text+"\n");
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}

Kann mir jemand helfen?
 
J

jnetdev

Gast
Mit dem bisschen Code und dieser Erklärung : NEIN
Da müsstest du schon mal alles komplett posten incl StackTrace.

Ansonsten hier noch ein ziemlich einfaches chat-system : http://www.java-forum.org/netzwerkp...bindung-server-fehlgeschlagen.html#post929410


Was ich nicht verstehe : "einer macht server der andere client" ... ist in meinen Augen völlig falsche idee. Es gibt EINEN zentralen Server und ansonsten nur Clients die sich zu diesem verbinden. Fertig aus ende.
 

skappler

Aktives Mitglied
Ok dann poste ich einfach mal alles^^
Das Problem ist: es gibt keine StackTraces. Damit könnte ich ja noch wenigstens was anfangen. Es passiert einfach garnichts.

Das mit dem Server hab ich so gemeint, dass es im moment nur möglich ist auf den Server einen einzigen Client zu connecten. Später wollte ich das ganze dann über Threads regeln, so dass mehrere Clients connecten können.
Im moment ist das ganze so gedacht, dass ich zwei Programme laufen hab. Oberflächlich beide identisch, nur hat eines der beiden intern einen ServerSocket, auf den der andere nach eingabe der IP Adresse connectet.

Hier nun der Code (die Klassen aufteilung und das Klassendesign ist sehr schlecht. Das ist eine meiner größten schwächen, aber ich arbeite dran :p)

GUI.java
Java:
package com.net.gui;

import java.awt.FlowLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class GUI extends JFrame{

	public String title = "GUI";
	
	public static String VERSION = "0.1.0";
	
	JTextArea area;
	JTextField commandLine;
	
	public GUI(String title){
		
		setTitle(title);
		setSize(420,320);
		setResizable(false);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		setLayout(new FlowLayout());
		
		area = new JTextArea(16,34);
		area.setLineWrap(true);
		JScrollPane pane = new JScrollPane(area);
		
		add(pane);
		
		commandLine = new JTextField(34);
		commandLine.requestFocus();
						
		add(commandLine);
		
		setVisible(true);
		
	}
	

	public static String getVERSION() {
		return VERSION;
	}

	public JTextArea getTextArea() {
		return area;
	}

	public JTextField getCommandLine() {
		return commandLine;
	}
	
	public void appendText(String s){
		area.append(s);
	}
	
	public void setText(String s){
		area.setText(s);
	}
	
}

ServerFunc.java
Java:
package com.net.server;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

import javax.swing.JTextArea;
import javax.swing.JTextField;

public class ServerFunc implements KeyListener{
	
	
	boolean keyTyped = false;

	ServerSocket myServer;
	Socket clientCon;
	
	DataInputStream in;
	PrintStream out;
	
	JTextArea outputDevice;
	JTextField inputDevice;
	
	public static int PORTNUMBER = 3333;
	
	public ServerFunc(JTextArea o, JTextField i){
		
		outputDevice = o;
		inputDevice = i;
		
		i.addKeyListener(this);
		
	}

	public void start() throws IOException{
		myServer = new ServerSocket(PORTNUMBER);
		outputDevice.append("Waiting for Connection\nYour IP is "+InetAddress.getLocalHost().getHostAddress());
		
		
		
		clientCon = myServer.accept();
		
		outputDevice.append("Client connected\nSay Hello!\n");
		
		in = new DataInputStream(clientCon.getInputStream());
		out = new PrintStream(clientCon.getOutputStream());
		
		listenForInput();
		
	}
	
	@SuppressWarnings("deprecation")
	public void listenForInput(){
			while(true){
				

				try {
					String text = in.readLine();
					outputDevice.append("Partner: "+text+"\n");
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
	}
	
	@Override
	public void keyPressed(KeyEvent arg0) {
		
		if (!keyTyped) {
			keyTyped = true;
			switch (arg0.getKeyCode()) {
			case KeyEvent.VK_ENTER:
				handleInput(inputDevice.getText());
				inputDevice.setText("");

				break;
			}
		}
			
	}

	private void handleInput(String text) {
		
		if(text.startsWith("/")){
			//handle Commands
			if(text.equals("/help")){
				outputDevice.append("No Help available\n");
			}
			
			
		}else{
			//send Text
			
			if(out != null) {
				out.println(text);
				outputDevice.append("You: "+text+"\n");
			}
			
		}
	
	
	}
	
	
	

	@Override
	public void keyReleased(KeyEvent arg0) {
		keyTyped = false;
	}

	@Override
	public void keyTyped(KeyEvent arg0) {
				
		
	}
	
}

ServerMain.java
Java:
package com.net.server;

import java.io.IOException;

import com.net.gui.GUI;

public class ServerMain {

	
	public static void main(String[] args) {
		GUI gui = new GUI("Server "+GUI.VERSION);
		ServerFunc function = null;
		
		function = new ServerFunc(gui.getTextArea(), gui.getCommandLine());

		//gui.getCommandLine().addKeyListener(function);
		
		try {
			function.start();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}

ClientFunc.java
Java:
package com.net.client;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.JTextArea;
import javax.swing.JTextField;

public class ClientFunc implements KeyListener{
	
	boolean connected = false;
	boolean keyTyped = false;

	String text;
	
	Socket serverCon;
	
	DataInputStream in;
	PrintStream out;
	
	JTextArea outputDevice;
	JTextField inputDevice;
	
	public static int PORTNUMBER = 3333;
	
	public ClientFunc(JTextArea o, JTextField i){
		
		outputDevice = o;
		inputDevice = i;
		
		i.addKeyListener(this);
		
	}

	public void start() throws IOException{
		outputDevice.append("Type \"/connect IPADRESS\" to connect\n");
		
		
	}
	
	public void connect(InetAddress i){
		try {
			
			serverCon = new Socket(i, PORTNUMBER);
			in = new DataInputStream(serverCon.getInputStream());
			out = new PrintStream(serverCon.getOutputStream());
			
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		outputDevice.append("> Connected to Server\n");
		outputDevice.append("> Say Hello!\n");
		connected = true;
	}
	
	@SuppressWarnings({ "deprecation", "deprecation" })
	public void listenForInput(){

		while(true){
			

			try {
				String text = in.readLine();
				outputDevice.append("Partner: "+text+"\n");
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
	}
	
	@Override
	public void keyPressed(KeyEvent arg0) {
		
		if (!keyTyped) {
			keyTyped = true;
			switch (arg0.getKeyCode()) {
			case KeyEvent.VK_ENTER:
				handleInput(inputDevice.getText());
				inputDevice.setText("");

				break;
			}
		}
			
	}

	private void handleInput(String text) {
		
		if(text.startsWith("/")){
			//handle Commands
			if(text.equals("/help")){
				outputDevice.append("No Help available\n");
			}
			if(text.startsWith("/connect")){
				String[] arr = text.split(" ");
				
				//TODO Regex for IP adresses
				try {
					InetAddress i = InetAddress.getByName(arr[1]);
					connect(i);

				} catch (UnknownHostException e) {
					outputDevice.append("Illegal IP\n");
				}
				//listenForInput();
			}
			
			
		}else{
			//send Text
			
			if(out != null)
				
					out.println(text);
					outputDevice.append("You: "+text+"\n");

				
		}
	
	
	}
	
	
	

	@Override
	public void keyReleased(KeyEvent arg0) {
		keyTyped = false;
	}

	@Override
	public void keyTyped(KeyEvent arg0) {
				
		
	}
	
}

ClientMain.java
Java:
package com.net.client;

import java.io.IOException;

import com.net.gui.GUI;

public class ClientMain {

	
	public static void main(String[] args) {
		GUI gui = new GUI("Client "+GUI.VERSION);
		ClientFunc function = null;
		
		function = new ClientFunc(gui.getTextArea(), gui.getCommandLine());

		
		try {
			function.start();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		while(!function.connected){
			
		}
		function.listenForInput();
		
	}

}

Wie gesagt beim debuggen läuft alles. Zuerst dacht ich es liegt am Breakpoint in der listenForInput Methode, ohne ihn gings aber auch.
 

Michael...

Top Contributor
Also ich finde den Code etwas verwirrend, aber wenn ich's richtig überblicke hängt der Client doch in einer Endlosschleife und baut nie eine Verbindung zum Server auf:
[JAVA=23] while(!function.connected){ }[/code]
Abgesehen davon, dass die Schleife grundsätzlich merkwürdig ist. Wenn überhaupt regelt man sowas über Listener/Observer o.ä.
 
S

SlaterB

Gast
bei mir geht alles bestens, wenn aus einer main alles gestartet auf einen Rechner, mit Threads

die readLine()-Methode in DataInputStream ist deprecated, vielleicht gibts Probleme mit Zeilenumbrüchen,
testweise solltest du erstmal einzelne Bytes mit read() lesen, und z.B. zählen, kommt überhaupt irgendwas an?
mehr Bytes bei längeren Nachrichten?

eine Schleife
> while (!function.connected) { }
ist wirklich ein GAU, wird millardenfach pro Sekunde wiederholt, läßt einen CPU-Kern auf dem Rechner auf 100% Belastung schmoren, bis endlich Verbindung aufgebaut,
mit einem einfachen Thread.sleep(10) darin schaffst du ummerkbare Pausen so das trotzdem in einem ganzen Menschenleben an Zeit nicht mehr so viel gearbeitet werden muss wie sonst in einer Sekunde
 

skappler

Aktives Mitglied
Ja ich weiß das ist sehr sehr unschön :p Aber es funktioniert. Es funktioniert weil die änderung von connected durch den KeyListener ausgelöst wird.
Ich wusste einfach nicht wie ich ihm sagen soll, auf die Änderung von connected zu warten.
Er verlässt die Schleife jedenfalls und baut auch eine Verbindung auf, sonst könnte ich ja garkeine Nachrichten schicken

EDIT:
@SlaterB
Auf die Idee mit Thread.sleep() bin ich garnicht gekommen. Schande über mich :p
Die Idee mit den Bytes lesen war gut. Er empfängt etwas. Ich empfange alles in ein byte[] und gebe das dann aus. Wie erwartet standen die ASCII Codes der einzelnen Buchstaben darin, sowie am schluß noch der Zeilenumbruch. Auch wird jetzt im Chatfenster was ausgegeben, nämlich die toString Variante des Arrays.
Kann ich das jetzt Irgendwie wieder auf Strings umstellen? Vor allem damit die Länge beliebig sein kann. Ich könnte ja jetzt aus dem array einen String zusammenbasteln, das kommt mir aber sehr umständlich vor.
 
Zuletzt bearbeitet:

skappler

Aktives Mitglied
Ok hab das Problem gelöst. Hab einfach, wie von Eclipse vorgeschlagen, einen BufferedReader genommen. Wenn jemand trotzdem noch einen Tipp hat wie ich das Problem mit der Endlosschleife "verschönern" kann, bitte melden ;)
 
S

SlaterB

Gast
oh, Posting heute morgen gar nicht gesehen,
eine Alternative wäre noch, das listenForInput() in ClientFunc, in connect() zu verschieben,

eigentlich naheliegend und symmetrisch, für den Server steht der Aufruf doch auch in ServerFunc..
 

skappler

Aktives Mitglied
So hatte ich das ganze vorher, aber da das ganze aus dem KeyListener raus aufgerufen wird. Geht er dann in die while schleife zum Empfangen, steckt er von der Aufrufhierarchie immernoch im Listener fest, und kann somit keine weiteren Kommandos entgegennehmen. Das Textfeld ist dann auch inaktiv, bzw sieht so aus als ob es hängt.
 
S

SlaterB

Gast
auch wieder richtig, so bist du dorthin gekommen,
die Wahl ist nun einen zweiten Thread zu starten, der main-Thread parallel zur GUI schon lange abgelaufen,
oder mit der Schleife main warten zu lassen, das ist schon ok so

um die Symmetrie dennoch zu wahren, könnte das Warten + der Aufruf in start() in ClientFunc, wirklich weitgehend gleich zu ServerFunc,
andererseits unschön, wenn eine start()-Methode quasi die ganze Zeit läuft ;)

falls in start() nur eine GUI-Ausgabe steht, rechtfertigt das auch das try/catch drumherum nicht wirklich,
freilich bleibt es ohne Funktion, solange listenForInput() selbst auch abfängt
 

skappler

Aktives Mitglied
auch wieder richtig, so bist du dorthin gekommen,
die Wahl ist nun einen zweiten Thread zu starten, der main-Thread parallel zur GUI schon lange abgelaufen,
oder mit der Schleife main warten zu lassen, das ist schon ok so

um die Symmetrie dennoch zu wahren, könnte das Warten + der Aufruf in start() in ClientFunc, wirklich weitgehend gleich zu ServerFunc,
andererseits unschön, wenn eine start()-Methode quasi die ganze Zeit läuft ;)

falls in start() nur eine GUI-Ausgabe steht, rechtfertigt das auch das try/catch drumherum nicht wirklich,
freilich bleibt es ohne Funktion, solange listenForInput() selbst auch abfängt

Ich hab noch nie wirklich mit THreads gearbeitet, deshalb hab ich das ganze ohne versucht. Mit wäre es wahrscheinlich schöner, aber ich wollte erstmal die grundlegenden Funktionen zum laufen bringen und mich dann um Threads kümmern, auch um evtl. mehrere Clients zu akzeptieren. (Ich bräuchte dann ja weiterhin nur einen ServerSocket, aber mehrere normale Sockets in der Server Klasse, seh ich das richtig?)

Der Code wie ich ihn hier gepostet habe ist noch sehr unschön. Jetzt wo alles läuft will ich das noch verbessern und optimieren. Das try/catch für die start() Methode ist nur ein überbleibsel, als ich noch das connect darin aufgerufen habe, wird also auch noch entfernt bzw. angepasst.

Vielen Dank für eure/deine Hilfe!
 
J

jnetdev

Gast
grundsätzlich gilt : blocking I/O-Ops in seperate Threads !

ansonsten freezed die GUI oder der rest der logik ...
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
R Seltsames Verhalten bei GET Request Netzwerkprogrammierung 7
X HTTP Seltsames Charset Netzwerkprogrammierung 8
M JAVA to php seltsames Fragezeichen in Ausgabe Netzwerkprogrammierung 7
S Seltsames Socketproblem Netzwerkprogrammierung 3
K Frage zum Verhalten von SocketChannel.write(.) Netzwerkprogrammierung 9
OnDemand Json Objekt leeres Array beim lesen Netzwerkprogrammierung 9
T Brauche Hilfe beim GET-String für HttpURLConnection Netzwerkprogrammierung 4
A sporadischer Fehler beim Schreiben auf NAS Netzwerkprogrammierung 2
A Automatisches Update beim Starten Netzwerkprogrammierung 1
J Hilfe beim programmiern einer App zur Anmeldung im Wlan-Netzwerk Netzwerkprogrammierung 0
A Problem beim Senden von Client zu Server Netzwerkprogrammierung 10
M Nur die erste Nachricht kommt beim Server an Netzwerkprogrammierung 11
M jsf-seite beim hinzufügen einer csv-datei in einen ordner aktualiseren Netzwerkprogrammierung 0
R Problem beim Programmieren eines Chatprogramms Netzwerkprogrammierung 5
A Probleme beim Klassen-Import von sun.misc. ... Netzwerkprogrammierung 19
B Probleme beim ersten Netzwerkprogramm Netzwerkprogrammierung 3
S Umstellung AS400 auf Postgre - Problem beim Arbeiten mit Metadaten Netzwerkprogrammierung 2
G Socket NIO2 Problem mit AsynchronousSocketChannel beim Schließen Netzwerkprogrammierung 3
Z Socket Probleme beim Senden und Empfangen Netzwerkprogrammierung 5
D RMI Problem beim shutdown von verteilter CORBA-Anwendung Netzwerkprogrammierung 6
Z Probleme beim Senden von Nachrichten an den Server Netzwerkprogrammierung 9
S Socket Verschiedene Exceptions beim Übertragen von Bildern über Socket Netzwerkprogrammierung 20
C ObjectInputReader wirft beim zweiten Aufruf eine Exception Netzwerkprogrammierung 3
Y RMI Initialisierung beim Server Netzwerkprogrammierung 10
B Socket Aufhängen beim Lesen Netzwerkprogrammierung 4
C Socket Probleme beim Lesen und Schreiben aus/in einen Socket Netzwerkprogrammierung 2
M Problem beim Datenempfang Netzwerkprogrammierung 2
DEvent Keine IOException beim schreiben Socket Netzwerkprogrammierung 3
M Authentifizierung beim Start von Java-Applets Netzwerkprogrammierung 2
N NIO Problem beim speziellen Behandeln von einzelnen Benutzern Netzwerkprogrammierung 13
E HTTP Problem beim Auslesen von Websiten Netzwerkprogrammierung 6
G Kryptische Zeichen beim Auslesen einer Website Netzwerkprogrammierung 11
Y Problem mit ObjectInputStream beim lesen vom Socket Netzwerkprogrammierung 10
T ServerSocket bleibt beim lesen von Input hängen Netzwerkprogrammierung 2
P HTTP Problem beim Download von einer Datei Netzwerkprogrammierung 4
clupus Exception beim Schließen eines Sockets Netzwerkprogrammierung 6
P Probleme beim weiter senden von Datein Netzwerkprogrammierung 10
S Threads beim Server koordinieren Netzwerkprogrammierung 5
K TrafficClass eines UDP Pakets kommt beim Empfänger nicht an Netzwerkprogrammierung 5
T Pfadangabe beim kopieren übers Netzwerk Netzwerkprogrammierung 5
Q NullPointExeption beim Versuch byte[] zu senden/writen Netzwerkprogrammierung 3
S Probleme beim senden von Daten per POST Methode an PHP Scrip Netzwerkprogrammierung 5
G Blockieren beim Öffnen der In und Outputstreams Netzwerkprogrammierung 2
I Problem beim empfangen von Daten (Zahlen) Netzwerkprogrammierung 7
J Was bedeutet: Address already in use: connect (beim client?) Netzwerkprogrammierung 4
Rontu Problem beim Übertragen einer Datei Netzwerkprogrammierung 9
J Problem beim Senden von File Netzwerkprogrammierung 4
G unbekannte Zeichen beim senden und lesen Netzwerkprogrammierung 2
V Problem beim Senden von Dateien Netzwerkprogrammierung 4
P problem beim schließen eines Streams Netzwerkprogrammierung 6
J RMI Fehler beim Proxy Netzwerkprogrammierung 2
G Fehlermeldung beim Erzeugen der WSDL Datei unter Axis Netzwerkprogrammierung 2
C Session Problem beim Zugriff auf Webseiten Netzwerkprogrammierung 3
J while-Schleife / Abbruchbed. beim Einlesen eines Streams Netzwerkprogrammierung 4
M Fehlende Bits / Bytes beim kopieren Netzwerkprogrammierung 4
I Apache http-client: Problem beim Proxyaufruf Netzwerkprogrammierung 2
C RMI: Problem beim Aufruf einer Methode. Falsch gecastet? Netzwerkprogrammierung 8
T RMI - Probleme beim Starten des Clients Netzwerkprogrammierung 4
D Problem beim holen einer PHP-Seite via HttpClient Netzwerkprogrammierung 19
G ActionEvent klappt beim Chat nicht Netzwerkprogrammierung 5
megachucky RMI - AccessControlException beim Naming.lookup() Netzwerkprogrammierung 12
G Probleme mit Firewall beim empfangen von dateien über socket Netzwerkprogrammierung 6
J Problem beim versenden von eigenen Objekten über RMI Netzwerkprogrammierung 2
M sessionhandling beim webserver Netzwerkprogrammierung 5
D Bekomme Dummyspace beim Internetseiten auslesen Netzwerkprogrammierung 2
R Problem beim Senden von Emails (Javamail) Netzwerkprogrammierung 2
TRunKX Hilfe beim senden und empfangen Netzwerkprogrammierung 2
S Probleme beim Beschränken der Geschwindigkeit Netzwerkprogrammierung 6
M Probleme beim Abfangen von Streams Netzwerkprogrammierung 5
M problem beim schicken von XML-DAtenpacketen via TCP Netzwerkprogrammierung 3
D Performance Problem beim File senden, empfangen Netzwerkprogrammierung 4

Ähnliche Java Themen

Neue Themen


Oben