# Chatserver/-client - Code stoppt bei readUTF()



## Avo_MODE (14. Nov 2017)

Hallo erstmal.

Wie im Titel erwähnt, arbeite ich an einem Programm, das einen ChatServer und ChatClient enthält.
Ich habe bei meinen "Problemzeilen" folgenden Code gesetzt, damit ich weiß, wann der Code aufhört.

```
System.out.println("1");
String line = streamIn.readUTF(); < Fehler
System.out.println("2"); < das wird nicht mehr in der Konsole ausgegeben
...
```

Ich habe 2 Projekte, ChatClient und ChatServer.
Klassen:
ChatClient:
- Client.java
- ClientGUI.java 
ChatServer:
- Server.java
- ServerGUI.java
- ServerClient.java

Achtet bei eurer Antwort darauf, mein Problem zu lösen und nicht mich auf meiner komplizierten Weise meines Codes zuzuweißen (Threads, Timers, etc.).

Hier die Codes:
Client.java (enthält den Fehler)

```
package me.avo.chat;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.JEditorPane;

public class Client {

    private Socket socket = null;
    private DataOutputStream streamOut = null;
    private DataInputStream streamIn = null;

    private String clientName = "";

    public Client(String clientName, String serverName, int serverPort) {
        this.clientName = clientName;
        try {
            socket = new Socket(serverName, serverPort);
            start();
        } catch (UnknownHostException uhe) {
            System.out.println("Host unknown: " + uhe.getMessage());
        } catch (IOException ioe) {
            System.out.println("Unexpected exception: " + ioe.getMessage());
        }
    }

    public DataInputStream getInputStream() {
        return streamIn;
    }

    public void handleChat(final JEditorPane dtrpnLogs) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Running");
                try {
                    try {
                        String line = streamIn.readUTF();
                        System.out.println("Received message");
                        dtrpnLogs.setText(dtrpnLogs.getText() + "\n" + line);
                    } catch (EOFException ex) {
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
    }

    public void sendMessage(String message) {
        try {
            System.out.println("Sending \"" + this.clientName + "> " + message + "\"");
            streamOut.writeUTF(this.clientName + ": " + message);
            streamOut.flush();
            System.out.println("Sent to streamOut");
        } catch (IOException ioe) {
            System.out.println("Sending error: " + ioe.getMessage());
        }
    }

    public void start() throws IOException {
        streamIn = new DataInputStream(socket.getInputStream());
        streamOut = new DataOutputStream(socket.getOutputStream());
    }

    public void stop() {
        try {
            if (streamIn != null)
                streamIn.close();
            if (streamOut != null)
                streamOut.close();
            if (socket != null)
                socket.close();
        } catch (IOException ioe) {
            System.out.println("Error closing ...");
        }
    }

}
```

ClientGUI.java

```
package me.avo.chat;

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTextField;

public class ClientGUI {

    private JFrame frame;
    private JTextField textField;
    private JTextField textField_1;
    private JTextField message;
    private Client client;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    ClientGUI window = new ClientGUI();
                    window.frame.setVisible(true);
                    window.frame.setTitle("ChatClient");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public ClientGUI() {
        initialize();
    }

    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 425, 400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);

        JLabel lblHostname = new JLabel("Hostname");
        lblHostname.setBounds(10, 11, 56, 14);
        frame.getContentPane().add(lblHostname);

        JLabel lblPort = new JLabel("Port");
        lblPort.setBounds(106, 11, 46, 14);
        frame.getContentPane().add(lblPort);

        JLabel lblUsername = new JLabel("Username");
        lblUsername.setBounds(186, 11, 56, 14);
        frame.getContentPane().add(lblUsername);

        textField = new JTextField();
        textField.setBounds(10, 30, 86, 20);
        frame.getContentPane().add(textField);
        textField.setColumns(10);

        final JSpinner spinner = new JSpinner();
        spinner.setBounds(106, 30, 70, 20);
        frame.getContentPane().add(spinner);

        textField_1 = new JTextField();
        textField_1.setBounds(186, 30, 86, 20);
        frame.getContentPane().add(textField_1);
        textField_1.setColumns(10);

        JScrollPane scrollPane = new JScrollPane();
        scrollPane.setBounds(10, 61, 389, 242);
        frame.getContentPane().add(scrollPane);

        final JEditorPane dtrpnLogs = new JEditorPane();
        dtrpnLogs.setText("Logs");
        scrollPane.setViewportView(dtrpnLogs);

        final JButton btnLogin = new JButton("Login");
        btnLogin.setBounds(282, 29, 117, 23);
        btnLogin.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                btnLogin.setEnabled(false);
                Thread thread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        client = new Client(textField_1.getText(), textField.getText(),
                                Integer.parseInt(String.valueOf(spinner.getValue())));
                        try {
                            client.start();
                            btnLogin.setText("Logged in");
                            Timer timer = new Timer();
                            timer.scheduleAtFixedRate(new TimerTask() {
                                @Override
                                public void run() {
                                    client.handleChat(dtrpnLogs);
                                }
                            }, 1000, 1000);
                        } catch (IOException e1) {
                            btnLogin.setEnabled(true);
                            e1.printStackTrace();
                        }
                    }
                });
                thread.start();
            }
        });
        frame.getContentPane().add(btnLogin);

        message = new JTextField();
        message.setBounds(10, 314, 250, 39);
        frame.getContentPane().add(message);
        message.setColumns(10);

        JButton btnSend = new JButton("Send Message");
        btnSend.setBounds(270, 314, 129, 39);
        btnSend.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Sending message..");
                client.sendMessage(message.getText());
                message.setText("");
                System.out.println("Message sent!");
            }
        });
        frame.getContentPane().add(btnSend);
    }

}
```

