Как сервер может передать сообщение другим клиентам? - PullRequest
0 голосов
/ 30 сентября 2019

Программа предназначена для подключения нескольких клиентов к одному серверу, и клиенты могут отправлять и получать сообщения среди других клиентов.

Например, если клиент A говорит «Привет», клиент B и клиент C, подключенные к серверу, также получают «Привет».

В моем текущем коде сервер принимает только отправленные сообщенияклиентами. В настоящее время я ищу решение, чтобы сервер транслировал сообщение, отправленное клиентом (например, ClientA) другим клиентам. Любой совет будет высоко ценится.

Этот серверный класс обрабатывает соединения нескольких клиентов с использованием потоков:

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

class EchoThread extends Thread {
    private Socket socket;

    //constructor
    public EchoThread(Socket clientSocket) {
        this.socket = clientSocket;
    }

    @Override
    public void run() {
        DataInputStream inp = null;

        try {
            inp = new DataInputStream(new BufferedInputStream(socket.getInputStream()));

            //print whatever client is saying as long as it is not "Over"
            String line = "";
            while (!line.equals("Over")) {
                try {
                    line = inp.readUTF();
                    System.out.println(line);
                } catch (IOException e) { System.out.println(e); }
            }

            //closes connection when client terminates the connection
            System.out.print("Closing Connection");
            socket.close();
        } catch (IOException e) { System.out.println(e); }
    }
}

public class Server {
    private static final int PORT = 5000;

    public static void main(String args[]) {
        ServerSocket serverSocket = null;
        Socket socket = null;

        //starts the server
        try {
            serverSocket = new ServerSocket(PORT);
            System.out.println("Server started");
            System.out.println("Waiting for a client ...\n");
        } catch (IOException e) { System.out.println(e); }

        //while loop to accept multiple clients
        int count = 1;
        while(true) {
            try {
                socket = serverSocket.accept();
                System.out.println("Client " + count + " accepted!");
                count++;
            } catch (IOException e) { System.out.println(e); }

            //starts the server thread
            new EchoThread(socket).start();
        }
    }
}

, и это клиентский класс (у меня есть несколько экземпляров этоговыполнение кода):

import java.net.*;
import java.io.*;

public class ClientA {
    private Socket socket = null;
    private DataInputStream input = null;
    private DataOutputStream output = null;

    public ClientA(String address, int port) {
        //establish connection
        try {
            socket = new Socket(address, port);
            System.out.println("Connected");

            //takes input from terminal
            input = new DataInputStream(System.in);

            //sends output to the socket
            output = new DataOutputStream(socket.getOutputStream());
        } catch (IOException e) { System.out.println(e); }

        //string to read message from input
        String line = "";

        //keep reading until "Over" is input
        while (!line.equals("Over")) {
            try {
                line = input.readLine();
                output.writeUTF(line);
            } catch (IOException e) { System.out.println(e); }
        }
        //close the connection
        try {
            input.close();
            output.close();
            socket.close();
        } catch (IOException e) { System.out.println(e); }
    }

    public static void main (String args[]) {
        ClientA client = new ClientA("127.0.0.1", 5000);
    }
}

Не стесняйтесь исправлять меня в моих комментариях к коду, поскольку я все еще не очень знаком с программированием сокетов.

Ответы [ 2 ]

0 голосов
/ 30 сентября 2019

Ты хорошо справился. Просто добавьте ветку для получения сообщения в ClientA;и хранить сокет клиентов на сервере. На самом деле, сервер также является «клиентом», когда отправляет сообщение клиенту.

Я добавляю некоторый код на основе вашего кода. Это работает хорошо, надеюсь, это полезно.

class EchoThread extends Thread {
//*****What I add begin.
private static List<Socket> socketList = new ArrayList<>();
//*****What I add end.

private Socket socket;

//constructor
public EchoThread(Socket clientSocket) {
    this.socket = clientSocket;
    socketList.add(socket);
}

@Override
public void run() {
    DataInputStream inp = null;

    try {
        inp = new DataInputStream(new BufferedInputStream(socket.getInputStream()));

        //print whatever client is saying as long as it is not "Over"
        String line = "";
        while (!line.equals("Over")) {
            try {
                line = inp.readUTF();
                System.out.println(line);

                //*****What I add begin.
                sendMessageToClients(line);
                //*****What I add end.
            } catch (IOException e) { System.out.println(e); break;}
        }

        //closes connection when client terminates the connection
        System.out.print("Closing Connection");
        socket.close();
    } catch (IOException e) { System.out.println(e); }
}

//*****What I add begin.
private void sendMessageToClients(String line) throws IOException {
    for (Socket other : socketList) {
        if (other == socket) {
            continue;//ignore the sender client.
        }
        DataOutputStream output = new DataOutputStream(other.getOutputStream());
        output.writeUTF(line);
    }
}
//*****What I add end.

}

public class ClientA {
private Socket socket = null;
private DataInputStream input = null;
private DataOutputStream output = null;

public ClientA(String address, int port) {
    //establish connection
    try {
        socket = new Socket(address, port);
        System.out.println("Connected");

        //takes input from terminal
        input = new DataInputStream(System.in);

        //sends output to the socket
        output = new DataOutputStream(socket.getOutputStream());

        //*****What I add begin.
        //Here create a thread to receive message from server.
        DataInputStream inp = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
        new Thread(() -> {
            while (true) {
                String str;
                try {
                    str = inp.readUTF();
                    System.out.println(str);
                } catch (IOException e) {
                    e.printStackTrace();//error.
                    break;
                }
            }
        }, "Client Reveiver.").start();
        //*****What I add end.

    } catch (IOException e) { System.out.println(e); }

    //string to read message from input
    String line = "";

    //keep reading until "Over" is input
    while (!line.equals("Over")) {
        try {
            line = input.readLine();
            output.writeUTF(line);
        } catch (IOException e) { System.out.println(e); }
    }
    //close the connection
    try {
        input.close();
        output.close();
        socket.close();
    } catch (IOException e) { System.out.println(e); }
}
0 голосов
/ 30 сентября 2019

У меня будет один серверный поток, который будет вести реестр клиентов, возможно, в параллельной коллекции. Затем я отправляю каждое сообщение, полученное от клиента, всем остальным клиентам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...