String von Client zu Server kommt nicht an

Jw456

Top Contributor
Das Problem passt nicht ganz zu dem Code. Das Problem kommt daher, dass der Server derzeit noch auf eine Textzeile vom Client wartet. Dieser Request läuft dann irgendwann in einen Timeout.

Der Client selbst öffnen einen ObjectInputStream und will bei der Initialisierung ein paar erste Bytes lesen. Diese kommen aber leider nicht (da der Server ja selbst noch wartet).

Das ist aber nicht das Verhalten des Codes, den Du gepostet hast :)

Generell ist es so, dass man sich auf eine "Kommunikationsart" festlegen sollte. Also entweder mann schickt nur Text oder man nutzt Object Streams oder man macht irgend was eigenes ...

Dann öffne ich gerne die Streams direkt, damit diese dann verwendbar sind. Da di Kommunikation blockierend ist, bekommt jeder Socket einen eigenen Thread. Wenn etwas kommt (beim Server), dann wird darauf reagiert.

Das habe ich mal kurz skizziert in folgendem Code. Das ist natürlich nicht komplett, denn der Server sollte alle seine Clients kennen und so. Aber das ignorieren wir mal einfach. Und da Du komplexe Dinge gerne per Object Stream versendest, basiert alles auf ObjectStream (Ein String ist ja auch ein Objekt - kann also versendet werden!)

Eine Nachricht, die empfangen wird auf Server Seite ist dann eine ReceivedMessage und bekommt - ähnlich wie man das von Events in Swing und Co kennt, auch den Sender mit:
Java:
package mypackage.server;

public class ReceivedMessage {
    private ClientSocketHandler handler;
    private Object message;

    public ClientSocketHandler getHandler() {
        return handler;
    }

    public Object getMessage() {
        return message;
    }

    public ReceivedMessage() {
    }

    public ReceivedMessage(ClientSocketHandler handler, Object message) {
        this.handler = handler;
        this.message = message;
    }
}

Einen Client Socket will gehandhabt werden. Das ist dann einfach mal folgende Klasse geworden:
Java:
package mypackage.server;

import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.function.Consumer;

public class ClientSocketHandler {

    private final Socket clientSocket;
    private final ObjectInputStream in;
    private final ObjectOutputStream out;

    private Consumer<ReceivedMessage> objectHandler;

    private volatile boolean running;

    public ClientSocketHandler(final Socket clientSocket) throws IOException {
        this.clientSocket = clientSocket;
        in = new ObjectInputStream(clientSocket.getInputStream());
        out = new ObjectOutputStream(clientSocket.getOutputStream());
        running = true;
    }

    public void start() {
        new Thread(this::receiveMessages).start();
    }

    public void sendMessage(Object obj) throws IOException {
        out.writeObject(obj);
    }

    public void receiveMessages() {
        while (running) {
            try {
                Object obj = in.readObject();
                if (objectHandler != null) objectHandler.accept(new ReceivedMessage(this, obj));
            } catch (EOFException eofe) {
              System.out.println("Connection closed ...");
              running = false;
            } catch (IOException ioe) {
                ioe.printStackTrace();
                System.out.println("Could not read from socket, closing!");
                running = false;
            } catch (ClassNotFoundException cnfe) {
                System.out.println("Message discarded, class not found: " + cnfe.getMessage());
            }
        }
        safeClose(in);
        safeClose(out);
        safeClose(clientSocket);
    }

    private void safeClose(AutoCloseable closeable) {
        if (closeable == null) return;
        try {
            closeable.close();
        } catch (Exception ex) {}
    }

    public void setObjectHandler(Consumer<ReceivedMessage> objectHandler) {
        this.objectHandler = objectHandler;
    }
}

Ist schnell umschrieben: Bekommt einen Socket, öffnet darauf die Object Streams. Man kann eine Routine hinterlegen, die Nachrichten dann verarbeitet. Und man kann das natürlich noch starten.

