Localhost - ok, ip - fast ok

Hi Leute, ich weiß mal wieder nicht weiter.
Szenario: Ich fange nach den Ferien wieder mit dem Adk Klon für die Schule an. Bin dabei
die Client Server Kommunikation einzurichten. Die Clients flushen die position jeden frame auf den
server socket, dieser bastelt sich ne „private leinwand“ und zeichnet schön brav alle spieler auf dem panel.

Nun Folgendes: Wenn ich den client über localhost mit dem server verbinde, kein Problem.
(Der Client selbst sieht noch nur sich selbst, der server alle.)
Wenn ich den Client über localhost verbinde, Kein Problem, alles perfekt. (Ich teste momentan nur mit einem
einzigen Client.) Sobald ich aber, (ip forwarding ist noch von den letzten experimenten mit dem chat richtig eingstellt,
hab aber alles nochmal überprüft und mit nem minecraft server getestet), über die ip verbinden will, passiert etwas was ich absolut nicht nachvollziehen kann:

Der CLient läuft wie immer. Der ERSTE FRAME, sendet erfolgreich die position, die auf dem Server erfolgreich gezeichnet wird. Das wars. Danach passiert eine Zeit lang
nichts, der client läuft normal weiter. (Man kann die schlange bewegen.) Nach einer Zeit treten massenhaft „java.net.SocketException: Software caused connection abort: socket write error“ fehler auf, auf der CLIENT SEITE. Der Server bleibt bei dem einen kästchen, das er beim aller ersten frame gezeichnet hat. Fehler kommen nicht.

Nun, im Anhang sind noch die Screenshots, oben der Server wie er richtig laufen sollte, unten wie er falsch läuft. Ich poste erstmal keinen Code, denn er funzt mit localhost
ja perfekt, (in dem bezug) und ausserdem ähnelt der code sehr dem, den ich damals beim chat verfasst hatte, der ja auch einwandfrei läuft.

Nur die Zeilen in denen die write ex auftritt:

