BufferedStream funktioniert nicht immer

Spiderpic98

Mitglied
Guten Tag,

ich habe ein Problem mit meinem Code. Ich versuche einen Chat zu erstellen und übergebe dem Server mithilfe von Write eine Naricht die dann der Server in der Konsole mit readline() ausgeben soll. Das komische ist nun, es funktioniert nur im Schnitt jedes 2. mal und ich verstehe nicht wieso

Java:
public class MessageController extends Thread {
  public static BufferedWriter out;
  public static BufferedReader in;

  public MessageController() throws IOException {

    System.out.println("MessageController gestartet");

  }

  @Override
  public void run() {
    try {
    BufferedWriter  out = new BufferedWriter(new OutputStreamWriter(Server.client.getOutputStream()));
    BufferedReader  in = new BufferedReader(new InputStreamReader(Server.client.getInputStream()));
    } catch (IOException e) {
      throw new RuntimeException(e);
    }

    while(true){
      System.out.println("Message wird gelesen");
      try{

          System.out.println("MessageController erhalten: " + in.readLine());

      }catch(IOException e){
        e.printStackTrace();
        System.out.println("fehler");
      }

    }


  }



}
Das ist der MessageListener der auf eine Naricht wartet. Dort wird der Output und Input vom Server erstellt.

Java:
try {

                            sendMessage();
                            System.out.println("Naricht wird gesendet");
                            System.out.println("ChatPane: " + messageText);
                            output.write(messageText);
                            output.newLine();
                            output.flush();
                            System.out.println("Naricht wurde gesendet");

                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }

Das ist der Ort an dem Die Naricht losgeschickt wird. Die Streams werden in der Methode sendMessage() erzeugt.

Code:
public class Server extends Thread
{

    public static ServerSocket server;

    public static Socket client;
    int port;

    public Server(int port) throws IOException
    {
       this.port = port;
        server = new ServerSocket(port);
        client = new Socket("localhost",port);

        System.out.println(port);
     //    server.setSoTimeout(10000);
    }


    @Override
    public void run() {

      try {
        ConnectionListener connectionListener;
        connectionListener = new ConnectionListener();
        connectionListener.start();
        MessageController messageController;
        messageController = new MessageController();
        messageController.start();
      } catch (IOException e) {
        throw new RuntimeException(e);
      }


      while (!server.isClosed()) {

        if (!client.isConnected()) {
          System.out.println("waiting for client");
        }

      }

    }

}

Und das ist der Server. Der Thread ConnectionListener macht nichts anderes als die accept() Methode abwickeln.
Ich habe jeweils einen Socket im Client und einem im Server. Ich verstehe nicht warum es mal funktioniert und mal nicht. Laut der Konsole führt er jedes mal alles bis

Java:
System.out.println("MessageController erhalten: " + in.readLine());

hierhin aus und dann wartet er auf input. Und ich vermute mal entweder es erreicht ihn gar nicht erst was oder er kann nichts damit anfangen was er bekommt.
Hat jemand vielleicht Rat?
 

KonradN

Super-Moderator
Mitarbeiter
Was ist das genaue Fehlerbild? Was passiert denn genau?

Was sein kann: Du startest mehrere Threads direkt hintereinander. Da nicht der ganze Code zu sehen ist, kann man nur raten, aber es wäre z.B. möglich, dass der Server Thread den Socket noch nicht richtig erstellt hat, wenn der Client bereits seinen connection Requests abgesetzt hat. Dann schlägt der Connection Request direkt fehl, der Server öffnet dann den Thread und es kommt aber kein Client mehr, da Du ja nur einen einzigen Client startest.

Lösung in so einem Fall wäre, dass man wirklich erst den Server bis zu Ende erstellt, ehe man den Client aufruft oder das in zwei Applikationen packt. Dann rufst Du erst den Server auf und wenn der Server läuft, dann rufst Du den Client zusätzlich auf.

Generell ist der Aufbau so aber auch extrem "mangelhaft". Da so mit statischen Variablen zu arbeiten, die auch public sind, würde ich schlicht als falsch bezeichnen.

