0

What I'm trying to do is make receiver class in the server which receives the sent messages from the client and make a sender class in the client. I'm trying to make the receiver in the server first 'cause I'll probably figure out how to do that in the client side after learning it. But doing this gives me java.net.BindException: Address already in use: JVM_Bind. I think it's because I have another Server server = new Server(); in the receiver. How do I solve this?

Server.java

package MultithreadingServerClient;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class Server {
    ServerSocket serverSocket = new ServerSocket(3000);
    Socket socket = serverSocket.accept();
    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);

    public Server() throws IOException {
    }

    public static void main(String[] args) {
        Thread serverSender = new Thread(new ServerSender());
        Thread serverReceiver = new Thread(new ServerReceiver());
        serverSender.start();
        serverReceiver.start();
    }
}

// Sender class
class ServerSender implements Runnable {

    @Override
    public void run() {
        try {
            Server serve = new Server();
            Scanner scanner = new Scanner(System.in);

            String msg = "";
            while (!msg.equalsIgnoreCase("exit")) {
                System.out.print("Server: ");
                msg = scanner.nextLine();

                serve.printWriter.println(msg);
            }

        } catch (IOException e) {
            System.err.println("Sender Error " + e);
        }
    }
}

class ServerReceiver implements Runnable {
    @Override
    public void run() {
        try {
            Server server = new Server();

            System.out.println(server.bufferedReader.readLine());
        } catch (IOException e) {
            System.err.println("Receiver Error " + e);
        }
    }
}

Client.java

package MultithreadingServerClient;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class Client {
    Socket socket = new Socket("localhost", 3000);
    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    PrintWriter printWriter = new PrintWriter(socket.getOutputStream());

    public Client() throws IOException {
    }

    // Receive messages
    public static void main(String[] args) {
        try {
            Client client = new Client();

            while (true) {
                System.out.println("Server: " + client.bufferedReader.readLine());
            }
        } catch (IOException e) {
            System.out.println("Server Closed!");
        }
    }
}

class ClientSender implements Runnable {
    @Override
    public void run() {
        try {
            Client client = new Client();

            client.printWriter.println("Test message: send to Server");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
Marviuz
  • 21
  • 5
  • Possible duplicate of [How do I resolve the "java.net.BindException: Address already in use: JVM\_Bind" error?](https://stackoverflow.com/questions/12737293/how-do-i-resolve-the-java-net-bindexception-address-already-in-use-jvm-bind) – prithivraj Feb 19 '18 at 09:28
  • does this mean I need a different port to the receiver? – Marviuz Feb 19 '18 at 09:31
  • Don't create multiple instances of `Server`, you may create the instance in `main` then just pass the `bufferedReader` to the receiver class, and the `printWriter` to the sender class. – Arnaud Feb 19 '18 at 09:34
  • how do i do that? – Marviuz Feb 19 '18 at 09:38

2 Answers2

2

Don't create multiple instances of Server, you may create the instance in main then just pass the bufferedReader to the receiver class, and the printWriter to the sender class.

Sender class :

class ServerSender implements Runnable {


    private PrintWriter writer;

    public ServerSender(PrintWriter printWriter){

        writer = printWriter;
    }

    @Override
    public void run() {
        try {

            Scanner scanner = new Scanner(System.in);

            String msg = "";
            while (!msg.equalsIgnoreCase("exit")) {
                System.out.print("Server: ");
                msg = scanner.nextLine();

                writer.println(msg);
            }

        } catch (IOException e) {
            System.err.println("Sender Error " + e);
        }
    }
}

Receiver class :

class ServerReceiver implements Runnable {

    private BufferedReader reader;

    public ServerReceiver(BufferedReader bufferedReader){

       reader = bufferedReader;

    }

    @Override
    public void run() {
        try {

            System.out.println(reader.readLine());
        } catch (IOException e) {
            System.err.println("Receiver Error " + e);
        }
    }
}

Method main in Server :

public static void main(String[] args) {

    Server serve = new Server();
    Thread serverSender = new Thread(new ServerSender(serve.printWriter));
    Thread serverReceiver = new Thread(new ServerReceiver(serve.bufferedReader));
    serverSender.start();
    serverReceiver.start();
}
Arnaud
  • 16,319
  • 3
  • 24
  • 39
0

You have two threads starting a new instance of the connection at the same port (3000). I assume that you are trying to have one thread receive a message from a server and another one for sending a message to client. I don't think you need to have a design like this. This can be done in a single threaded environment. There is no need for client (sender & receiver) and server (sender & receiver).

ServerSocket.accept(); method will listen to all the message incoming to the specified port number.

In order for the server to send reply to the client . You can use DataOutputStream.writeUTF() & DataOutputStream.flush() method.

The same goes for client side. Have a look at the program below.

class Server {
    public static void main(String args[]) throws IOException {
        try (ServerSocket serverSocket = new ServerSocket(3333); // open connection at port 3333
                Socket socket = serverSocket.accept();
                DataInputStream inputStream = new DataInputStream(socket.getInputStream());) {
            DataOutputStream outStream = new DataOutputStream(socket.getOutputStream());
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            String messageFromClient = "", messageToBeClient = "";
            while (!messageFromClient.equals("exit")) {
                messageFromClient = inputStream.readUTF();
                System.out.println("Message From Client :  " + messageFromClient);
                messageToBeClient = reader.readLine();
                outStream.writeUTF(messageToBeClient);
                outStream.flush();
            }
        }
    }
}


class Client {
    public static void main(String args[]) throws Exception {
        try (Socket socket = new Socket("localhost", 3333); // establish connection to the open socket at port 3333
                DataInputStream inputStream = new DataInputStream(socket.getInputStream());) {
            DataOutputStream outStream = new DataOutputStream(socket.getOutputStream());
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            String messageFromServer = "", messageToServer = "";
            while (!messageToServer.equals("exit")) {
                messageToServer = reader.readLine();
                outStream.writeUTF(messageToServer);
                outStream.flush();
                messageFromServer = inputStream.readUTF();
                System.out.println("Message From Server :  " + messageFromServer);
            }
        }
    }
}
prithivraj
  • 71
  • 12
  • Thank you for this answer. We're studying socket programming at school and we're tasked to make a program that communicates to one another using similar approach as the KnockKnockServer program provided by oracle. As I already finished it, it made me curious about doing it with multi-threading so that I can receive and send messages at the same time. My goal was to learn about multi-threading a bit that's why I tried this. But thank you for the answer! – Marviuz Feb 19 '18 at 11:11