Ein einfacher Server sieht dann so aus:
Java:
package mypackage.server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    private final int port;
    private boolean running;
    private ServerSocket serverSocket;

    public Server (final int port) {
        this.port = port;
    }

    public void open() {
        if (running) return;

        new Thread(this::acceptNewConnections).start();
    }

    private void handleMessage(ReceivedMessage msg) {
        System.out.println(msg.getMessage());
        try {
            msg.getHandler().sendMessage("Empfangen: " + msg.getMessage());
        } catch (IOException ex) {
            System.out.println("Unable to send message back!");
            ex.printStackTrace();
        }
    }

    private void acceptNewConnections() {
        try {
            serverSocket = new ServerSocket(port);
            System.out.println("Waiting on Port " + port);
            running = true;
        } catch (IOException ex) {
            System.out.println("Unable to open port!");
            ex.printStackTrace();
        }

        while (running) {
            try {
                Socket client = serverSocket.accept();
                System.out.println("Client connected ...");
                ClientSocketHandler handler = new ClientSocketHandler(client);
                handler.setObjectHandler(this::handleMessage);
                handler.start();
                // die einzelnen Handler werden in der Regel auch noch verwaltet!
            } catch (IOException ex) {
                System.out.println("Exception when accepting a new Client.");
                ex.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        Server server = new Server(4243);
        server.open();
    }
}
Also in erster Linie ein Thread, der auf neue Clients wartet, die Verbindungen annimmt und dann entsprechende Handler erstellt.
Der ObjectHandler (fällt mir gerade auf, dass das blöd ist. Sollte besser NewMessageHandler heissen) ist hier einfach minimal aufgebaut. Die nachricht wird ausgegeben und ein String zurück gesendet.

Mal einfach eine angepasste Klasse, die mit dem Server umgehen kann:
Java:
package mypackage.client;

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

public class ClientDB {

    private InetSocketAddress address;
    ObjectOutputStream out;

    public void los()
    {
        try
        {
            address = new InetSocketAddress("127.0.0.1",4243);
            Socket s = new Socket();
            s.connect(address, 1000); // Verbinde Dich mit dem Server, maximale Wartezeit: 3 Sekunden
            out = new ObjectOutputStream(s.getOutputStream());
            out.writeObject("select * from leute"); // SQL-Befehl an Server absenden
            out.flush();

            // Empfangen werden vom Server aber binäre Rohdaten, also wird ObjectInputStream benötigt:

            ObjectInputStream ois = new ObjectInputStream(s.getInputStream());

            // Ausgabe der ArrayList mit dem ResultSet der Datenbank in einem String
            // nachdem die Rohdaten zunächst wieder in eine ArrayList von Typ String
            // zurückverwandelt wurden

            System.out.println("Ausgabe der Daten:");
            Object msg = ois.readObject();
            System.out.println(msg);


//          ois.close();
//          s.close();
//          writer.close();
        }

        catch(IOException ex) {ex.printStackTrace();}
        catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // Client starten:

        ClientDB client1 = new ClientDB();
        client1.los();
    }
}

Am Client habe ich kaum was gemacht - da könnte man dann noch einiges optimieren.

Was man da z.B. machen könnte:
- Man erstellt einfach Nachrichten Klassen. Also von mir aus sowas wie eine SQLQuery Klasse.
- Der NewMessageHandler prüft dann: Ist die msg vom Typ SQLQuery? -> SQL Query ausführen.

So kann man dann viele Nachrichten-Klassen bauen, die dann behandelt werden.

Man könnte dazu sogar etwas bauen wie eine Map, die als Key den Klassennamen hat und als Value dann ein Consumer<> oder so.

Also ganz klar: Das war nur ein Anfang und man kann einiges mehr ausbauen!
alles richtig.
Du erklärst aber nicht warum es lokal geht aber mit öffentlicher IP nicht.


Ich habe seinen Code mal mit öffentlicher und lokaler IP getestet ging beides.
Server und Client auf derselben Maschine, nur der Server blendet sich nach einer Verbindung.
 

Turing0001

Aktives Mitglied
Hallo Kneitzel,

danke für Deine Mühe, ich werde es mal in Ruhe anschauen. Gerne hätte ich aber gewusst, warum mein Code nicht läuft. Vielleicht hier noch mal zum Vergleich mein Chatclient und mein Chatserver, welche nun via WAN-IP auch nicht mehr funktionierern, obwohl das Ganze mit mehreren Clients vor einigen Monaten beim Test einwandfrei mit einigen Bekannten funktionierte. Vielleicht hast Du die Tage ja mal Zeit es Dir anzuschauen. Hat den Vorteil dass Du den Code 1.1 übernehmen und direkt bei Dir testen kanst und ich wüsste, warum dieser Code plötzlich nicht mehr funktioniert:

Hier der Client:

Java:
import java.io.*;
import java.net.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
 
 
public class EinfacherChatClientA {
     JTextArea eingehend;
    JTextField ausgehend;
    BufferedReader reader;
    PrintWriter writer;
    Socket sock;
 
public static void main(String[] args) {
    EinfacherChatClientA client = new EinfacherChatClientA();
    client.los(); // Chatclient starten
}
 
public void los() {
    JFrame frame = new JFrame ("Lächerlich einfacher Chat-Client");
    JPanel hauptPanel = new JPanel () ;
    eingehend = new JTextArea(15,20);
    eingehend.setLineWrap(true);
    eingehend.setWrapStyleWord(true);
    eingehend.setEditable(false);
    JScrollPane fScroller = new JScrollPane(eingehend);
    fScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
    fScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
    ausgehend = new JTextField(20);
    JButton sendenButton = new JButton ("Senden");
    sendenButton.addActionListener(new SendenButtonListener());
    hauptPanel.add(fScroller);
    hauptPanel.add(ausgehend);
    hauptPanel.add(sendenButton);
   
    netzwerkEinrichten(); // Verbindung zum Server herstellen
   
    Thread readerThread = new Thread(new EingehendReader()); // Thread erzeugen für dauerhafte Kommunikation mit Server
    readerThread.start();
   
    frame.getContentPane().add(BorderLayout.CENTER, hauptPanel);
    frame.setSize(400,500);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
 
private void netzwerkEinrichten() {
    try {
            sock = new Socket("192.180.2.101", 4243); // Verbindung zum Server auf Port 4243
            InputStreamReader streamReader = new InputStreamReader(sock.getInputStream()); // Eingabestrom vom Server holen (Input-Leitung)
            reader = new BufferedReader(streamReader);
            writer = new PrintWriter(sock.getOutputStream()); // Ausgabestrom zum Server holen (Output-Leitung)
            System.out.println("Netzwerkverbindung steht. Port des Servers:  " + sock.getPort() + " Serveradresse: " + sock.getInetAddress());
           
    } catch (IOException ex) {
      ex.printStackTrace();
    }
}
private class SendenButtonListener implements ActionListener {  // Text der verschickt werden soll lesen und absenden
    public void actionPerformed(ActionEvent ev) {
    try{
            writer.println(ausgehend.getText());
            writer.flush(); // Writer/Tastaturpuffer leeren.
 
        } catch(Exception ex) {
          ex.printStackTrace();
        }
        ausgehend.setText(""); // Eingabefeld löschen
        ausgehend.requestFocus();
        }
    }
   
    class EingehendReader implements Runnable // Permanent hören, ob eine Nachricht vom Server kommt
    {
        public void run()
        {
            String nachricht;
            try
            {
                while((nachricht=reader.readLine()) != null) // Liest vom Server bis null (=Ende der Nachricht) zurückgegeben wird
                {
                    System.out.println("Gelesen: " + nachricht); // Nachricht in TextArea anzeigen
                    eingehend.append(nachricht + "\n");
                }
               
            }
            catch(Exception ex){ex.printStackTrace();}
        }
   
    }
}


Hier nun noch der Server:


Java:
import java.io.*;
import java.net.*;
import java.util.*;
 
public class SehrEinfacherChatServer {
 
    ArrayList clientAusgabeStröme;
 //--------------------------------------------------------------------------------------
 
    public class ClientHandler implements Runnable { // Permanent auf neuen Client warten, also Thread benötigt
        BufferedReader reader;
        Socket sock;
       
        public ClientHandler (Socket clientSocket) { // Eingabestrom vom Client holen
            try {
                sock = clientSocket;
                InputStreamReader isReader = new InputStreamReader (sock.getInputStream());
                reader = new BufferedReader(isReader);
                PrintWriter writer = new PrintWriter(sock.getOutputStream());
                clientAusgabeStröme.add(writer); // Writerobjekt in ArrayList speichern, damit jederzeit Nachricht an Client gesendet werden kann

           
            } catch(Exception ex) {ex.printStackTrace();}
        } // Konstruktor schließen
       
        public void run() { // permanent auf Nachricht von einem Client warten
            String nachricht;
            try {
                while ((nachricht = reader.readLine()) !=null) {
                    System.out.println("gelesen: " + nachricht);
                    esAllenWeitersagen(nachricht); // Eingehende Nachricht eines Clients an alle anderen Clients weiterleiten
                } // Ende der while-Schleife
            } catch(Exception ex) {ex.printStackTrace();System.out.println("Fehler beim Lesen vom Client!");}
        } // run schließen
    } // innere Klasse schließen
   
    //-------------------------------------------------------------------------------------
   
    public static void main (String[] args) {
        new SehrEinfacherChatServer().los(); // Serverprogramm starten
    }
    // los() erzeugt ein Serversocket und wartet permanent auf Anfrage eines neuen Client
   
    public void los() {
        clientAusgabeStröme = new ArrayList();
       
        try {
            ServerSocket serverSock = new ServerSocket(4243);
            System.out.println("Hier ist der Chat-Server auf Port 4243!");
           
            while(true) { // Auf Anfrage von neuem Client warten...
                Socket clientSocket = serverSock.accept();//Erzeuge neuen Socket für Client der gerade angefragt hat
                InetAddress ip=clientSocket.getInetAddress();
                String adr=ip.getHostName();//oder getHostAddress()
                int portnr = clientSocket.getPort();//bzw. getLocalPort auf Serverseite
                System.out.println("Hostname und Port des Clients: " + adr + " " + portnr);
                //PrintWriter writer = new PrintWriter(clientSocket.getOutputStream());
                //clientAusgabeStröme.add(writer);
                Thread t = new Thread(new ClientHandler(clientSocket)); // Neuen Thread erzeugen für permanente Kommunikation mit diesem Client...
                t.start(); //...und diesen Thread starten
                System.out.println("Habe eine Verbindung");
            }
            // wenn wir hier angelangt sind, haben wir eine Verbindung
       
        }catch(Exception ex) {
         ex.printStackTrace();
        }
    }
   
    //--------------------------------------------------------
    // Eingegangene Nachricht eines Clients an alle anderen Clients weiterleiten.
    // Dazu alle Writer-Objekte in der ArrayList durchlaufen und für jedes die write() Funktion aufrufen:
   
    public void esAllenWeitersagen(String nachricht) {
       
        Iterator<PrintWriter> it = clientAusgabeStröme.iterator(); // Durchlauf mit einem Iterator ( ähnlichz zu for-each-Schleife)
        while(it.hasNext()) {
            try {
                PrintWriter writer = (PrintWriter) it.next();
                writer.println(nachricht);
                writer.flush();
            } catch(Exception ex) {
              ex.printStackTrace();
            }
        } // Ende der while-Schleife
    } // esAllenWeitersagen schließen
} // Klasse schließen

LG
 
K

kneitzel

Gast
Gerne hätte ich aber gewusst, warum mein Code nicht läuft.

Du erklärst aber nicht warum es lokal geht aber mit öffentlicher IP nicht.

Ich habe meine Vermutung diesbezüglich doch geäußert:
Das Problem passt nicht ganz zu dem Code.

Meine Vermutung ist, dass Du bei der Anpassung ggf. noch etwas mehr angepasst hast. Schickt der Client denn immer noch die Nachricht? Sprich: Bist Du wirklich sicher, dass bei den Tests von Dir dieser Code noch vorhanden war:
Java:
          writer = new PrintWriter(s.getOutputStream());
          writer.println("select * from leute"); // SQL-Befehl an Server absenden
          try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
          writer.flush();

Die folgende Aussage passt diesbezüglich ja auch:
Aber mit den oben erwähnten Testprogrammen funktioniert es ja, zumindest solange die Kommunikation (Senden von Daten) nur von Server zu Client läuft. Sowie die Kommunikation bidirektional wird, gibt es die erwähnten Probleme.
==> Irgendwas ging und mit einer Anpassung kommt es dann zu den Problemen.

Wie gesagt: Viele Informationen, die im Thread gegeben wurden, passen nicht zusammen. Zusammen mit irgendwelchen wilden Vermutungen rund um TCP/IP ist es sehr schwer, ein genaues Bild zu bekommen - zumal ja während der Diskussion der Code bestimmt nicht unverändert bleibt :)
 

Jw456

Top Contributor
Java:
public class ServerDB {

    Connection conn;//Schnittstelle um Verbindung zur DB herzustellen
    Statement stmt;
    ResultSet rSet;
    BufferedReader reader;


    public void los()
    {
        try
        {
            ServerSocket servsock = new ServerSocket(4243); // Verbindungsschnittstelle auf Port 4243 erstellen
            while(true)
            {
                System.out.println("Hallo hier ist der Server!");
                Socket sock = servsock.accept(); // Warten auf "Anruf" von einem Client. accept() blockiert bis ein Client "anruft"

                // Empfange einen String (= SQL Befehl) vom Client:

                InputStreamReader isReader = new InputStreamReader (sock.getInputStream());
                reader = new BufferedReader(isReader);
                String nachricht = null;
                System.out.println("Bin hier");



                nachricht = reader.readLine(); // Lesen des SQL Befehls

                System.out.println("Empfangene Nachricht: " + nachricht);
                //JOptionPane.showMessageDialog(null, "Nachricht: " + nachricht);
                System.out.println("Empfangene Nachricht nochmal: " + nachricht);
                // Ab hier wieder wie gehabt Verbindung zur Datenbank:

               /* DriverManager.setLogWriter(new PrintWriter(System.out));
                Class.forName("org.sqlite.JDBC");
                System.out.println("Treiber geladen");
                String url = "jdbc:sqlite::resource:"+ "MyDB.db";
                conn = DriverManager.getConnection(url,"",""); // Verbindungsobjekt erstellen
                System.out.println("Verbindung steht" );
                stmt = conn.createStatement();
                rSet = stmt.executeQuery(nachricht); // Schicke den SQL-Befehl an die Datenbank und nimm das Ergebnis entgegen
                ResultSetMetaData md = rSet.getMetaData(); // Ermittele Meta-Daten des ResultSets
                int columns = md.getColumnCount();
                System.out.println("Anzahl der Spalten: " + columns + " \n");*/

                ArrayList <String> tabledat = new ArrayList<String>();
                tabledat.add("Hallo1 /n");
                tabledat.add("hallo2 /n");

                /*while(rSet.next()) { // Solange noch Ergebnisdatensätze da sind...

                    for(int i=1; i<=columns; ++i) {
                        // Durchlaufe alle Spalten der aktuellen Zeile des ResultSets
                        tabledat.add(rSet.getString(i)); // Aktuellen Eintrag des ResultSets in ArrayList speichern

                    }
                }*/





                // Ergebnis der Datenbankabfrage wir wieder als binärer Datenstrom zum
                // Client zurückgeschickt

                OutputStream os = sock.getOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(os);

                oos.writeObject(tabledat);
                oos.flush();

                oos.close();
               // servsock.close();
            }

        }

        catch (IOException ex)
        {
            ex.printStackTrace();
            System.out.println("Fehler : " + ex);

        }

        finally {
            CloseDB(stmt,conn); // Datenbankverbindung schließen
        }



    }

    public void CloseDB(Statement stmt, Connection conn )
    {
        try {
            stmt.close();
            conn.close();
        } catch(Exception e) {
            //
        }
    }
    public static void main(String[] args) {
        // Starte den Server:

        ServerDB serv = new ServerDB();
        serv.los();
    }
}
 

Jw456

Top Contributor
Habe es gerade nochmal mit einem anderen Programm getestet. Solange ich nur Daten von Server anfordere funktioniert es. Wenn ich aber Daten vom Client an den Server sende und auf Rückantwort warte, gibt es plötzlich Probleme, die es vorher nicht gab. Ich poste mal nochmal den vollständigen Code von meinem Client und dem Server. Ich bitte das Chaos schon im Voraus zu entschuldigen
verstehe ich das richtig du hast hier in diesem fall Server und Client auf der gleichen Maschine laufen.
 

Turing0001

Aktives Mitglied
Hallo JW456,

immer noch das gleiche Problem. Nein, Client und Server liegen auf verschiedenen Rechnern. Für den Rechner mit dem Server ist die Portweiterleitung eingerichtet.
 

Turing0001

Aktives Mitglied
Hier auch nochmal ein Client/Server-Programm, mit welchem das Ganze funktioniert. Client liegt wieder auf Rechner 1, Server auf Rechner 2 mit der Portweiterleitung. Im Client kann also sowohl die lokale IP-Adresse von Rechner 2 eingetragen werden, als auch die WAN-IP und es funzt.

Client:

Java:
import java.io.*;
import java.net.*;

public class client {
    
    private InetSocketAddress address;
    
    public void los()
    {
        
        try
        {
        
          address = new InetSocketAddress("192.168.2.101",4243);
          Socket s = new Socket();
          s.connect(address, 3000); // Verbinde Dich mit dem Server, maximale Wartezeit: 3 Sekunden
          // Socket s = new Socket("192.168.2.101",4243); //Socketverbindung zum Hostost erzeugen
          InputStreamReader lies = new InputStreamReader(s.getInputStream()); // Lies die Daten vom Serversocket
          BufferedReader reader = new BufferedReader(lies);
          //Daten mit einem Reader lesen wie bei Dateien:
          
          String text = reader.readLine();
          System.out.println("Tipp des Tages: " + text);
          reader.close();
          s.close();
        }
          
       catch(IOException ex) {ex.printStackTrace();}
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // Client starten:
        
        client client1 = new client();
        client1.los();
    }
}


Hier noch der Server:

Java:
import java.io.*;
import java.net.*;

public class server {
    
    String[] tippListe={"Weniger Chips und Schokolade essen!","Kaufen Sie sich was schönes!","Sagen Sie heute die Wahrheit","Mehr Programmieren Üben!","Knuddeln Sie Ihren Partner!"};
    public void los()
    {
        try
        {
            ServerSocket servsock = new ServerSocket(4243); // Verbindungsschnittstelle auf Port 4243 erstellen
            while(true)
            {
               System.out.println("Hallo hier ist der Server!");
               Socket sock = servsock.accept(); // Warten auf "Anruf" von einem Client. accept() blockiert bis ein Client "anruft"
               PrintWriter writer = new PrintWriter(sock.getOutputStream()); // Ausgabedatenleitung zum Clientsocket aufbauen...
               String tipp = getTipp();
               writer.println(tipp); // ... und die Daten an den Client senden
               System.out.println("Clientadresse: " + sock.getInetAddress() + "  Portnummer: "+ sock.getPort() + " " + "Lokaler Port: " + sock.getLocalPort());
               writer.close(); // Ausgabedatenleitung wieder schließen
               //servsock.close();
               System.out.println(tipp);
            }
            
        }
        catch (IOException ex){ex.printStackTrace();}
    }
    
    private String getTipp()
    {
        int zufall = (int)(Math.random()*tippListe.length);
        return tippListe[zufall];
    }

    
    public static void main(String[] args) {
        // Starte den Server:
        
        server serv = new server();
        serv.los();
    }
}


Ich verstehe langsam die (Java)Welt nicht mehr.
 
K

kneitzel

Gast
Du bist also wirklich 100% sicher, dass der Code, den du für den Client gezeigt hast, wirklich genau so ist? Du also garantiert an den Server mit einem PrintWriter und println mit anschließendem flush etwas an den Server gesendet hast?

Was sind das für zwei Systeme (Betriebssystem)? Welche Java Version nutzt du jeweils? Wie genau startest Du Server und Client? Und da Du das Default Encoding nutzt: führ mal das folgende Programm auf beiden Systemen aus:
Java:
import java.nio.charset.Charset;

public class PrintDefaultCharset {
    public static void main(String[] args) {
        System.out.println(Charset.defaultCharset());
    }
}
 
K

kneitzel

Gast
Eine Frage drängt sich mir noch auf - unabhängig von dem Problem:

Sollen das nur einfache Spiel-Projekte sein? Was will Du dabei lernen oder vertiefen?

Generell ist das, was Du da derzeit machst, nicht wirklich etwas, das man noch machen würde.
a) In der Regel verwendet man "höhere" Protokolle, also Protokolle, die auf dem, was Du da machst, aufsetzen und extrem viel bieten. So ist z.B. das HTTP Protokoll sehr verbreitet. Und da könnte man viele Dinge, die Du da machst, direkt als WebService schreiben. Und wenn ich da so ein select sehe: REST bietet sich da an - da wäre dann ein "select * from user" einfach ein Request, alle User aufzulisten.