Hier sollte man Variablen private und nicht statisch haben. Wenn eine Klasse eine Instanz auf eine andere Klasse. braucht, dann sollte man ihr diese geben (z.B. im Konstruktor). So würde man dann saubere Abhängigkeiten bekommen und man hätte auch eine Kapselung so dass man einfacher Elemente ändern kann ohne dann an mehreren Stellen massiv Änderungen vornehmen zu müssen.
 

KonradN

Super-Moderator
Mitarbeiter
Wie so eine Server Implementierung etwas aussehen könnte, die mit Threads arbeitet, habe ich einmal auf die Schnelle unter
skizziert.

Ist aber noch nicht getestet und der Client fehlt noch ... Und Nachrichten, die der Server empfängt sendet er einfach an alle (anderen) verbundenen Clients weiter.
 

KonradN

Super-Moderator
Mitarbeiter
Evtl. auch hier noch kurz ein paar Hinweise zu dem Code, da es ja auch um die Vermeidung von so public static Variablen ging.
(Ich habe noch ein paar weitere Änderungen eingebaut, aber immer noch ungetestet. Sorry!)

Man baut es als Objekte auf. So habe ich einen TcpServer als Klasse aufgebaut.

- Dieser soll ja auf einem Port hören, daher wird beim Konstruktor der port übergeben und da dann auch erst einmal gespeichert.

- Dann will man ja, dass dieser TcpServer auf dem Port hören kann. Dazu habe ich die Methode start (ehemals listen) erstellt:
Da wir hier mit Threads arbeiten wollen, habe ich dazu einfach einen einfachen Thread verwendet, der dann auch in der Klasse gespeichert wird.
-> Wenn es schon einen Thread gibt und dieser noch läuft, dann werfen wir eine Exception. Man kann den TcpServer sozusagen nur einmal starten.
-> Dann wird ein neuer Thread erzeugt, der einfach listenForNewConnections aufruft.

- listenForNewConnections
--> Es wird ein ServerSocket gestartet. Das war zuerst in einem try with resources, so dass der auf jeden Fall sicher geschlossen wird, aber man braucht diesen Socket auch für die close() Methode. Daher wurde das eine Instanzvariable.
--> So lange der ServerSocket nicht geschlossen ist wird in einer Schleife:
----> Auf eine neue Connection gewartet.
----> Für jede Connection wird eine Instanz von TcpServerClient erstellt und in einer Liste von clients verwaltet.

- TcpServer hat Ressourcen intern, die man ggf. schließen können will. Man will ja alles stoppen -> Autoclosable ist da das Interface, das einem in den Sinn kommen soll mit der close Methode. Diese Methode schließt den Socket und auch alle TcpServerClients.


Der TcpServerClient bekommt dann den Socket und auch eine Referenz auf den TcpServer. (Hier wäre ggf. ein Interface interessant. Es wird ja nur eine Schnittstelle benötigt um halt empfangene Nachrichten weiter zu geben und so. Da könnte man dann auch eine Klasse für die Daten übergeben.)
Im Konstruktor wird dann der writer erstellt und der Thread zum lesen von Nachrichten gestartet.

Der Thread erstellt einfach einen Reader und liest immer von diesem. Jede Nachricht wird dem TcpServer signalisiert. (Da kann man auch ein Interface MessageReceiver oder so bauen. Das muss ja nicht der TcpServer sein.)
Unschön ist hier noch: Da wird immer mit einer Exception raus gegangen. Da sollte man einen sauberen Exit ermöglichen. Aber erst einmal für die Kernfunktionalität egal.

Man kann eine Nachricht senden und man hat das close(), das alles schließt.

Das wäre so der grobe Aufbau in einem ersten ganz schnellen Entwurf. Wirklich so herunter geschrieben was man daran merkt, wie massiv die Anpassungen zwischen dem ersten Post und der neuen Überarbeitung sind.
 

Spiderpic98