socketWriter.write(player.getLocation() + "
");
socketWriter.flush();

aber das ist ja klar. getloc ist ein string, write sind alle richtig eingerichtet pi pa po.
Hat jemand eine Ahnung? :frowning:

*** Edit ***

Jetzt hab ich das ganze nochmal gestartet, und währen ich den post hier geschrieben habe laufen gelassen. das programm ist zwar gefreezed, aber es kamen keine exceptions. jetzt versteht ich gar nichts mehr. (natürlich über die ip, nicht localhost)

*ausserdem ich wieder bilder vergessen tu ^^

bisschen zu lesen gibt es (naheliegend wie immer) wenn man die Exception sucht, etwa


oder der Link darin, mehr gibts wohl allgemein nicht zu sagen,

speziell zu deinem Problem wird die Exception kaum von der graphischen Darstellung abhängen oder wenn dann wichtiger Hinweis,
vereinfache dein Programm massiv, am Server kann sicherlich alles bis auf vielleicht Systemout.println-Ausgabe der empfangenden Daten oder zumindest ‘ein Paket angekommen’ wegfallen
-> ändert sich irgendwas oder genauso Exception?
ist die Exception überhaupt halbwegs produzierbar? ok, klingt ja sehr danach

beim Client arbeite ebenso vereinfacht ohne GUI, lasse Zufallsdaten senden, geht das auf einmal?
auch deinen gesammten Programminhalt mit Position und allen Fachklassen kann weg,
allein eine Schleife die x ms wartet und dann 5 Dummy-Zeichen sendet
-> ändert sich irgendwas oder genauso Exception?

wenn du so elementar den Fehler noch hast, dann schadet es nicht den Code zu posten, wahrscheinlich gibt es aber eh andere Ursachen,
falls erfreulicherweise irgendwann irgendwie (auch ruhig im Internet nach Beispielen suchen) ein Programm gefunden, welches dauerhaften Netzwerkaustausch zuläßt,
dann Schritt für Schritt zu deinem Programm umwandeln, Datenart, Datenmenge, GUI-Steuerung nach und nach aufnehmen,
-> gibt es einen Punkt ab dem wieder Exceptions?


was bedeutet eigentlich das ‘ERSTE FRAME’? sind das verschiedene Clients oder gibt es bei einem Client mehrere? was ist ein Frame hier?
wird vielleicht mehrfach Verbindung geöffnet, nutzen unterschiedliche Programmteile die Verbindung?

na, alles herunterbrechen auf einen 30-Zeilen-Client mit einer Schleife zum Senden, wenn das geht, dann erst kann man irgendwas anderes langsam anfangen

ok, ich werde deine tipps heute abend beherzigen, mal sehn was sich machen lässt.
Was mich wundert ist eben, das es mit localhost normal funktioniert. und nein der
fehler ist eben nicht produzierbar, manchmal gibt es auch einfach nur nen freeze, siehe edit.

mit localhost geht es auch ganz ohne Netzwerk, da muss kein Router, Firewall, Proxy oder weiß was alles komisches beteiligt sein,
das spricht freilich hauptsächlich auf externe Ursachen an, für Java-Code fällt mir spontan auch wenig ein

freeze würde als feststellbare Anomalie im geplanten Ablauf durchaus auch als Fehler reichen

Mich würde die Entstehungsgeschichte deines socketWriters interessieren.

Die Clients flushen die position jeden frame auf den
server socket
Klingt so als würdest du jeden Frame eine neue Verbindung zum ServerSocket aufbauen, was logischerweise nicht gutgeht (zu viele Verbindungen).

öh… ne das ist einfach wie immer: (eigentlich wie immer, denke es wird sonst nicht viel unterschiedlicher gemacht)

...
w.write(string + "
");
w.flush();

erstellst du den Writer nur ein mal und nutzt dann die variable im loop … oder steht das new Writer mit im loop ?

ich hätte hier immer noch den router in verdacht
hairpin-connection und so
lasse das ganze von einem freund von “außen” testen, hairpin belastet die router-cpu extrem

warum TCP und warum String ? alles extrem overhead den man runterbrechen kann, wie siehts aus mit TCP-NoDelay ?

es kann sein das dein router einfach die bremse ist und nicht korrekt arbeitet > WE und neu einrichten
wie siehts sonst mit der netzwerk-config aus ? sicherheitsprogramme ?

es gibt eine vielzahl an fehlerquellen, das es aber direkt mit localhost “sauber” läuft lässt nur auf ein externes problem oder ein timeout schließen

da ich bei Sockets nie den PrintWriter nutze, nur ein Schuß ins Blaue

unter .NET würde der PrintWriter geschlossen werden, wenn er den Sichtbarkeitsbereich verlässt. In dem Moment wird aber auch der Socket geschlossen. Ich kenne aber das Verhalten an der Stelle in Java nicht.

[QUOTE=Unregistered]erstellst du den Writer nur ein mal und nutzt dann die variable im loop … oder steht das new Writer mit im loop ?

ich hätte hier immer noch den router in verdacht
hairpin-connection und so
lasse das ganze von einem freund von “außen” testen, hairpin belastet die router-cpu extrem

warum TCP und warum String ? alles extrem overhead den man runterbrechen kann, wie siehts aus mit TCP-NoDelay ?

es kann sein das dein router einfach die bremse ist und nicht korrekt arbeitet > WE und neu einrichten
wie siehts sonst mit der netzwerk-config aus ? sicherheitsprogramme ?

es gibt eine vielzahl an fehlerquellen, das es aber direkt mit localhost “sauber” läuft lässt nur auf ein externes problem oder ein timeout schließen[/QUOTE]

hm, von aussen klappt es momentan gar nicht, das ist aber grad ein anderes Problem.
Für wie blöd hälst du mich, natürlich erstell ich den writer nur einmal -.- xD
@mogel : Damals beim Chat (mein erstes Netzwerk test Programm) hat es auch mit PrintWriter geklappt… soll ich stattdessen den bufferedwriter verwenden?

keine Ahnung - es war nur ein Hinweis. Ich sende immer direkt bytes über den Socket und konvertiere alles von Hand so wie ich es brauche.

[QUOTE=mymaksimus]
Für wie blöd hälst du mich, natürlich erstell ich den writer nur einmal -.- xD[/QUOTE]
mal abgesehen vom Tonfall läßt der wenige gepostete Code immer noch schlimmstes befürchten,

gibt es mehrere Klasse oder mehrere Objekte einer Klasse die in den Socket schreiben?
den socket könnten diese mehrere Komponenten als Parameter bekommen, die Definition und Verwendung von w legt eine lokale Variable nahe,
ganz so schlimm wird es vielleicht nicht sein, eher Instanzattribut, dennoch bedenklich

reichlich Code/ Beschreibung posten vermeidet manche Zweifel

Das war ein Witz, nicht der Tonfall wie man es sich vorstellen könnte, sry ^^

Du darfst aber auch nicht vergessen, dass man manchmal auch die offensichtlichen Dinge übersieht. Daher einfach nochmal die Nachfrage

Sry das ich euch jz warten lassen habe, ging nicht anders ^^
Nun folgendes, einiger massen minimiertes Programm, zur demonstration meines Problems:


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.JFrame;

public class SpeedNet {
	public SpeedNet(){
		new Server();
		try{
			Thread.sleep(1000);
		}
		catch(Exception e){
			e.printStackTrace();
		}
		new Client();
	}
	public static void main(String[] args) {
		new SpeedNet();
	}
	class Client {
		public Client(){
			try{
				final PrintWriter w = new PrintWriter(new Socket("localhost", 5151).getOutputStream());
				System.out.println("Client: connected.");
				new Thread(new Runnable() {
					public void run() {
						while(true){
							w.write(Math.random() + "
");
							w.flush();
							try{Thread.sleep(2);}catch(Exception e){}
						}
					}
				}).start();
			}
			catch(Exception e){
				e.printStackTrace();
			}
		}
	}
	class Server {
		public Server(){
			JFrame f = new JFrame();
			f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			f.setVisible(true);
			new Thread(new Runnable() {
				public void run() {
					try{
						BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new ServerSocket(5151).accept().getInputStream()));
						System.out.println("Server: Found Client.");
						while(true){
							if(bufferedReader.ready()){
								System.out.println(bufferedReader.readLine());
							}
						}
					}
					catch(Exception e){
						e.printStackTrace();
					}
				}
			}).start();
		}
	}
}

Die Ausgabe ist - wie zu erwarten -

ausgabe
[spoiler]
Client: connected.
Server: Found Client.
0.538116121326988
0.014297818729470335
0.17585083398982726
0.6482846889730394
0.23342650166469303
0.9557572744179165
[SPOILER=und so weiter]
0.9294637041348746
0.22850390632757278
0.15896632620805995
0.3070932014121551
0.15794381311453187
0.8752875106476766
0.11358572460732252
0.3700977770392633
0.9269618586326376
0.5913619939035909
0.1752978448019209
0.8984599911941886
0.2613550129215152
0.2590547442720389
0.18164627241648423
0.21420716281257834
0.8995901385540406
0.22260803238267846
0.03381507107128656
0.5988859504368058
0.22836961805691713
0.9499959758293949
0.8763924123669596
0.30069951123597216
0.7407937115665704
0.9733717733015601
0.8267678743639416
0.3162008951503855
0.6866894731314201
0.9527801759990103
0.20646497463870184
0.8287751915033197
0.06516067435992257
0.7595281872207771
0.16127997261867044

[/spoiler]

[/SPOILER]

Nun, statt localhost in zeile 27 nun meine Ip.
Folgende Ausgabe:

click here to see the awesome
[spoiler]
Client: connected.
Server: Found Client.
0.6202982011847981
[/spoiler]

Also, ich denke jetzt ist klar was ich meine. Höheres sleep geht auch nicht. (1, 2 seks)
Folgendes werde ich jetzt mal versuchen:

  • Angucken ob mein Chat von damals noch funktioniert
  • Eine neue Port Regel im Router einstellen, vllt ist 5151 ja irgendwie kaputt…
  • Gucken ob Wireshark mir irgendwie weiterhilft (Vllt ist das ja ziemlich blöd, aber ich hab das noch nie benutzt und weiß noch gar nicht richtig was das macht :slight_smile: )

*** Edit ***

Nop, der chat funzt auch nicht. ist dan wohl doch der router… teste gleich mal nen anderen port mit neuer regel…
oder ist doch was am programm falsch?

*** Edit ***

Aus Wireshark wurde ich auch nicht wirklcih schlau, ausser, dass, wenn ich es richtig gedeutet habe, die nachricht mehrmals rausgeschickt wird, aber eben nur einmal ankommt…

kannst Du über den Router eine Verbindung aufbauen, dann ist die NAT-Regel richtig - bei weiteren Problemen ist das dann Dein Programm

hä?
wie jetzt? was fürne NAT regel? Ich hab nur diese Port Weiterleitung gemacht… (oder ist das das?)
Und was ist denn am Programm falsch, sodass es, um es nochmal zu wiederholen, über localhost klappt
und über die ip nur die erste gesendete string gelesen wird?

https://www.google.de/search?q=NAT-Regel

Du machst deine Sockets und Streams ja nichtmal zu!?!? Da is klar dass dann alle möglichen sonderbaren Fälle rauskommen, besonders wenn du erst dein Programm mit localhost laufen lässt und dann über die IP -> der Socket ist noch vom vorherigen Durchlauf blockiert. Bitte sieh dir auch an wie man mit Streams umgeht, da gibts zig Tutorials dazu - mit endlosschleife gehts nicht. Guck z.B hier: http://wiki.byte-welt.net/wiki/Daten_einlesen_(Java)

Ok guck ich mir morgen mal an. Danke

Wusste gar nicht das ein fehlendes .close so viel kaputt machen kann…

naja, bei verschiedenen Programmstarts glaube ich kaum daran,
und blockierte Sockets ergeben auch klare Fehlermeldungen,

eher Kategorie allgemeiner Strohhalme-Lösungshoffnungen, schadet aber nix dazu was zu machen