Socket Verschicken von Objecten außerhalb des Routers

M

Mr.Bross

Gast
Hi,

Ich habe ein Object(zweidimensionales int-Array) , das ich über einen ObjectOutputStream zum Clienten schicke (Socket-Verbindung). Jetzt zu meinem Problem:

Wenn ich es innerhalb des Routers, also 192.168.*.*, verschicke, klappt es einwandfrei. Doch wenn ich die externe IP-Adresse nehme (wiesistmeineip.de - wiesistmeineip), dann funktioniert es nicht. Das Object wird zwar verschickt, aber kommt komischerweise nicht an. Der ObjectInputStream bleibt einfach hängen (Habe auch schon 10min gewartet...).
Woran kann das denn liegen??
 
G

Gas

Gast
Router richtig konfiguriert?
So sollte es mit richtiger Konfiguration ablaufen:
Object an externe IP gesendet -> Router schaut im Paket nach Port -> Router schaut ob für den Port eine Weiterleitung eingestellt ist. Wenn ja -> Router leitet Paket an interne IP weiter -> Rechner hat Paket und bekommt Object.

Stichwort für Routerkonfiguration:
Portweiterleitung
 
M

Mr.Bross

Gast
Da niemand mehr etwas schreibt, gebe ich noch ein paar Informationen:

Ich schreibe vom Server aus durch einen PrintWriter einen Code, der dem Client mitteilt, dass er das Object(int-Array) erstellen und verschicken soll. Dieser führt das so lange aus, bis der Server wieder einen Code schickt, der dann den Clienten veranlasst, keine Objecte mehr zu erstellen und zu verschicken.
Intern klappt das alles ja. Doch extern kommt zwar der Code an (Anfangen UND Aufhören), jedoch bleibt er einfach beim verschicken, bzw. der Server beim lesen stecken.
 
M

Mr.Bross

Gast
Habe gerade gemerkt, dass nach paar Minuten diese Exception beim Server geschmissen wird:

Java:
java.io.StreamCorruptedException: invalid type code: FF
	at java.io.ObjectInputStream.readObject0(Unknown Source)
	at java.io.ObjectInputStream.readObject(Unknown Source)
	at de.test.ServerC$5.run(ServerC.java:2419)
	at java.lang.Thread.run(Unknown Source)

Der Client bleibt jedoch weiterhin stehen...
 
M

Mr.Bross

Gast
Hi,

