So, I made a simple server-client chat program, but I have a problem:
if the server tries to message the client, the server lags or freezes a bit, same with the client.
is there something that I do wrong?

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

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class Server extends Application {

    private Group serverGR;
    private Scene serverSC;
    private Stage window;
    private TextField tf;
    private TextArea ta;

    private ServerSocket ss;
    private Socket s;
    private DataInputStream dis;
    private DataOutputStream dos;

    ConnectionThread cT = new ConnectionThread();

    public void init() {
        cT.start();
    }

    @Override
    public void start(Stage primaryStage) {
        try {
        serverGR = new Group();
        serverSC = new Scene(serverGR, 800, 500, Color.LIGHTCYAN);
        window = primaryStage;
        window.setTitle("Bleidorb Simplistic ChatProgram \\\\\\\\\"ServerMode\"\\\\\\\\");
        window.setScene(serverSC);
        window.show();

        tf = new TextField();
        tf.setTranslateX(10);
        tf.setTranslateY(10);
        tf.setPrefWidth(400);
        tf.setPrefHeight(20);
        tf.appendText("Type your message here.");
        tf.setOnAction(event -> {

            String server = "Server: ";
            server += tf.getText();

                try {
                    dos.writeUTF(server);
                    dos.flush();
                    ta.appendText(dis.readUTF() + "\n");
                } catch (IOException e) {
                    e.printStackTrace();
                }

            tf.clear();

        });

        ta = new TextArea();
        ta.setTranslateX(10);
        ta.setTranslateY(40);
        ta.setPrefWidth(400);
        ta.setPrefHeight(400);

        serverGR.getChildren().addAll(tf, ta);
        } catch (Exception e) {
            System.out.println(e.toString() + "\n something wrong in startmethod, lol?");
        }
    }   

    @SuppressWarnings("deprecation")
    public void stop() {
        try {
            cT.stop();
            dis.close();
            ss.close();
            s.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }

    private class ConnectionThread extends Thread {

        @Override
        public void run(){
            try {
                ss = new ServerSocket(5279, 100);
                s = ss.accept();
                s.setTcpNoDelay(true);
                dis = new DataInputStream(s.getInputStream());
                dos = new DataOutputStream(s.getOutputStream());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

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

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class Client extends Application {

    private Group serverGR;
    private Scene serverSC;
    private Stage window;
    private TextField tf;
    private TextArea ta;

    private Socket s;
    private DataInputStream dis;
    private DataOutputStream dos;

    ConnectionThread cT = new ConnectionThread();

    public void init() {
        cT.start();
    }

    @Override
    public void start(Stage primaryStage) {
        try {
        serverGR = new Group();
        serverSC = new Scene(serverGR, 800, 500, Color.LIGHTCYAN);
        window = primaryStage;
        window.setTitle("Bleidorb Simplistic ChatProgram \\\\\\\\\"ClientMode\"\\\\\\\\");
        window.setScene(serverSC);
        window.show();

        tf = new TextField();
        tf.setTranslateX(10);
        tf.setTranslateY(10);
        tf.setPrefWidth(400);
        tf.setPrefHeight(20);
        tf.appendText("Type your message here.");
        tf.setOnAction(event -> {

            String client = "Client: ";
            client += tf.getText();

                try {
                    dos.writeUTF(client);
                    dos.flush();
                    ta.appendText(dis.readUTF() + "\n");
                } catch (IOException e) {
                    e.printStackTrace();
                }

            tf.clear(); 

        });

        ta = new TextArea();
        ta.setTranslateX(10);
        ta.setTranslateY(40);
        ta.setPrefWidth(400);
        ta.setPrefHeight(400);

        serverGR.getChildren().addAll(tf, ta);
        } catch (Exception e) {
            System.out.println(e.toString() + "\n something wrong in startmethod, lol?");
        }
    }   

    @SuppressWarnings("deprecation")
    public void stop() {
        try {
            cT.stop();
            dos.close();
            s.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }

    private class ConnectionThread extends Thread {

        @Override
        public void run(){
            try {
                s = new Socket("localhost", 5279);
                s.setTcpNoDelay(true);
                dis = new DataInputStream(s.getInputStream());
                dos = new DataOutputStream(s.getOutputStream());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

Recommended Answers

All 14 Replies

Looks like a design problem around when you read the input from the ObjectInputStreams - you only try to read them after sending something. So the client can send something but the server won't respond until something is typed a the server.

The way this is normally done is to have a new thread (yes, more threading!) that sits in a loop waiting for input from the ObjectInputStream and copying whatever it receives to the user interface text field. You do that in both the server and the client. Then whenever you send anything, in either direction, the message is received and processed immediatly.

ps: You don't need a ConnectionThread for the Client's connection. The client must make a connection straight away and cannot do anything else until the connection is made, so that doesn't need a separete thread.

commented: I just need to loop this: ta.appendText(dis.readUTF() + "\n"); right? +0

I just need to loop this: ta.appendText(dis.readUTF() + "\n"); right?

Yes, but it has to be in its own thread so it doesn't block everything else.

Little thread tutorial....

Creating a subclass of Thread (as in your code above) is perfectly valid but most people would not recommend it... by extending Thread you remove any possibility of extending anything else. And it's just not good design - the subclass is NOT a kind of Thread, it's a thing that can be executed in a Thread. In general it's much better to make your code a Runnable (ie has a run()method) and pass that to a Thread for execution. eg

private class ConnectionHandler implements Runnable {

        @Override
        public void run(){
            etc etc

...

 new Thread(new ConnectionHandler()).start();

But even better, if you have got as far as lambdas in Java, you can bypass creating a new class altogether and just have a simple method, eg

public void connectionListener() {
    try {
        s = new Socket("localhost", 5279);
        etc etc

new Thread(this::connectionListener).start();

the client does not get the server message, what went wrong?
btw I used the "implements Runnable" (:
I don't know how to fully use lambdas, I read this: https://www.freecodecamp.org/news/learn-these-4-things-and-working-with-lambda-expressions-b0ab36e0fffc/
rn, I am not really focusing on lambdas, it's nice to know, I will make a seperate project to test it out, but there is something wrong with the client input, (that gets the server messages from the server) ,or the server output, (that sends the server messages to the client). I don't know if for loop is making some problems, I just have a feeling of it, but I don't know why?

btw here is my code:

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

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class Server extends Application {

    private Group serverGR;
    private Scene serverSC;
    private Stage window;
    private TextField tf;
    private TextArea ta;

    private ServerSocket ss;
    private Socket s;
    private DataInputStream dis;
    private DataOutputStream dos;

    ConnectionThread cT = new ConnectionThread();

    public void init() {
        new Thread(new ConnectionThread()).start();
    }

    @Override
    public void start(Stage primaryStage) {
        try {
            serverGR = new Group();
            serverSC = new Scene(serverGR, 800, 500, Color.LIGHTCYAN);
            window = primaryStage;
            window.setTitle("Bleidorb Simplistic ChatProgram \\\\\\\\\"ServerMode\"\\\\\\\\");
            window.setScene(serverSC);
            window.show();

            tf = new TextField();
            tf.setTranslateX(10);
            tf.setTranslateY(10);
            tf.setPrefWidth(400);
            tf.setPrefHeight(20);
            tf.appendText("Type your message here.");
            tf.setOnAction(event -> {

                String server = "Server: ";
                server += tf.getText();
                try {
                    dos.writeUTF(server);
                    ta.appendText(server + "\n");
                    // ta.appendText(dis.readUTF() + "\n");
                    dos.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                tf.clear();
            });

            ta = new TextArea();
            ta.setTranslateX(10);
            ta.setTranslateY(40);
            ta.setPrefWidth(400);
            ta.setPrefHeight(400);

            serverGR.getChildren().addAll(tf, ta);
        } catch (Exception e) {
            System.out.println(e.toString() + "\n something wrong in startmethod, lol?");
        }
    }

    @SuppressWarnings("deprecation")
    public void stop() {
        try {
            new Thread(new ConnectionThread()).stop();
            dis.close();
            ss.close();
            s.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }

    private class ConnectionThread implements Runnable {

        @Override
        public void run() {
            try {
                ss = new ServerSocket(5279, 100);
                s = ss.accept();
                s.setTcpNoDelay(true);
                dis = new DataInputStream(s.getInputStream());
                dos = new DataOutputStream(s.getOutputStream());

                for (;;) {
                    System.out.println("server test input");
                    ta.appendText(dis.readUTF() + "\n");
                }

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

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

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class Client extends Application {

    private Group serverGR;
    private Scene serverSC;
    private Stage window;
    private TextField tf;
    private TextArea ta;

    private Socket s;
    private DataInputStream dis;
    private DataOutputStream dos;

    public void init() {
        try {
            s = new Socket("localhost", 5279);
            s.setTcpNoDelay(true);
            dis = new DataInputStream(s.getInputStream());
            dos = new DataOutputStream(s.getOutputStream());
            new Thread(new ConnectionThread()).start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void start(Stage primaryStage) {
        try {
            serverGR = new Group();
            serverSC = new Scene(serverGR, 800, 500, Color.LIGHTCYAN);
            window = primaryStage;
            window.setTitle("Bleidorb Simplistic ChatProgram \\\\\\\\\"ClientMode\"\\\\\\\\");
            window.setScene(serverSC);
            window.show();

            tf = new TextField();
            tf.setTranslateX(10);
            tf.setTranslateY(10);
            tf.setPrefWidth(400);
            tf.setPrefHeight(20);
            tf.appendText("Type your message here.");
            tf.setOnAction(event -> {

                String client = "Client: ";
                client += tf.getText();

                try {
                    dos.writeUTF(client);
                    ta.appendText(client + "\n");
                    // ta.appendText(dis.readUTF() + "\n");
                    dos.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                tf.clear();
            });

            ta = new TextArea();
            ta.setTranslateX(10);
            ta.setTranslateY(40);
            ta.setPrefWidth(400);
            ta.setPrefHeight(400);

            serverGR.getChildren().addAll(tf, ta);
        } catch (Exception e) {
            System.out.println(e.toString() + "\n something wrong in startmethod, lol?");
        }
    }

    @SuppressWarnings("deprecation")
    public void stop() {
        try {
            new Thread(new ConnectionThread()).stop();
            dos.close();
            s.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }

    private class ConnectionThread implements Runnable {

        @Override
        public void run() {
            try {
                for (;;) {
                    System.out.println("client test input");
                    ta.appendText(dis.readUTF() + "\n");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

ignore the code above please, I forgot that I can use one class instead of two, just for the "implements runnable".
let me simplify this code.

much better code here
I just don't see the server message in the client program

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

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class Server extends Application implements Runnable {

    private Group serverGR;
    private Scene serverSC;
    private Stage window;
    private TextField tf;
    private TextArea ta;

    private ServerSocket ss;
    private Socket s;
    private DataInputStream dis;
    private DataOutputStream dos;

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

    @Override
    public void start(Stage primaryStage) {
        try {
            serverGR = new Group();
            serverSC = new Scene(serverGR, 800, 500, Color.LIGHTCYAN);
            window = primaryStage;
            window.setTitle("Bleidorb Simplistic ChatProgram \\\\\\\\\"ServerMode\"\\\\\\\\");
            window.setScene(serverSC);
            window.show();

            tf = new TextField();
            tf.setTranslateX(10);
            tf.setTranslateY(10);
            tf.setPrefWidth(400);
            tf.setPrefHeight(20);
            tf.appendText("Type your message here.");
            tf.setOnAction(event -> {

                String server = "Server: ";
                server += tf.getText();
                try {
                    dos.writeUTF(server);
                    ta.appendText(server + "\n");
                    // ta.appendText(dis.readUTF() + "\n");
                    dos.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                tf.clear();
            });

            ta = new TextArea();
            ta.setTranslateX(10);
            ta.setTranslateY(40);
            ta.setPrefWidth(400);
            ta.setPrefHeight(400);

            serverGR.getChildren().addAll(tf, ta);
        } catch (Exception e) {
            System.out.println(e.toString() + "\n something wrong in startmethod, lol?");
        }
    }

    @SuppressWarnings("deprecation")
    public void stop() {
        try {
            new Thread(this).stop();
            dis.close();
            ss.close();
            s.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void run() {
        try {
            ss = new ServerSocket(5279, 100);
            s = ss.accept();
            s.setTcpNoDelay(true);
            dis = new DataInputStream(s.getInputStream());
            dos = new DataOutputStream(s.getOutputStream());

            for (;;) {
                System.out.println("server test input");
                ta.appendText(dis.readUTF() + "\n");
            }

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

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

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class Client extends Application implements Runnable {

    private Group serverGR;
    private Scene serverSC;
    private Stage window;
    private TextField tf;
    private TextArea ta;

    private Socket s;
    private DataInputStream dis;
    private DataOutputStream dos;

    public void init() {
        try {
            s = new Socket("localhost", 5279);
            s.setTcpNoDelay(true);
            dis = new DataInputStream(s.getInputStream());
            dos = new DataOutputStream(s.getOutputStream());
            new Thread(this).start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void start(Stage primaryStage) {
        try {
            serverGR = new Group();
            serverSC = new Scene(serverGR, 800, 500, Color.LIGHTCYAN);
            window = primaryStage;
            window.setTitle("Bleidorb Simplistic ChatProgram \\\\\\\\\"ClientMode\"\\\\\\\\");
            window.setScene(serverSC);
            window.show();

            tf = new TextField();
            tf.setTranslateX(10);
            tf.setTranslateY(10);
            tf.setPrefWidth(400);
            tf.setPrefHeight(20);
            tf.appendText("Type your message here.");
            tf.setOnAction(event -> {

                String client = "Client: ";
                client += tf.getText();

                try {
                    dos.writeUTF(client);
                    ta.appendText(client + "\n");
                    // ta.appendText(dis.readUTF() + "\n");
                    dos.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                tf.clear();
            });

            ta = new TextArea();
            ta.setTranslateX(10);
            ta.setTranslateY(40);
            ta.setPrefWidth(400);
            ta.setPrefHeight(400);

            serverGR.getChildren().addAll(tf, ta);
        } catch (Exception e) {
            System.out.println(e.toString() + "\n something wrong in startmethod, lol?");
        }
    }

    @SuppressWarnings("deprecation")
    public void stop() {
        try {
            new Thread(this).stop();
            dos.close();
            s.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void run() {
        try {
            for (;;) {
                System.out.println("client test input");
                ta.appendText(dis.readUTF() + "\n");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

You are not giving much info to help debug this. Please explain exactly what the test procedure was and exactly what messages were (or were not) displayed.

so I run the Server Program then the Client Program and when I type something in the server textfield and press enter, I get a error inside the Client Class.

client test input
java.lang.NullPointerException
    at com.VINSTORM.bleidorb.ZcommunicationTestServerV4.main.Client.run(Client.java:104)
    at java.lang.Thread.run(Unknown Source)

Client.java:104 =

                ta.appendText(dis.readUTF() + "\n");

when I type something in the server and press enter in the textfield, it displayed in the server program, but not in the client program.

when I type something in the client and press enter in the textfield, it displayed in the server and client program, this one works fine.

server -> client (message not displayed on client, message displayed only on server)
client -> server (message displayed on both programs)

For future reference: If you are asking for help with a problem and you have an Exception message... TELL US ABOUT IT!
It's the single most important piece of information and you have to share it with us.

NPE in line 104. There are only two variables that can be null on that line, ta and dis.
So either the text area or the input stream has not been initialised when that line is executed.
Let's halve the problem by finding out which it is. Print them both immediately before line104. The fact that the client -> server case works suggests that the text area is ok, but its still best to test that assumption.

Look at the startup process for a JavaFX app, in particular the difference between init and start and the order in which they are called. I sense a confusion about which code should be in which method.

(ps: The fact that client to server is working means you have successfully implemented 99 % of the difficult stuff. Well done.)

I was kinda stuck, but I finally got it. I just forgot that the thread starts first then the initialize.
it is now fixed. Here is the complete code:

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

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class Server extends Application implements Runnable {

    private Group serverGR;
    private Scene serverSC;
    private Stage window;
    private TextField tf;
    private TextArea ta;

    private ServerSocket ss;
    private Socket s;
    private DataInputStream dis;
    private DataOutputStream dos;

    public void init() {

    }

    @Override
    public void start(Stage primaryStage) {
        try {
            serverGR = new Group();
            serverSC = new Scene(serverGR, 800, 500, Color.LIGHTCYAN);
            window = primaryStage;
            window.setTitle("Bleidorb Simplistic ChatProgram \\\\\\\\\"ServerMode\"\\\\\\\\");
            window.setScene(serverSC);
            window.show();

            tf = new TextField();
            tf.setTranslateX(10);
            tf.setTranslateY(10);
            tf.setPrefWidth(400);
            tf.setPrefHeight(20);
            tf.appendText("Type your message here.");
            tf.setOnAction(event -> {

                String server = "Server: ";
                server += tf.getText();
                try {
                    dos.writeUTF(server);
                    ta.appendText(server + "\n");
                    // ta.appendText(dis.readUTF() + "\n");
                    dos.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                tf.clear();
            });

            ta = new TextArea();
            ta.setTranslateX(10);
            ta.setTranslateY(40);
            ta.setPrefWidth(400);
            ta.setPrefHeight(400);

            serverGR.getChildren().addAll(tf, ta);

            try {
                new Thread(this).start();
                } catch (Exception e) {
                    e.printStackTrace();
                }

        } catch (Exception e) {
            System.out.println(e.toString() + "\n something wrong in startmethod, lol?");
        }
    }

    @SuppressWarnings("deprecation")
    public void stop() {
        try {
            new Thread(this).stop();
            dis.close();
            ss.close();
            s.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void run() {
        try {
            ss = new ServerSocket(5279, 100);
            s = ss.accept();
            s.setTcpNoDelay(true);
            dis = new DataInputStream(s.getInputStream());
            dos = new DataOutputStream(s.getOutputStream());

            for (;;) {
                System.out.println("server test input");
                ta.appendText(dis.readUTF() + "\n");
            }

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

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

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class Client extends Application implements Runnable {

    private Group serverGR;
    private Scene serverSC;
    private Stage window;
    private TextField tf;
    private TextArea ta;

    private Socket s;
    private DataInputStream dis;
    private DataOutputStream dos;

    public void init() throws IOException {
        try {
        s = new Socket("192.168.2.145", 5279);
        s.setTcpNoDelay(true);
        dis = new DataInputStream(s.getInputStream());
        dos = new DataOutputStream(s.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void start(Stage primaryStage) {
        try {
            serverGR = new Group();
            serverSC = new Scene(serverGR, 800, 500, Color.LIGHTCYAN);
            window = primaryStage;
            window.setTitle("Bleidorb Simplistic ChatProgram \\\\\\\\\"ClientMode\"\\\\\\\\");
            window.setScene(serverSC);
            window.show();

            tf = new TextField();
            tf.setTranslateX(10);
            tf.setTranslateY(10);
            tf.setPrefWidth(400);
            tf.setPrefHeight(20);
            tf.appendText("Type your message here.");
            tf.setOnAction(event -> {

                String client = "Client: ";
                client += tf.getText();

                try {
                    dos.writeUTF(client);
                    ta.appendText(client + "\n");
                    // ta.appendText(dis.readUTF() + "\n");
                    dos.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                tf.clear();
            });

            ta = new TextArea();
            ta.setTranslateX(10);
            ta.setTranslateY(40);
            ta.setPrefWidth(400);
            ta.setPrefHeight(400);

            serverGR.getChildren().addAll(tf, ta);

            try {
                new Thread(this).start();
            } catch (Exception e) {
                e.printStackTrace();
            }

        } catch (Exception e) {
            System.out.println(e.toString() + "\n something wrong in startmethod, lol?");
        }
    }

    @SuppressWarnings("deprecation")
    public void stop() {
        try {
            new Thread(this).stop();
            dos.close();
            s.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void run() {
        try {
            for (;;) {
                System.out.println("client test input");
                ta.appendText(dis.readUTF() + "\n");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

of course, I can make this code much better and modify in a real world application, but I now know how to use this (:
now what I have to learn is how to use this with different routers, not just my local router :think:

Well done! Thats not an easy project.

One bug I noticed still outstanding
new Thread(this).stop();
creates a new Thread and stops it (null op because it was never started)

If you want to stop the threads you started earlier you need to keep track of them, eg

Thread thead1 = new Thread(myRunnable);
thread1.start();
...
thread1.stop();

(Thread.stop is deprecated, but if you are doing it as part of a shutdown then you should be OK.)

how can I make it that another client can join in?
like there is 2 clients and 1 server.
do I just copy the clients code?

No. You just start the same client code twice, or as many times as you want for many clients.
But you do have to enhance the server code to keep track of the clients, and keep separate data input/output streams open for each client, and have separate threads waiting for input from each client.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.