Server.java

```
package me.avo.chat;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

public class Server {

    private ServerSocket server;

    private ArrayList<ServerClient> connectedClients = new ArrayList<>();

    private int port;

    private Server(int port) {
        this.port = port;
    }

    public static Server newServer(int port) {
        return new Server(port);
    }

    public ArrayList<ServerClient> getConnectedClients() {
        return connectedClients;
    }

    public void sendToAll(String line) {
        try {
            for (ServerClient ss : connectedClients) {
                if (!ss.isConnected()) {
                    connectedClients.remove(ss);
                    System.out.println("Couldn't send to " + ss.getSocket());
                    continue;
                }
                ss.sendMessage(line);
                System.out.println("Sent to " + ss.getSocket());
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void waitForClients() {
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println("Runned timer");
                try {
                    Socket socket = server.accept();
                    final ServerClient client = new ServerClient(socket);
                    if (client != null) {
                        ServerGUI.getLogPane().setText(
                                ServerGUI.getLogPane().getText() + "\nClient connected: " + client.getSocket());
                        Thread thread = new Thread(new Runnable() {
                            @Override
                            public void run() {
                                client.chatHandle();
                            }
                        });
                        thread.start();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }, 1000, 1000);
    }

    public boolean start() {
        try {
            server = new ServerSocket(port);
            return true;
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        }
    }

}
```

ServerGUI.java

```
package me.avo.chat;

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;

public class ServerGUI {

    private JFrame frmChatserver;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    ServerGUI window = new ServerGUI();
                    window.frmChatserver.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public ServerGUI() {
        initialize();
    }

    private static JEditorPane dtrpnLogs;

    private static Server pbl_server;

    public static JEditorPane getLogPane() {
        return dtrpnLogs;
    }

    public static Server getServer() {
        return pbl_server;
    }

    private void initialize() {
        frmChatserver = new JFrame();
        frmChatserver.setTitle("ChatServer");
        frmChatserver.setBounds(100, 100, 450, 400);
        frmChatserver.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmChatserver.getContentPane().setLayout(null);

        JLabel lblPort = new JLabel("Port");
        lblPort.setBounds(10, 11, 46, 14);
        frmChatserver.getContentPane().add(lblPort);

        final JSpinner txtPort = new JSpinner();
        txtPort.setBounds(66, 8, 86, 20);
        frmChatserver.getContentPane().add(txtPort);

        JScrollPane scrollPane = new JScrollPane();
        scrollPane.setBounds(10, 36, 414, 317);
        frmChatserver.getContentPane().add(scrollPane);

        dtrpnLogs = new JEditorPane();
        dtrpnLogs.setText("Logs");
        scrollPane.setViewportView(dtrpnLogs);

        final JButton btnStartChatserver = new JButton("Start Chatserver");
        btnStartChatserver.setBounds(162, 7, 262, 23);
        btnStartChatserver.addActionListener(new ActionListener() {
            Thread thread;

            @SuppressWarnings("deprecation")
            @Override
            public void actionPerformed(ActionEvent e) {
                if (btnStartChatserver.getText().equals("Start Chatserver")) {
                    btnStartChatserver.setText("Stop Chatserver");
                    final int port = (int) txtPort.getValue();
                    thread = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            final Server server = Server.newServer(port);
                            server.start();
                            pbl_server = server;
                            dtrpnLogs.setText(dtrpnLogs.getText() + "\nServer started at port " + port);
                            Thread waitFor = new Thread(new Runnable() {
                                @Override
                                public void run() {
                                    server.waitForClients();
                                }
                            });
                            waitFor.start();
                        }
                    });
                    thread.start();
                } else {
                    btnStartChatserver.setText("Start Chatserver");
                    if (thread != null)
                        thread.stop();
                    dtrpnLogs.setText(dtrpnLogs.getText() + "\nServer stopped");
                }
            }
        });
        frmChatserver.getContentPane().add(btnStartChatserver);
    }
}
```

ServerClient.java

