Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
SocketVerschicken von Objecten außerhalb des Routers
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??
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
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.
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)
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.
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.
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...
Kommt denn überhaupt eine Verbindung zustande? Vielleicht blockt ja dein Router schon den Aufbau deiner Verbindung.... Entsprechenden Port freigeben bzw. zu dir forwarden?
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...
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?
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...
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, ...)
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...
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...
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.
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...
[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]
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.
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.
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)
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...