Hatte leider bis jetzt keine Zeit den Code reinzustellen. Habe jetzt jedoch rausgefunden, dass es nicht einmal mit nur einem Objekt geht :-(
Hier der gekürzte Code:

Server:

Java:
PrintWriter writer = output.get(1);

		writer.println("-105");
		writer.flush();

		BufferedReader reader = input.get(1);

		int go = 0;

		try
		{
          while(!reader.ready()) 
          {

          }  
                  

			if (reader.ready())
			{

				System.out.println("in reader.ready()");

				String ss = reader.readLine();

				if (ss.equals("-105"))
				{
                    System.out.println("Nachricht war -105");
					go = 1;
				}

			}

			if (go == 1)
			{

				ObjectInputStream in = oinput.get(1);

				System.out.println("ObjectInputStream: " + in);

				int tfo[][] = (int[][]) in.readObject();

			}
			else
			{
				System.out.println("failed");
			}

		}
		catch (IOException e1)
		{
			e1.printStackTrace();
		}
		catch (ClassNotFoundException e3)
		{
			e3.printStackTrace();
		}
		catch (HeadlessException e5)
		{
			e5.printStackTrace();
		}


Die Nachricht wird erfolgreich geschrieben und es kommt die richtige Antwort zurück. Der ObjectInputStream geht. Denn wenn es damit Probleme geben würde, würde er beim erstellen des ObjectInputStreams stecken bleiben. Das mit dem input und output funktioniert ebenfalls, sonst würde die Antwort nicht ankommen.

Hier der Client:


Java:
if (message.equals("-105"))
		{

			ObjectOutputStream output = ooutputs.get(1);

			PrintWriter writer = output.get(1);

			System.out.println("Nachricht war 105 (Client)");

			writer.println("-105");
			writer.flush();

			int tfo[][] = new int[512][436];

			/*
			 * 
			 * Hier wird tfo der Wert zugewisen, funktioniert auch richtig (Habe es
			 * Debugged)
			 */

			System.out.println("vor verschicken");

			output.writeObject(tfo);
            System.out.println("nach writeObject()");
			output.flush();
            System.out.println("nach flush()");
			output.reset();

			System.out.println("nach reset()");

		}

Ich habe beim Clienten durch die System.out.println()-Anweisungen gemerkt, dass es gar nicht bis zu dem "nach writeObject()" gelangt. Es bleibt einfach bei output.writerObject(tfo) stecken.

Jetzt stellt sich mir die Frage, woran dies liegen könnte und vorallem warum es über die interne IP (192.168.*.*) klappt und über die externe nicht. Wenn es wenigstens bei beiden nicht gehen würde, hätte ich einen Anhaltspunkt, den ich jetzt nicht habe.

PS: output,input, usw sind Hashmaps mit den jeweiligen Streams bzw Writern/Readern.
 

HoaX

Top Contributor
Kann es sein dass du einen Input/OutputStream hast, und auf diesen mit PrintWriter und ObjectOutputStream zugreifst? Das darfst du nicht!
Gleiches Problem sollte aber auch bei lokaler Anwendung geschehen und nix mit dem Router zu tun haben.
 
M

Mr.Bross

Gast
Ja das mache ich, jedoch habe ich es durch ein enum abgesichert, dass nichts passieren sollte. Und wie du bereits gesagt hast, müsste es dann auch innerhalb des Routers Probleme machen...
 

Thief

Bekanntes Mitglied
Kommt denn überhaupt eine Verbindung zustande? Vielleicht blockt ja dein Router schon den Aufbau deiner Verbindung.... Entsprechenden Port freigeben bzw. zu dir forwarden?
 
M

Mr.Bross

Gast
Kann ein Router einfach etwas geschriebenes vom ObjectOutputStream von nem PrintWriter unterscheiden?? Denn mit dem PrintWriter funktioniert alles auch über die Externe.

Ich habe es gerade mit zwei ganz einfachen kurzen Klassen probiert, und es läuft wie immer bis zum empfangen.


Server

Java:
import java.awt.HeadlessException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class InputTest {

	public static void main(String args[])
	{

		new InputTest().los();

	}

	public void los()
	{
		try
		{

			ServerSocket sock = new ServerSocket(5005);
			Socket socket = sock.accept();

			System.out.println("ObjectInputStream: vor erstellen");

			ObjectInputStream in = new ObjectInputStream(socket
					.getInputStream());

			System.out.println("ObjectInputStream: nach erstellen");

			System.out.println("ObjectInputStream: " + in);

			Integer[][] tfo = (Integer[][]) in.readObject();

			System.out.println("ObjectInputStream:  fertig");

		}
		catch (IOException e1)
		{
			e1.printStackTrace();
		}
		catch (ClassNotFoundException e3)
		{
			e3.printStackTrace();
		}
		catch (HeadlessException e5)
		{
			e5.printStackTrace();
		}

	}

}



Client:

Java:
import java.io.ObjectOutputStream;
import java.net.Socket;

public class OutputTest {

	public static void main(String args[])
	{

		new OutputTest().los();

	}

	public void los()
	{
		try
		{
			Socket socket = new Socket("**.**.**.***", 5005);

			ObjectOutputStream output = new ObjectOutputStream(socket
					.getOutputStream());

			Thread.sleep(5000);

			Integer tfo[][] = new Integer[50][50];

			tfo[0][1] = 5;

			System.out.println("vor verschicken");

			output.writeObject(tfo);
			System.out.println("nach writeObject()");
			output.flush();
			System.out.println("nach flush()");
			output.reset();

			System.out.println("nach reset()");

			Thread.sleep(20000);

			System.out.println("end");

		}
		catch (Exception ex)
		{
			ex.printStackTrace();
		}

	}
}

Komischerweise wird alles verschickt (bis nach reset), bevor beim Server "ObjectInputStream: nach erstellen" erscheint. Dann kommt diese Meldung und er bleibt dann bei in.readObject() stecken.



PS: Falls jemand Zeit hat, kann er es ja bitte mal testen. Dann weiß ich ob es an meinem Router/Rechner o.ä. liegt oder ob es an Java liegt oder an meinem Code. Sleep Befehle kann man auch wegmachen, waren nur zum testen da...
 

HoaX

Top Contributor
Bitte wie willst du das über ein Enum sichern? Das kann nur schief gehen. Die Auswirkungen merkst du ja scheinbar gerade.

Dem Router ist es völlig egal was da für Daten drüber gehen. Nimm entweder nur ObjectStreams oder nur Reader/Writer. Du kannst ja auch Strings einfach über den ObjectOutputStream schicken, wozu noch Reader/Writer?
 
M

Mr.Bross

Gast
Ich bin mir ziehmlich sicher, dass es gut geht mit dem enum. Außerdem wieso sollte es innerhalb des Routers dann gehen?
 
M

Mr.Bross

Gast
Ich habe jetzt mal ein bisschen gewartet und nach 15min kommt das int[][]-Array an. Es ist etwa 1600*1100 groß, mit kleinen Weten gefüllt. (bis 300) Wieso dauert es so lange?? Innerhalb des Routers dauert es nur 3 sekunden...
 

FArt

Top Contributor
Ich habe jetzt mal ein bisschen gewartet und nach 15min kommt das int[][]-Array an. Es ist etwa 1600*1100 groß, mit kleinen Weten gefüllt. (bis 300) Wieso dauert es so lange?? Innerhalb des Routers dauert es nur 3 sekunden...

Die "kleinen" Werte sind irrelevant... ein int ist ein int...

Wieso dauert es so lange? Das kann nur jemand beantworten, der deine Infrastruktur kennt und vielleicht mal ein paar Messungen vornimmt (Bandbreite, Auslastung, Antwortzeiten, Latenzen, Leitungsfehler, ...)
 
G

Gas

Gast
Ich habe jetzt mal ein bisschen gewartet und nach 15min kommt das int[][]-Array an. Es ist etwa 1600*1100 groß, mit kleinen Weten gefüllt. (bis 300) Wieso dauert es so lange?? Innerhalb des Routers dauert es nur 3 sekunden...

Sind immerhin fast 7mb. Und das muss erst mal über den upload hoch und mit dem download wieder runter geladen werden.
 
M

Mr.Bross

Gast
Also ich habe einen upload von 2 Mb/s und einen download von 34000 Mbit/s. Gibt es nun eine Möglichkeit dies zu verschnellern?? Es bringt ja bestimmt nichts ein byte zu nehmen statt einem int...
 

FArt

Top Contributor
Also ich habe einen upload von 2 Mb/s und einen download von 34000 Mbit/s. Gibt es nun eine Möglichkeit dies zu verschnellern?? Es bringt ja bestimmt nichts ein byte zu nehmen statt einem int...

kleine Rechenaufgabe: Berechne für die oben aufgeführten Werte die theoretische Zeit, die Download bzw. Upload benötigen. Gleiche das Ergebnis mit den empirisch ermittelten Messwerten und deiner Frage ab.
 
M

Mr.Bross

Gast
Mit 2MB/s Upload braucht es bei 7MB etwa 3,5 Sekunden. Dann müssen wir das wieder runterladen mit 34 MBit/s (also 4,25MB/s). Dies würde etwa 1.6 Sekunden brauchen. Oder habe ich mich da von Grund auf verrechnet?? Müssten ja eigentlich dann etwa 6 Sekunden benötigen, und nicht 600...
 
T

tuxedo

Gast
Ich bin mir ziehmlich sicher, dass es gut geht mit dem enum.



*ymmd*

[offtopic]
Das erinnert mich stark an unsere indischen Kollegen in der Firma: "Ich hab alles richtig gemacht und programmiert. Da muss der Compiler [wohl gemerkt der Java Compiler] dran schuld sein. Der macht wohl nicht das was ich will"
[/offtopic]
 
M

Mr.Bross

Gast
Wie sich herausgestellt hat geht es auch mit dem enum. Die größe, bzw. die Schnelligkeit ist das Problem!!!
 

FArt

Top Contributor
Wie sich herausgestellt hat geht es auch mit dem enum. Die größe, bzw. die Schnelligkeit ist das Problem!!!
Du hast ja selbst schon festgestellt, dass die Größe selber nicht das Problem sein kann. Jetzt ist es also an der Zeit meinen Tipp von vorhin zu beherzigen: schau dir die Leitung an. Das bedeutet also nicht, dass du dich auf die Suche begibst um das WLAN-Kabel zu finden, sondern dass du dir mal mit Netzwerktools die Werte der verschiedenen Bereiche (LAN, Internet, ...) ansiehst und bewertest.
 

HoaX

Top Contributor
Ob lokal oder über Internet sollte für das Programm doch keinen Unterschied machen, und wenn da einmal eine Exception fliegt dass der StreamHeader kaputt ist, dann ist das für mich Beweis genug um zu sagen der Enum funktioniert nicht.
 
M

Mr.Bross

Gast
Ich habe ein paar Sachen geändert und dann kam diese Exception nicht mehr. Nun sind wir bei diesem Problem...

@FArt Kannst du mir so ein Netzwerktool empfehlen??
 
M

Mr.Bross

Gast
Zählt auch ein normaler Download?? Da habe ich gerade mit 5,1 MB/s (höchste) geladen. Durchschnitt war etwa 4,5 (immer so zwischen 4 und5 hinundher-geschwankt)
 
G

Gas

Gast
Mit 2MB/s Upload braucht es bei 7MB etwa 3,5 Sekunden. Dann müssen wir das wieder runterladen mit 34 MBit/s (also 4,25MB/s). Dies würde etwa 1.6 Sekunden brauchen. Oder habe ich mich da von Grund auf verrechnet?? Müssten ja eigentlich dann etwa 6 Sekunden benötigen, und nicht 600...

Verwechselst du da mal nicht Bit mit Byte beim Upload?
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
N Java socket Programmierung Filme verschicken Netzwerkprogrammierung 20
B Socket Bilder verschicken via Sockets. Heap-Problem. Netzwerkprogrammierung 2
B SocketChannel ByteBuffer Bilder verschicken Netzwerkprogrammierung 17
x46 Socket Files per Socket verschicken Netzwerkprogrammierung 1
D Socket Class über Netzwerk verschicken Netzwerkprogrammierung 2
S Socket Über UDP Objekte verschicken Netzwerkprogrammierung 9
D Socket Datei nur stückweise über Socket verschicken Netzwerkprogrammierung 6
F Fragen zu Netzwerkspiel, ArrayList verschicken Netzwerkprogrammierung 5
I Socket HTTP Nachrichten über Sockets verschicken Netzwerkprogrammierung 2
G Objekte per TCP verschicken + Thread Netzwerkprogrammierung 4
G Verschlüsselte Strings über Netzwerk verschicken Netzwerkprogrammierung 19
G TCP Verbindung überprüfen OHNE daten zu verschicken Netzwerkprogrammierung 11
P Massen emails verschicken an Kunden die in Datenbank sind Netzwerkprogrammierung 4
T Daten über GSM verschicken Netzwerkprogrammierung 4
S Knuddels Chat System: Bot / Nachrichten verschicken? Netzwerkprogrammierung 6
O email verschicken Netzwerkprogrammierung 8
8 ByteArray per Netzwerk verschicken Netzwerkprogrammierung 6
B Eigenes Protokoll über Sockets verschicken Netzwerkprogrammierung 4
P Serialialiserte Objekte übers Netzwerk verschicken Netzwerkprogrammierung 9
D .jpg, .wav per ServerClient Verbindungen verschicken Netzwerkprogrammierung 8
D Daten per Server- Client nur als byte verschicken? Netzwerkprogrammierung 3
A FileSend - Dateien verschicken Netzwerkprogrammierung 19
B Nachrichten über das Netzwerk verschicken Netzwerkprogrammierung 3

Ähnliche Java Themen


Oben