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

Multi-threaded Server Client Address already in use

我想做的是在服务器中设置接收方 class 以接收客户端发送的消息,并在客户端设置发送方 class 。我试图首先在服务器中制作接收器,因为在学习之后我可能会弄清楚如何在客户端做到这一点。但是这样做给了我 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();
        }
    }
}

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

发件人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);
        }
    }
}

接收者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);
        }
    }
}

Server 中的方法 main :

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

您有两个线程在同一端口 (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);
            }
        }
    }
}