b) Wenn man ein eigenes Protokoll haben möchte, dann macht es Sinn, auf eine Lib zuzugreifen, die einem schon sehr viel bietet. https://netty.io/ wäre da z.B. eine Library mit der man da schnell und einfach etwas aufbauen kann.

Ansonsten kann man das aber natürlich auch weiter vertiefen - eine Möglichkeit, da alles in mehrere Klassen zu unterteilen, hast Du ja jetzt, aber gerad wenn es um Ports nach außen geht, dann kommt da einiges mit ins Spiel - vor allem Security:
- Zum einen will man alles verschlüsseln, also SSL / TLS kommen da ins Spiel.
- Zum Anderen dann noch eine Autorisierung - das ist eher einfach.
 

Turing0001

Aktives Mitglied
Hallo Kneitzel,

bei beiden die Ausgabe windows-1252
Hast Du den Chatclient/Chatserver schon mal testen können? Und Du hast recht, den DBServer hatte ich nochmals verändert. Soll ich den Code für Client und Server nochmals einstellen? Ich möchte unbedingt wissen, warum meine Version nicht funktioniert, auch wenn die Codequalität natürlich sehr zu wünschen übrig lässt und Du mit Deiner Kritik recht hast. Vor allem die Sache mitdem Chatprogramm will mir nicht inden Kopf. Es hat sich lediglich dei WAN-IP geändert, der Code ist genauso wie vorher, auch die Einstellung der statischen Portweiterleitung im Router ist unverändert.
 

