简体   繁体   English

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

[英]Multi-threaded Server Client Address already in use

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 . 但是这样做给了我java.net.BindException: Address already in use: JVM_Bind I think it's because I have another Server server = new Server(); 我认为这是因为我有另一个Server server = new Server(); in the receiver. 在接收器中。 How do I solve this? 我该如何解决?

Server.java 服务器.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 客户端.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();
        }
    }
}

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. 不要创建Server多个实例,您可以在main创建实例,然后将bufferedReader传递给接收器类,并将printWriter传递给发送器类。

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

You have two threads starting a new instance of the connection at the same port (3000). 您有两个线程在同一端口(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(); 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. 您可以使用DataOutputStream.writeUTF()和DataOutputStream.flush()方法。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM