多线程服务器客户端地址已在使用中

时间:2018-02-19 09:26:30

标签: java sockets server client serversocket

我尝试做的是在服务器中创建接收器类,它从客户端接收已发送的消息并在客户端中创建发送者类。我试图先在服务器中设置接收器,因为我可能会在学习之后弄清楚如何在客户端做到这一点。但这样做会给我java.net.BindException: Address already in use: JVM_Bind。我认为这是因为我在接收器中有另一个Server server = new Server();。我该如何解决这个问题?

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();
        }
    }
}

2 个答案:

答案 0 :(得分:2)

不要创建Server的多个实例,您可以在main中创建实例,然后将bufferedReader传递给接收者类,将printWriter传递给发件人类。

发件人类:

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);
        }
    }
}

接收者类:

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);
        }
    }
}

main中的方法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();
}

答案 1 :(得分:0)

您有两个线程在同一端口(3000)启动新连接实例。我假设您尝试让一个线程从服务器接收消息,另一个线程用于向客户端发送消息。我不认为你需要这样的设计。这可以在单线程环境中完成。客户端(发送者和接收者)和服务器(发送者和接收者)不需要。

的ServerSocket.accept();方法将侦听传入指定端口号的所有消息。

为了让服务器向客户端发送回复。您可以使用   DataOutputStream.writeUTF()& DataOutputStream.flush()方法。

客户端也是如此。看看下面的程序。

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);
            }
        }
    }
}