Turing0001

Aktives Mitglied
Hallo Kneitzel,

momentan ist mein Ziel, wieder in die Java-Programmierung reinzukommen, nach langer Absesenheit. Spieleprogrammierung ist ein Ziel, korrekt, aber erst einmal die Basics auffrischen und vertiefen. Teilweise weiss ich aber nicht recht, wo ich da anfangen soll, es gibt so viele Baustellen und meine Zeit ist begrenzt.
 

Turing0001

Aktives Mitglied
Hallo JW456,

nein, das ist nicht die Ursache. In einer zweiten Version habe ich dei ArrayList parametrisiert, das macht aber keinen Unterschied. Und wie gesagt, im lokalen Netz mit 3 Rechnern läuft das Ganze ja einwandfrei und bis vor einiger Zeit auch mit meiner WAN-IP, nun plötzlich nicht mehr.
 
K

kneitzel

Gast
Hallo Kneitzel,

bei beiden die Ausgabe windows-1252
Hast Du den Chatclient/Chatserver schon mal testen können? Und Du hast recht, den DBServer hatte ich nochmals verändert. Soll ich den Code für Client und Server nochmals einstellen? Ich möchte unbedingt wissen, warum meine Version nicht funktioniert, auch wenn die Codequalität natürlich sehr zu wünschen übrig lässt und Du mit Deiner Kritik recht hast. Vor allem die Sache mitdem Chatprogramm will mir nicht inden Kopf. Es hat sich lediglich dei WAN-IP geändert, der Code ist genauso wie vorher, auch die Einstellung der statischen Portweiterleitung im Router ist unverändert.
Ja, bitte Server und Client in der Version einstellen, in der der Fehler gekommen ist. Und dazu bitte die ganze Ausgabe, also auch incl. ggf. getätigter Ausgaben.
 

Jw456

Top Contributor
Hallo JW456,

nein, das ist nicht die Ursache. In einer zweiten Version habe ich dei ArrayList parametrisiert, das macht aber keinen Unterschied. Und wie gesagt, im lokalen Netz mit 3 Rechnern läuft das Ganze ja einwandfrei und bis vor einiger Zeit auch mit meiner WAN-IP, nun plötzlich nicht mehr.

ArrayList clientAusgabeStröme;
//dann kommt das
public void los() {
clientAusgabeStröme = new ArrayList();

wo sind die Spitzen Klammern im post #59 beim server?
 

Turing0001

Aktives Mitglied
Hallo Kneitzel,

Sie wünschen, wir liefern.

Client:

Java:
package mypackage;

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




public class ClientDB {
    
     private InetSocketAddress address;
     PrintWriter writer;
    
    public void los()
    {
        
        try
        {
        
            
         address = new InetSocketAddress("192.168.2.101",4243);// Hier natürlich die WAN-IP angeben
        
          Socket s = new Socket();
          s.connect(address, 3000); // Verbinde Dich mit dem Server, maximale Wartezeit: 3 Sekunden
          
          // Erstellen eines Printwriters, da hier Texte und keine binären Rohdaten gesendet werden:
          
          writer = new PrintWriter(s.getOutputStream());
          writer.println("select * from leute"); // SQL-Befehl an Server absenden
          try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
          writer.flush();
          
          // Empfangen werden vom Server aber binäre Rohdaten, also wird ObjectInputStream benötigt:
          
          ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
          
    
          // Ausgabe der ArrayList mit dem ResultSet der Datenbank in einem String
          // nachdem die Rohdaten zunächst wieder in eine ArrayList von Typ String
          // zurückverwandelt wurden
          
          System.out.println("Ausgabe der Daten:");
          ArrayList <String> al = (ArrayList<String>)(ois.readObject());
          System.out.println(al.toString());
        
        
//          ois.close();
//          s.close();
//          writer.close();
        }
          
       catch(IOException ex) {ex.printStackTrace();}
       catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // Client starten:
        
        ClientDB client1 = new ClientDB();
        client1.los();
    }
}

Client Fehlermeldung:

java.net.SocketException: Ein Verbindungsversuch ist fehlgeschlagen, da die Gegenstelle nach einer bestimmten Zeitspanne nicht richtig reagiert hat, oder die hergestellte Verbindung war fehlerhaft, da der verbundene Host nicht reagiert hat
at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:325)
at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:350)
at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:803)
at java.base/java.net.Socket$SocketInputStream.read(Socket.java:981)
at java.base/java.io_ObjectInputStream$PeekInputStream.read(ObjectInputStream.java:2914)
at java.base/java.io_ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2930)
at java.base/java.io_ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:3427)
at java.base/java.io_ObjectInputStream.readStreamHeader(ObjectInputStream.java:962)
at java.base/java.io_ObjectInputStream.<init>(ObjectInputStream.java:405)
at mypackage.ClientDB.los(ClientDB.java:41)
at mypackage.ClientDB.main(ClientDB.java:73)