Mitglied
Wie so eine Server Implementierung etwas aussehen könnte, die mit Threads arbeitet, habe ich einmal auf die Schnelle unter
skizziert.

Ist aber noch nicht getestet und der Client fehlt noch ... Und Nachrichten, die der Server empfängt sendet er einfach an alle (anderen) verbundenen Clients weiter.
Danke für die Antworten! Das Beispiel hilft sehr. Eine Frage hätte ich noch zu dem Client. Im Konstruktor wird einmal der Socket und der Serversocket übergeben. Warum? Der Socket wäre meine Vermutung damit jeder Client auch einen Socket hat durch die Narichten fließen können, aber ich verstehe nicht ganz warum der Serversocket übergeben werden muss?
 

KonradN

Super-Moderator
Mitarbeiter
Also der TcpServerClient ist nicht der Client der Anwendung sondern im TcpServer die Verwaltung eines verbundenen Clients!

Und der Socket wird übergeben, da dieser ja die Verbindung zum Client ist.
Der TcpServer wird übergeben, da dies ja der eigentliche Server ist. Mit den Nachrichten des Servers muss ja irgendwas gemacht werden.

Evtl. hilft es etwas, wenn man das etwas mehr wie Events aufzieht? Dann hätte man sowas wie ein Message das Sender (Object) und Message (String) hat. Und dann hat man ein Interface MessageConsumer, das eine Methode receive(Object) hat. Dann würde TcpServer dieses Interface implementieren und der Parameter wäre dann der MessageConsumer? (Aber halt immer noch diese TcpServer Instanz. Aber wir hätten da die Abhängigkeit schon zu einem Interface gewandelt.

Das kann man auch noch weiter treiben. Der Server muss die TcpServerClient nicht verwalten. Das gehört ja nicht zwangsläufig zu einem TcpServer, der nur die Aufgabe hat, auf neue Verbindungen zu warten. Das kann dann also auch so aussehen:

- ChatServer
--> Hat einen TcpServer der auf neue Verbindungen warten.
--> Hat Clients. Diese Klasse kann sonst was beinhalten. Wenn man IRC als Protokoll anschaut, dann könnte da halt einiges an Informationen gespeichert sein. Aber es hält auch den TcpServerClient als Verbindung.
--> Der ChatServer würde dann halt der MessageConsumer sein.

Das wird dann aber recht viel und das geht halt über eine einfache Struktur für so eine reine ServerSocket Lösung hinaus.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
JavaDevOp Socket Status von UDP-Port prüfen (PortUnreachableException funktioniert nicht?) Netzwerkprogrammierung 32
B Multicast-Nachrichten-Empfang funktioniert nicht Netzwerkprogrammierung 5
G UDP Packet empfangen funktioniert nicht. Netzwerkprogrammierung 16
Dann07 Proxy funktioniert nicht so wie gewünscht! Netzwerkprogrammierung 18
M Textchat Funktioniert nur halb Netzwerkprogrammierung 2
H Einfacher Server funktioniert nicht Netzwerkprogrammierung 1
N Test Servlet funktioniert nicht Netzwerkprogrammierung 11
J FTP Upload über Proxy funktioniert nicht Netzwerkprogrammierung 1
C Mini Client-Server-Anwendung funktioniert nicht Netzwerkprogrammierung 8
KingSquizzi3 Website parsen mit Hilfe von jsoup funktioniert nicht Netzwerkprogrammierung 3
V TCP Client funktioniert auf Emulator aber nicht auf Smartphone Netzwerkprogrammierung 5
N RMI "RMI über Lan funktioniert nicht" & "RMI-Server im Lan scannen" Netzwerkprogrammierung 13
G Mail senden funktioniert nicht mit SSL Netzwerkprogrammierung 7
L IText mit Servlets, funktioniert nicht Netzwerkprogrammierung 0
D TCP Socket funktioniert nicht richtig Netzwerkprogrammierung 3
L Email versenden mit Java funktioniert nicht, Fehlermeldungen: MessagingException & SocketException Netzwerkprogrammierung 10
C Portscanner funktioniert nicht! Netzwerkprogrammierung 8
K Chatprogramm - Server funktioniert nicht Netzwerkprogrammierung 5
G FTP FTP-Client funktioniert nicht bei Modem-Verbindungen Netzwerkprogrammierung 8
D JNLP über Webstart funktioniert nicht... Netzwerkprogrammierung 2
M HTTP File Upload mit Prozessbar Funktioniert nicht. Netzwerkprogrammierung 8
J FTP FTP funktioniert nicht. Netzwerkprogrammierung 5
R Client funktioniert nicht Netzwerkprogrammierung 2
M while-Schleife funktioniert nicht bei Nachrichtempfang von Server Netzwerkprogrammierung 3
L Socket Chat funktioniert nicht Netzwerkprogrammierung 2
D ...class.getResourceAsStream("/meine.properties") funktioniert nicht über RMI? Netzwerkprogrammierung 3
S RMI Methodenaufruf funktioniert nur lokal Netzwerkprogrammierung 11
C Java Chat funktioniert nicht richtig Netzwerkprogrammierung 6
V Quelltaxt einer Website auslesen funktioniert nicht Netzwerkprogrammierung 2
A RMI RMI Methodenaufruf funktioniert nur spontan Netzwerkprogrammierung 5
S RMI RMI-Applet kommunikation funktioniert nicht Netzwerkprogrammierung 8
D FTP Pfadangabe für ftp-upload funktioniert nicht Netzwerkprogrammierung 5
A Socket UnknownHostException funktioniert nicht! Netzwerkprogrammierung 3
B Socket Daten empfangen funktioniert nicht richtig - wo liegt der Fehler? Netzwerkprogrammierung 7
M chat funktioniert nicht (Connection refused: connect) Netzwerkprogrammierung 3
R Java-Chat-Applet funktioniert nur in Eclipse Netzwerkprogrammierung 3
T RMI - Client Zugriff auf Server funktioniert nicht Netzwerkprogrammierung 5
M RMI, cast funktioniert nich Netzwerkprogrammierung 2
P Bilder: FTP-Upload funktioniert nicht richtig Netzwerkprogrammierung 2
G Datein versenden funktioniert nicht ! Netzwerkprogrammierung 19
W RMI funktioniert nur wenn ich im selben Eclipse Projekt bin Netzwerkprogrammierung 3
S OutputStreamWriter funktioniert nicht wie ich will Netzwerkprogrammierung 2
M serialisierung funktioniert nur nach neuer instanzierung Netzwerkprogrammierung 3
G Google-Suche funktioniert nicht Netzwerkprogrammierung 6
S Server - Telnet funktioniert, Server - Client nicht Netzwerkprogrammierung 3
F SimpleFTP funktioniert nicht Netzwerkprogrammierung 6
N UDP zwischen Java und C++ funktioniert nicht. Netzwerkprogrammierung 4
L JavaMail: Versenden von mails funktioniert nicht Netzwerkprogrammierung 7
A Bei FTP Übertragung wird Datei nicht komplett übertragen Netzwerkprogrammierung 2
M JAX-WS unter Java 17 plötzlich nicht mehr möglich Netzwerkprogrammierung 5
T OutputStream kommt nicht an Netzwerkprogrammierung 18
L30nS RMI RMI-Server kann Dialog nicht volkommen anzeigen Netzwerkprogrammierung 2
L Server-Socket liest Input-Stream nicht Netzwerkprogrammierung 5
Tobero Java serversocket nicht nur zuganglich für localhost Netzwerkprogrammierung 6
T String von Client zu Server kommt nicht an Netzwerkprogrammierung 92
S .jar läuft local, aber nicht remote (SSH/Terminal) Netzwerkprogrammierung 10
Z Kann nicht Daten vom Server lesen Socket Netzwerkprogrammierung 10
J SSL haut nicht hin Netzwerkprogrammierung 3
A Socket-Anwendung (BufferedWriter/Reader liest nicht aktuellen Wert) Netzwerkprogrammierung 6
platofan23 Socket Java Socket mit DynDns nicht erreichbar Netzwerkprogrammierung 6
J Wechsel auf Jdk13 , sfpt funktionier nicht mehr Netzwerkprogrammierung 2
B RESTful API weiß nicht weiter Netzwerkprogrammierung 2
L Kann VM nicht ueber Host Name finden Netzwerkprogrammierung 0
V Ich finde den Fehler nicht... Netzwerkprogrammierung 2
T HTTPS-Requests an Server: POST-Parameter kommen nicht an Netzwerkprogrammierung 5
S Socket Webserver mit SSLSocket geht nicht Netzwerkprogrammierung 1
P RMI stub wird nicht gefunden Netzwerkprogrammierung 8
M com.google.gson wird nicht erkannt Netzwerkprogrammierung 2
M Socket Server antwortet dem Client nicht Netzwerkprogrammierung 6
D FTP ListNames() funktinoniert nicht richtig Netzwerkprogrammierung 2
Thallius JDBC getConnection kommt nicht zurück Netzwerkprogrammierung 1
J Java Server empfängt php inhalt nicht Netzwerkprogrammierung 1
P RMI - Neue eigene Instanz für jeden Aufruf auf nicht serialisierbares Objekt - wie? Netzwerkprogrammierung 0
F FTP FTPClient Datei lässt sich nicht öffnen Netzwerkprogrammierung 4
F Reader/ Writer werden nicht geschlossen Netzwerkprogrammierung 2
Z Verbindung zwischen 2 Rechnern über ServerSockets nicht möglich Netzwerkprogrammierung 3
F Java Server Scanner oder InputStream kann nicht gelsesen werden! Netzwerkprogrammierung 6
R Socket bei server.accept(); gehts nicht weiter Netzwerkprogrammierung 2
K Server liest Daten nicht Netzwerkprogrammierung 6
E Gruppenchat: Über HTTPS oder nicht? Netzwerkprogrammierung 5
P nanoHttp upload.html page lädt nicht Netzwerkprogrammierung 4
M Byte Array kommt nicht an Netzwerkprogrammierung 0
X Daten können nicht sofort empfangen werden Netzwerkprogrammierung 1
K ByteArray über Netzwerk senden klappt nicht Netzwerkprogrammierung 5
D Socket UDP Client reagiert nicht auf spontane Meldungen Netzwerkprogrammierung 5
C Servlet erstellen klappt nicht Netzwerkprogrammierung 3
A Socket Socket-Problem - Object wird nicht übertragen Netzwerkprogrammierung 3
S Socket (client) verbindet nicht Netzwerkprogrammierung 6
B Methoden und Konstruktoren von Java.net package werden nicht geladen Netzwerkprogrammierung 2
L Server anpingen (Pingzeit) ?? Pingzeit wird nicht verändert Netzwerkprogrammierung 6
M JSP wird im gesamten Projekt nicht neugeladen Netzwerkprogrammierung 3
B HTTP Webseite unter IP-Addresse nicht aufrufbar - unter Domain schon Netzwerkprogrammierung 9
A Socket ASCii Zeichen werden nicht per udp übermittelt. please help . Netzwerkprogrammierung 6
J Erster Server-Client läuft auf lokalem Rechner problemlos. Zwei Rechner über das Internet nicht Netzwerkprogrammierung 8
H HTTP Header Response kann nicht ausgelesen werden Netzwerkprogrammierung 4
K Socket InputStream wird nicht erzeugt Netzwerkprogrammierung 4
R Socket SSL-Connect in Servlet - keystore wird nicht gefunden Netzwerkprogrammierung 2
V Socket Objekte werden nicht aktualisiert Netzwerkprogrammierung 2
F Kann Klasse nicht zu Servlet casten Netzwerkprogrammierung 5
T Server und Client verbinden nicht Netzwerkprogrammierung 6

Ähnliche Java Themen

Neue Themen


Oben