```
package me.avo.chat;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

public class ServerClient {

    private Socket socket;
    private DataInputStream in;
    private DataOutputStream out;

    public ServerClient(Socket socket) throws IOException {
        this.socket = socket;
        in = new DataInputStream(socket.getInputStream());
        out = new DataOutputStream(socket.getOutputStream());
    }

    public Socket getSocket() {
        return socket;
    }

    public DataOutputStream getOutputStream() {
        return out;
    }

    public DataInputStream getInputStream() {
        return in;
    }

    public boolean isConnected() {
        return !(socket.isClosed());
    }

    public void chatHandle() {
        Timer chat_connectClient = new Timer();
        chat_connectClient.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println("Runned chathandler");
                try {
                    DataInputStream in = getInputStream();
                    String line = null;
                    boolean hasNext = false;
                    try {
                        line = in.readUTF();
                        hasNext = true;
                    } catch (EOFException ex) {
                        line = null;
                        hasNext = false;
                    }
                    if (hasNext) {
                        System.out.println("Received \"" + line + "\"");
                        ServerGUI.getServer().sendToAll(line);
                        ServerGUI.getLogPane().setText(ServerGUI.getLogPane().getText() + "\nLogged message: " + line);
                        System.out.println("Message connected to Clients!");
                    }
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }, 1000, 1000);
    }

    public void sendMessage(String line) {
        try {
            out.writeUTF(line);
            out.flush();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public ArrayList<String> getMessages() {
        try {
            ArrayList<String> messages = new ArrayList<>();
            for (int i = 0; i <= in.available(); i++) {
                messages.add(in.readUTF());
            }
            return messages;
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return null;
    }

}
```

Ich bin für jede Art von Hilfe dankbar.

LG
Avo


----------



## Avo_MODE (14. Nov 2017)

(Ich kann das Thema nicht editieren, deshalb schreibe ich es mal als Antwort)

Mir ist aufgefallen, dass ich das Problem nicht beschrieben habe.



Avo_MODE hat gesagt.:


> Code (Java): System.out.println("1");
> String line = streamIn.readUTF(); < Fehler
> System.out.println("2"); < das wird nicht mehr in der Konsole ausgegeben
> ...


Der markierte Bereich "< Fehler" zeigt die Zeile, indem der Code nicht mehr weitergeht. Hier soll die Chat-Nachricht gelesen werden. Diese wird NUR im Server-Log gesendet, wird aber nicht den einzelnen Clients zugesendet.

Screenshot:


----------



## VfL_Freak (15. Nov 2017)

Moin,


Avo_MODE hat gesagt.:


> Achtet bei eurer Antwort darauf, mein Problem zu lösen und nicht mich auf meiner komplizierten Weise meines Codes zuzuweißen (Threads, Timers, etc.).


ich werde mich hüten ..... 

dann:


Avo_MODE hat gesagt.:


> System.out.println("1");
> String line = streamIn.readUTF(); < Fehler
> System.out.println("2"); < das wird nicht mehr in der Konsole ausgegeben


Wo genau im Code tritt das auf rsp. WO ist diese Zeile?
Aber viel wichtiger: WELCHER Fehler kommt denn?
Poste mal den kompletten StackTrace !

VG Klaus


----------



## Avo_MODE (15. Nov 2017)

VfL_Freak hat gesagt.:


> Moin,
> 
> ich werde mich hüten .....
> 
> ...


Es kommt keine Fehlermeldung. Bei der markierten Zeile "< Fehler" hört der Code au und man die Nachricht nicht aus dem DataInputStream lesen. Warum?


----------



## Avo_MODE (15. Nov 2017)

Ich habe das Problem nun behoben, indem ich mit den Threads und Timern herumgespielt habe.

Trotzdem danke für jegliche Hilfe.

#closerequest - falls es das gibt 

LG Avo


----------



## VfL_Freak (15. Nov 2017)

Moin,
prima 



Avo_MODE hat gesagt.:


> Ich habe das Problem nun behoben, indem ich mit den Threads und Timern herumgespielt habe.


Und warum postet Du dann hier die Lösung nicht für die Nachwelt ?? 
VG Klaus


----------



## Avo_MODE (17. Nov 2017)

VfL_Freak hat gesagt.:


> Moin,
> prima
> 
> 
> ...


Wie gesagt, habe ich mit den Threads und Timern herumgespielt. Deshalb kann ich nicht genau beschreiben, wie ich den Fehler behoben habe. Allerdings ist mir aufgefallen dass der Timer nur einmal aufgerufen worden ist und deshalb keine Nachrichten abgerufen hat. Vielleicht hilft das der Nachwelt c:


----------



## JuKu (17. Nov 2017)

Fürs nächste mal empfehle ich dir eine Library wie Vertx zu verwenden, damit geht das alles deutlich einfacher und du musst dich gar nicht um solche Sachen selbst kümmern.

Wie immer bei diesen Themen poste ich dazu mittlerweile meine beiden Tutorials:

*[Tutorial] Ein Chat Server in Java – Teil 1 / 2*
*[Tutorial] Ein Chat Server in Java – Teil 2 / 2*

Schau dir am besten mal an, wie viel Arbeit einem solch eine Networking Library abnimmt.


----------