Servercode:

Java:
package mypackage;

import java.io.*;
import java.net.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;

import javax.swing.JOptionPane;



public class ServerDB {
    
    Connection conn;//Schnittstelle um Verbindung zur DB herzustellen
    Statement stmt;
    ResultSet rSet;
    BufferedReader reader;
    

    public void los()
    {
        try
        {
            ServerSocket servsock = new ServerSocket(4243); // Verbindungsschnittstelle auf Port 4243 erstellen
            while(true)
            {
                System.out.println("Hallo hier ist der Server!");
                Socket sock = servsock.accept(); // Warten auf "Anruf" von einem Client. accept() blockiert bis ein Client "anruft"
                
                // Empfange einen String (= SQL Befehl) vom Client:
                
                InputStreamReader isReader = new InputStreamReader (sock.getInputStream());
                reader = new BufferedReader(isReader);
                //String nachricht = reader.readLine(); // Lesen des SQL Befehls
                String nachricht = null;
                System.out.println("Bin hier");
                OutputStream os = sock.getOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(os);
                //oos.writeObject(tabledat);
                //System.out.println("Daten zurückgeschickt an Client");
                oos.flush();
                
                nachricht = reader.readLine(); // Lesen des SQL Befehls
            
                System.out.println("Empfangene Nachricht: " + nachricht);
//                try {
//                    Thread.sleep(500);
//                } catch (InterruptedException e) {
//                    // TODO Auto-generated catch block
//                    e.printStackTrace();
//                }
                //JOptionPane.showMessageDialog(null, "Nachricht: " + nachricht);
                System.out.println("Empfangene Nachricht nochmal: " + nachricht);
                // Ab hier wieder wie gehabt Verbindung zur Datenbank:
                
               DriverManager.setLogWriter(new PrintWriter(System.out));
               Class.forName("org.sqlite.JDBC");
               System.out.println("Treiber geladen");
               String url = "jdbc:sqlite::resource:"+ "MyDB.db";
               conn = DriverManager.getConnection(url,"",""); // Verbindungsobjekt erstellen
                  System.out.println("Verbindung steht" );
                  stmt = conn.createStatement();
                  rSet = stmt.executeQuery(nachricht); // Schicke den SQL-Befehl an die Datenbank und nimm das Ergebnis entgegen
                  ResultSetMetaData md = rSet.getMetaData(); // Ermittele Meta-Daten des ResultSets
                  int columns = md.getColumnCount();
                  System.out.println("Anzahl der Spalten: " + columns + " \n");
                  
                  ArrayList <String> tabledat = new ArrayList<String>();
                  
                  while(rSet.next()) { // Solange noch Ergebnisdatensätze da sind...
                
                for(int i=1; i<=columns; ++i) {
                     // Durchlaufe alle Spalten der aktuellen Zeile des ResultSets
                    tabledat.add(rSet.getString(i)); // Aktuellen Eintrag des ResultSets in ArrayList speichern
                    
                }
            }
                  
                  
                  
                  // Ergebnis der Datenbankabfrage wir wieder als binärer Datenstrom zum
                  // Client zurückgeschickt
                  
//                  OutputStream os = sock.getOutputStream();
//                  ObjectOutputStream oos = new ObjectOutputStream(os);
                  
              oos.writeObject(tabledat);
              System.out.println("Daten zurückgeschickt an Client");
//               oos.flush();
              
               //oos.close();
               //servsock.close();
            }
            
        }
        
        catch (IOException ex)
        {ex.printStackTrace();}
        catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        finally {           
            CloseDB(stmt,conn); // Datenbankverbindung schließen
        }   
    
    
  
}
    
    public void CloseDB(Statement stmt, Connection conn )
    {
        try {
            stmt.close();
            conn.close();
        } catch(Exception e) {
            //
        }
    }
    public static void main(String[] args) {
        // Starte den Server:
        
        ServerDB serv = new ServerDB();
        serv.los();
    }
}


Server Ausgabe und Fehlermeldung:

Hallo hier ist der Server!
Bin hier
java.net.SocketException: Ein Verbindungsversuch ist fehlgeschlagen, da die Gegenstelle nach einer bestimmten Zeitspanne nicht richtig reagiert hat, oder die hergestellte Verbindung war fehlerhaft, da der verbundene Host nicht reagiert hat
at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:325)
at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:350)
at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:803)
at java.base/java.net.Socket$SocketInputStream.read(Socket.java:981)
at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:297)
at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:339)
at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:188)
at java.base/java.io.InputStreamReader.read(InputStreamReader.java:181)
at java.base/java.io.BufferedReader.fill(BufferedReader.java:161)
at java.base/java.io.BufferedReader.readLine(BufferedReader.java:326)
at java.base/java.io.BufferedReader.readLine(BufferedReader.java:392)
at mypackage.ServerDB.los(ServerDB.java:48)
at mypackage.ServerDB.main(ServerDB.java:132)

Ich hoffe, das hilft Dir weiter.
 
K

kneitzel

Gast
ArrayList clientAusgabeStröme;
//dann kommt das
public void los() {
clientAusgabeStröme = new ArrayList();

wo sind die Spitzen Klammern im post #59 beim server?
Die braucht man nicht. Wäre dies zwingend notwendig, dann wäre Java bei Einführung der Generics nicht abwärts kompatibel gewesen.

Daher ist es vollkommen legitim, das auch so zu nutzen.
 

Turing0001

Aktives Mitglied
Hallo Kneitzel,

kann ich Dir hier über das Forum eine PN zukommen lassen? Dann würde ich Dir meine WAN-IP geben (da ich Dir vertraue), Server läuft und Du könntest den Client mal direkt testen. Ansonsten per sms wenn ich Dir die Handynummer gebe (auf den sozialen Medien bin ich nirgends engagiert, zu wenig Vertrauen). Jetzt erst mal Brotzeit!
 
K

kneitzel

Gast
schon komisch gradle biringt mir den fehler Maven nicht
OK
Mit was für einem Charset arbeitest Du? Bei Maven hast Du in den Properties in der Regel etwas wie:
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

und in Gradle ein:
tasks.withType(JavaCompile) { options.encoding = 'UTF-8' }

Damit sollten Umlaute verarbeitet werden können.

@Turing0001
Ich bin im Augenblick etwas ratlos. Das sieht eigentlich soweit in Ordnung aus. Ich bin nur über eine Sache gestolpert:
Socket.getInputStream kann wohl Bytes wegwerfen, wenn diese schon im Socket zwischengespeichert sind:
  • The network software may discard bytes that are buffered by the socket. Bytes that aren't discarded by the network software can be read using read.
Aber so ganz verstehen tue ich das im Augenblick nicht.

Was Du ändern kannst: Zieh das Erzeugen der jeweiligen Streams / Writer direkt nach den connect:

Also im Client:
Java:
            s.connect(address, 3000); // Verbinde Dich mit dem Server, maximale Wartezeit: 3 Sekunden
            ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
            writer = new PrintWriter(s.getOutputStream());

Und im Server:
Java:
                Socket sock = servsock.accept(); // Warten auf "Anruf" von einem Client. accept() blockiert bis ein Client "anruft"
                InputStreamReader isReader = new InputStreamReader (sock.getInputStream());
                OutputStream os = sock.getOutputStream();

Verändert das evtl. schon etwas?

kann ich Dir hier über das Forum eine PN zukommen lassen? Dann würde ich Dir meine WAN-IP geben (da ich Dir vertraue), Server läuft und Du könntest den Client mal direkt testen. Ansonsten per sms wenn ich Dir die Handynummer gebe (auf den sozialen Medien bin ich nirgends engagiert, zu wenig Vertrauen). Jetzt erst mal Brotzeit!
Über "Gespräche" kannst Du mir persönliche Nachrichten im Forum zuschicken.
 

Jw456

Top Contributor
habe es auch auf einem Rechner Server und Client getestet mit öffentlicher IP geht.

habe im Moment keinen zweiten Rechner .



Frage was hast du eine IPv4 oder IPv6?
 

Jw456

Top Contributor
Hallo habe dienen Server und Client Code mit Gui noch mal mit zwei Rechner getestet.
Im Lan mit Öffentlicher IP im Client. Natürlich habe ich den Port im Router geforwarded .
Geht bei mir.



An deinem Code liegt es nicht wenn es bei dir nicht geht.
Da würde ich auf den Router tippen als erstes. Vielleicht ist da eine Firewall die das blockiert.
Order dein Forwarding ist nicht richtig.



Welchen Router hast du?



Wie schon gesagt geht es ja auch bei deinen Kumpels. Nur bei dir nicht da wollte aber gestern keiner richtig drauf eingehen. Also muss es eigentlich eine Konfig Sache Router oder Rechner sein. Nicht der Java Code.



Ob das Ganze in Bezug auf Sicherheit sinnvoll ist, ist wider ein anders Thema.
 

Turing0001

Aktives Mitglied
Hallo habe dienen Server und Client Code mit Gui noch mal mit zwei Rechner getestet.
Im Lan mit Öffentlicher IP im Client. Natürlich habe ich den Port im Router geforwarded .
Geht bei mir.



An deinem Code liegt es nicht wenn es bei dir nicht geht.
Da würde ich auf den Router tippen als erstes. Vielleicht ist da eine Firewall die das blockiert.
Order dein Forwarding ist nicht richtig.



Welchen Router hast du?



Wie schon gesagt geht es ja auch bei deinen Kumpels. Nur bei dir nicht da wollte aber gestern keiner richtig drauf eingehen. Also muss es eigentlich eine Konfig Sache Router oder Rechner sein. Nicht der Java Code.



Ob das Ganze in Bezug auf Sicherheit sinnvoll ist, ist wider ein anders Thema.
Hallo,

danke für die Info. Kneitzel hatte es gestern auch probiert und das Ergebnis war einwandfrei. Muss also beim Router irgendetwas sein. Ich habe die Einstellungen zur Portweiterleitung überprüft, daran liegt es nicht, da habe ich auch seit Monaten nichts verändert. Bei der Firewall bin ich mir nicht sicher, ich habe nur die Windows-Firewall aktiviert, aber auch dahatsich eigentlich in letzter Zeit nichts geändert. Wegen der Porteinstellungen hier mal ein Screenshot (obwohl das meines Wisssens nach hier im Forum wohl nicht so gerne gesehen wird wenn ich mich recht erinnere):

Screen.png


Dasganze istwirklich sehr mysteriös. Ich werde aber auch nochmal mit der Firewall experimentieren. Vielen Dank für Deine Mühe.
 

Jw456

Top Contributor
Benutze mal im Router nicht den Rechner Nahmen sondern die IP die er im Lan hat.
Firewall im Router wenn vorhanden mal ausschalten.
 
K

kneitzel

Gast
Der Router lässt ja den Verbindungsaufbau zu. Das zeigt, dass das Portforwarding funktioniert auf den Router.
Und da die Connection zustande kommt, ist da auch erst einmal keine Firewall, die den Verbindungsaufbau blockiert.

An welcher Stelle etwas schief läuft, kann ich im Augenblick so auch nicht sagen. Da wäre es interessant, mal mit wireshark die Pakete im Detail zu analysieren um zu sehen, was für Pakete wohin geschickt werden. Die einfachen Erklärungsversuche taugen aber schlicht nichts (Und es würden andere Verhalten auftreten, so an den Stellen etwas nicht klappen sollte).

Man kann den Router einmal ausschalten und wieder einschalten um da ein Fehlverhalten etwas auszuschließen. Aber halte ich für unwahrscheinlich.

Mal ein ganz einfacher Test, den Du aber mal laufen lassen könntest:
[CODE lang="java" title="ServerDB"]package mypackage;

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

public class ServerDB {

public void los()
{
try
{
ServerSocket servsock = new ServerSocket(4243);
System.out.println("Waiting on port 4243 ...");
Socket socket = servsock.accept();
System.out.println("connected!");
OutputStream out = socket.getOutputStream();
InputStream in = socket.getInputStream();

new Thread( () -> {
try {
while (true) System.out.println("Received: " + in.read());
} catch (IOException ex) {
ex.printStackTrace();
}
}).start();

for (int i = 0; i<100; i++) {
out.write(i);
System.out.println("Send: " + i);
out.flush();
}

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

public static void main(String[] args) {
ServerDB serv = new ServerDB();
serv.los();
}
}[/CODE]

[CODE lang="java" title="ClientDB"]package mypackage;

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

public class ClientDB {

public void los()
{

try
{
InetSocketAddress address = new InetSocketAddress("127.0.0.1",4243);

Socket socket = new Socket();
socket.connect(address, 3000);
System.out.println("connected!");
OutputStream out = socket.getOutputStream();
InputStream in = socket.getInputStream();

new Thread( () -> {
try {
while (true) System.out.println("Received: " + in.read());
} catch (IOException ex) {
ex.printStackTrace();
}
}).start();

for (int i = 0; i<100; i++) {
out.write(i);
System.out.println("Send: " + i);
out.flush();
}
}

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

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// Client starten:

ClientDB client1 = new ClientDB();
client1.los();
}
}[/CODE]

Der Test nutzt minimale Funktionen um einfach nur paar Bytes zu versenden. (Beide senden einfach von 0-99 hin)

Die Programme beenden sich nicht - also erst Server starten, dann Client, dann sollten die Zahlen von 0-99 versendet und empfangen worden sein und du kannst mit Ctrl-C beide abbrechen.
 

Turing0001

Aktives Mitglied
Der Router lässt ja den Verbindungsaufbau zu. Das zeigt, dass das Portforwarding funktioniert auf den Router.
Und da die Connection zustande kommt, ist da auch erst einmal keine Firewall, die den Verbindungsaufbau blockiert.

An welcher Stelle etwas schief läuft, kann ich im Augenblick so auch nicht sagen. Da wäre es interessant, mal mit wireshark die Pakete im Detail zu analysieren um zu sehen, was für Pakete wohin geschickt werden. Die einfachen Erklärungsversuche taugen aber schlicht nichts (Und es würden andere Verhalten auftreten, so an den Stellen etwas nicht klappen sollte).

Man kann den Router einmal ausschalten und wieder einschalten um da ein Fehlverhalten etwas auszuschließen. Aber halte ich für unwahrscheinlich.

Mal ein ganz einfacher Test, den Du aber mal laufen lassen könntest:
[CODE lang="java" title="ServerDB"]package mypackage;

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

public class ServerDB {

public void los()
{
try
{
ServerSocket servsock = new ServerSocket(4243);
System.out.println("Waiting on port 4243 ...");
Socket socket = servsock.accept();
System.out.println("connected!");
OutputStream out = socket.getOutputStream();
InputStream in = socket.getInputStream();

new Thread( () -> {
try {
while (true) System.out.println("Received: " + in.read());
} catch (IOException ex) {
ex.printStackTrace();
}
}).start();

for (int i = 0; i<100; i++) {
out.write(i);
System.out.println("Send: " + i);
out.flush();
}

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

public static void main(String[] args) {
ServerDB serv = new ServerDB();
serv.los();
}
}[/CODE]

[CODE lang="java" title="ClientDB"]package mypackage;

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

public class ClientDB {

public void los()
{

try
{
InetSocketAddress address = new InetSocketAddress("127.0.0.1",4243);

Socket socket = new Socket();
socket.connect(address, 3000);
System.out.println("connected!");
OutputStream out = socket.getOutputStream();
InputStream in = socket.getInputStream();

new Thread( () -> {
try {
while (true) System.out.println("Received: " + in.read());
} catch (IOException ex) {
ex.printStackTrace();
}
}).start();

for (int i = 0; i<100; i++) {
out.write(i);
System.out.println("Send: " + i);
out.flush();
}
}

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

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// Client starten:

ClientDB client1 = new ClientDB();
client1.los();
}
}[/CODE]

Der Test nutzt minimale Funktionen um einfach nur paar Bytes zu versenden. (Beide senden einfach von 0-99 hin)

Die Programme beenden sich nicht - also erst Server starten, dann Client, dann sollten die Zahlen von 0-99 versendet und empfangen worden sein und du kannst mit Ctrl-C beide abbrechen.
Hallo Kneitzel,

habe es gerade in Eclipse getestet. Bei Client und Server wird in der Konsole Send 0 ... Send 99 ausgegeben, aber bei beiden keine Received-Ausgabe, stattdessen bei beiden wieder nach einiger Zeit die Fehlermeldung (hier die vom Client):

java.net.SocketException: Ein Verbindungsversuch ist fehlgeschlagen, da die Gegenstelle nach einer bestimmten Zeitspanne nicht richtig reagiert hat, oder die hergestellte Verbindung war fehlerhaft, da der verbundene Host nicht reagiert hat
at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:325)
at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:350)
at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:803)
at java.base/java.net.Socket$SocketInputStream.read(Socket.java:981)
at java.base/java.net.Socket$SocketInputStream.read(Socket.java:976)
at mypackage.ClientDB.lambda$0(ClientDB.java:23)
at java.base/java.lang.Thread.run(Thread.java:832)

Ich weiß auch keinen Rat mehr, zumal bei Dir ja der Zugriff auf meine WAN-IP korrekt funktionierte
 
K

kneitzel

Gast
Ich habe jetzt noch einmal etwas mehr recherchiert. Es findet sich in den Telekom Hilfeseiten einiges an Aussagen, dass die Portfreischaltung nur von Außen getestet werden kann. Aber wirkliche Aussagen, die man hier ernsthaft zitieren könnte, kann ich nicht bringen. Das ist aber definitiv eine Spezialität des Speedport Routers (Besonders speziell wird es, da ja der Verbindungsaufbau klappt, d.h. beim Verbindungsaufbau senden sich Server und Client erfolgreich Pakete zu. Nur nachfolgende Pakete werden dann nicht mehr weiter gesendet.

Die Anleitung zu den Speedport 900 Routern habe ich auch einmal durchgesehen - da ist diesbezüglich keinerlei Konfiguration vorgesehen / möglich.

(Bei z.B. FirtzBox klappt sowas übrigens auch ganz ohne Probleme. Ebenso bei selbst aufgesetzten (Linux-) Routern. Ich greife auf meinen Terminal-Server immer über den DNS Namen zu - und damit immer über die externe IP)

Jetzt könnte man ja sagen: Dann musst Du halt lokale Tests per lokalen IPs machen. Aber diese Aussage ist in meinen Augen recht fatal, denn das verkompliziert einiges. Man will ja später auch per DNS zugreifen um dann auch SSL und co zu haben.
 

Turing0001

Aktives Mitglied
Ich habe jetzt noch einmal etwas mehr recherchiert. Es findet sich in den Telekom Hilfeseiten einiges an Aussagen, dass die Portfreischaltung nur von Außen getestet werden kann. Aber wirkliche Aussagen, die man hier ernsthaft zitieren könnte, kann ich nicht bringen. Das ist aber definitiv eine Spezialität des Speedport Routers (Besonders speziell wird es, da ja der Verbindungsaufbau klappt, d.h. beim Verbindungsaufbau senden sich Server und Client erfolgreich Pakete zu. Nur nachfolgende Pakete werden dann nicht mehr weiter gesendet.

Die Anleitung zu den Speedport 900 Routern habe ich auch einmal durchgesehen - da ist diesbezüglich keinerlei Konfiguration vorgesehen / möglich.

(Bei z.B. FirtzBox klappt sowas übrigens auch ganz ohne Probleme. Ebenso bei selbst aufgesetzten (Linux-) Routern. Ich greife auf meinen Terminal-Server immer über den DNS Namen zu - und damit immer über die externe IP)

Jetzt könnte man ja sagen: Dann musst Du halt lokale Tests per lokalen IPs machen. Aber diese Aussage ist in meinen Augen recht fatal, denn das verkompliziert einiges. Man will ja später auch per DNS zugreifen um dann auch SSL und co zu haben.
Hallo Kneitzel,

so ist es. Habe gerade den Router neu gestartet, ohne Verbesserung. Ich werde mich die nächsten Tage mal mit der Telekom in Verbindung setzen, vielleicht haben die eine Antwort. Vielen vielen Dank jedenfals für eure Mühen.
 

Jw456

Top Contributor
Hallo Kneitzel,

habe es gerade in Eclipse getestet. Bei Client und Server wird in der Konsole Send 0 ... Send 99 ausgegeben, aber bei beiden keine Received-Ausgabe, stattdessen bei beiden wieder nach einiger Zeit die Fehlermeldung (hier die vom Client):

java.net.SocketException: Ein Verbindungsversuch ist fehlgeschlagen, da die Gegenstelle nach einer bestimmten Zeitspanne nicht richtig reagiert hat, oder die hergestellte Verbindung war fehlerhaft, da der verbundene Host nicht reagiert hat
at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:325)
at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:350)
at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:803)
at java.base/java.net.Socket$SocketInputStream.read(Socket.java:981)
at java.base/java.net.Socket$SocketInputStream.read(Socket.java:976)
at mypackage.ClientDB.lambda$0(ClientDB.java:23)
at java.base/java.lang.Thread.run(Thread.java:832)

Ich weiß auch keinen Rat mehr, zumal bei Dir ja der Zugriff auf meine WAN-IP korrekt funktionierte
zur info
mit dem Localhost 127.0.0.1
habe ich auch keinen Reciev. mit der öffentlichen oder der interenen server ip ja.

was der Test auf den Localhost bewirken solte ist mir nicht klar.

edit hatte es auf einen Rechner.
 

mihe7

Top Contributor
Jetzt könnte man ja sagen: Dann musst Du halt lokale Tests per lokalen IPs machen. Aber diese Aussage ist in meinen Augen recht fatal, denn das verkompliziert einiges. Man will ja später auch per DNS zugreifen um dann auch SSL und co zu haben.
Man kann testweise auch über die hosts den Domainnamen auf eine lokale IP mappen, vielleicht wäre das für @Turing0001 ein gangbarer Workaround.
 
K

kneitzel

Gast
Man kann testweise auch über die hosts den Domainnamen auf eine lokale IP mappen, vielleicht wäre das für @Turing0001 ein gangbarer Workaround.
Ja, aber das muss dann bei jedem Rechner sein … und Tests sind dann nur begrenzt möglich, z.B. in Form eines Portscans.

Mich wundert vor allem das Verhalten. Was hat die Telekom da gebaut? Denn unter dem Strich wird da doch auch nur ein Linux in der Kiste stecken mit entsprechender Konfiguration. Aber da habe ich keine Informationen zu gefunden. Interessiert mich, da bei mir eigentlich ein Wechsel von Vodafone zur Telekom ansteht und mich das dann ja auch treffen würde…
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
T Brauche Hilfe beim GET-String für HttpURLConnection Netzwerkprogrammierung 4
T server empfängt nur 1 Buchstaben vom String Netzwerkprogrammierung 1
N Name eines Attributes aus einem festen String und einer Variablen generieren Netzwerkprogrammierung 5
S Socket String InputStream in hex umwandeln Netzwerkprogrammierung 1
T Socket Gleiche String ungleich? Netzwerkprogrammierung 8
M Socket String Arrays über Socket an Server schicken Netzwerkprogrammierung 2
F String in Datenbank speichern Netzwerkprogrammierung 1
I RMI String Netzwerkprogrammierung 2
precoc String Array versenden Netzwerkprogrammierung 7
T Socket String zu Socket Netzwerkprogrammierung 26
7 String an Server Netzwerkprogrammierung 2
lumo String[] wird zu null bei Serialisierung Netzwerkprogrammierung 8
S WebService, 4-stelliger String (Jahr) als Calendar Netzwerkprogrammierung 5
M String an PHP Script aus Java übergeben Netzwerkprogrammierung 12
N String als byte Array über Socket versenden Netzwerkprogrammierung 8
M Messenger - String oder Objekte Netzwerkprogrammierung 4
T Socket Nullterminierten String lesen Netzwerkprogrammierung 4
J Datei übertragen ja String + datei übertragen nein Netzwerkprogrammierung 5
H String Array durch einen Stream schicken. Netzwerkprogrammierung 4
N Socket Stream in String Netzwerkprogrammierung 4
J Browser-String angeben Netzwerkprogrammierung 5
S String[] über Socket senden Netzwerkprogrammierung 3
F Stream wird als Char übertragen. Char -> in String umwand Netzwerkprogrammierung 5
G String in InetAddres umwandeln klappt nicht Netzwerkprogrammierung 5
A String per ByteBuffer empfangen? Netzwerkprogrammierung 6
ModellbahnerTT Problem feste String ins Netzwerk zu geben Netzwerkprogrammierung 5
G UTF-8 in STring umwandeln oder umgedreht Netzwerkprogrammierung 12
F String in eine URL umwandeln Netzwerkprogrammierung 7
P string over net Netzwerkprogrammierung 4
T Html-Source über URL in einen String speichern? Netzwerkprogrammierung 16
B HEX String zu einem Byte Array ? *verzweiflung* :( Netzwerkprogrammierung 16
K String zurück liefern ! Netzwerkprogrammierung 4
S SSLSocketFactory.createSocket(String hostname, int port),wo? Netzwerkprogrammierung 5
O Ip-String in byte[]-Array umwandeln? Netzwerkprogrammierung 3
C gesendeten String einlesen Netzwerkprogrammierung 3
G String to Socket ? Netzwerkprogrammierung 3
A StringCorruptedException: invalid String header Netzwerkprogrammierung 2
I Performanteste Kommunikationsmethode zwischen Client u. Server Netzwerkprogrammierung 4
L Socket Automatische Zuweisung von Server und Client Rolle Netzwerkprogrammierung 12
ExceptionOfExpectation Server/Client-Kommunikation Netzwerkprogrammierung 34
M Server-Client-System für Browsergame Netzwerkprogrammierung 5
B Axis2 Webservice mit Client Zertifikat Authentifizierung Netzwerkprogrammierung 3
Yonnig Threads mit Client/Server und GUI (laufend bis button-click) Netzwerkprogrammierung 9
T Jetty mit Client-Zertifikat nur bei spezifischer URL Netzwerkprogrammierung 1
J Einlesen von Servernachrichten von TCP-Client Netzwerkprogrammierung 17
J Client-Server und SOAP Netzwerkprogrammierung 23
L30nS RMI Aufruf einer Client-Methode von einem RMI-Server Netzwerkprogrammierung 3
D WebSocket Server mit HTML Client und Java Server Netzwerkprogrammierung 5
D Server - Client Informationsaustausch, Möglichkeiten Netzwerkprogrammierung 3
H Socket Chat entwickeln mit Java Server Client Netzwerkprogrammierung 4
X Kann ich einen Client/Server verbindung hinkriegen die mir alle paar Sekunden die aktuellen Daten per Realtime zuschickt ? Netzwerkprogrammierung 9
T Client zu Client Kommunikation Netzwerkprogrammierung 2
D Slf4j - Logging - Client-Server Architektur Netzwerkprogrammierung 3
J client server mit nur einem PC Netzwerkprogrammierung 33
M Socket Nachricht von TCP-Client an Server schicken Netzwerkprogrammierung 12
M Socket Verbindung Matlab(Server) Java(Client) Netzwerkprogrammierung 1
R Socket FATAL EXCEPTION MAIN bei Socket based client/server app Netzwerkprogrammierung 2
G Server-Client IO Problem Netzwerkprogrammierung 6
ruutaiokwu ständig "sender address rejected: improper use of smtp" bei smtp-client Netzwerkprogrammierung 4
J HTTP [Java 9] Neuer HTTP Client - Tutorial Netzwerkprogrammierung 3
A Chatserver/-client - Code stoppt bei readUTF() Netzwerkprogrammierung 7
I Socket Das erste Server-Client Programm Netzwerkprogrammierung 16
L Zugriffprobleme Client - Webservice AspenTechnology Netzwerkprogrammierung 0
A Client Client Übertragung Netzwerkprogrammierung 12
M Socket Server antwortet dem Client nicht Netzwerkprogrammierung 6
K Socket Netty Client wirft Fehler! Netzwerkprogrammierung 3
I Client/Server Kommunikation bei einem Spiel Netzwerkprogrammierung 4
E Objekte versenden, Client-Server Netzwerkprogrammierung 25
C Mini Client-Server-Anwendung funktioniert nicht Netzwerkprogrammierung 8
U Client Soap Verbindung wieder schließen Netzwerkprogrammierung 0
U Socket Client mit hash authentifizieren Netzwerkprogrammierung 3
F HTTP HTTP Rest Client mit TLS1.2 und selbst signiertem Zertifikat Netzwerkprogrammierung 2
P Server als Client nutzen Netzwerkprogrammierung 8
D Socket Run Args Client/Server Socket Netzwerkprogrammierung 1
Cromewell Socket Multithreaded Server und Client Netzwerkprogrammierung 1
Y Client/Server/DB communication Netzwerkprogrammierung 3
JavaWolf165 Socket mit .writeUtf etwas vom Client zum Server schicken Netzwerkprogrammierung 13
J Client - Serversocket Netzwerkprogrammierung 1
P RMI Client Server Programm über Internet Netzwerkprogrammierung 2
brainless Client Server Kommunikation verschlüsseln Netzwerkprogrammierung 13
gamebreiti Socket Server / Client Anwendung Manipulation von Objekten durch Server Netzwerkprogrammierung 9
T Socket Server/Client Kommunikation Netzwerkprogrammierung 8
N Fragen zu Sockets Client Netzwerkprogrammierung 3
F Extasys TCp Client extends Funktion Netzwerkprogrammierung 0
F Server Client Anwendung mit UDP Netzwerkprogrammierung 2
O Client zwischen XML und JSON auswählen lassen Netzwerkprogrammierung 2
A RMI Wo treten Exceptions bei RMI Aufrufen auf? Auf Client oder auf Server? Netzwerkprogrammierung 3
A ByteBuffer - Client/Server Netzwerkprogrammierung 9
A Socket Wie ein einfacher Multithreads Service mit Telnet als Client mit Observable/Observer gelöst.... Netzwerkprogrammierung 0
K C# Server - Android Client Netzwerkprogrammierung 0
T Application Client NullPointerExc Netzwerkprogrammierung 7
V TCP Client funktioniert auf Emulator aber nicht auf Smartphone Netzwerkprogrammierung 5
H Machbarkeitsfrage: TCP/IP Client (z.B. Netty) für Java Web Applcation Netzwerkprogrammierung 1
P MIME-TYPE Erklaerung, Kommunikation zwischen Client und Server Netzwerkprogrammierung 3
H HTTP REST Jersey - PUT-Beispiel von Client senden Netzwerkprogrammierung 0
J Sichere Kommunikation bei Server Client Netzwerkprogrammierung 3
T Frage zu Client-Server Applikation Netzwerkprogrammierung 2
H Socket Client/Server Socket Programmieren Netzwerkprogrammierung 1
M Theoretische Frage zu Server - Client Netzwerkprogrammierung 2
P HTTP Server / Client Netzwerkprogrammierung 1

Ähnliche Java Themen

Neue Themen


Oben