Попытка сделать широковещательный сервер, который выводит клиентов - PullRequest
0 голосов
/ 30 июня 2018

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

Код сервера:

package Group;
import java.net.*;
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.*;

public class GroupServer extends Thread {
    private ServerSocket server;
    protected List<ClientHandler> clients;

    public static void main(String[] args) throws IOException {
        new GroupServer(9876);
    }

    public GroupServer(int port) {
        try {
            this.server = new ServerSocket(port);
            System.out.println("New server initialized!");
            clients = Collections.synchronizedList(new ArrayList<ClientHandler>());
            this.start();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
public void run() {
    while (true) {
        try {
            Socket client = server.accept();
            System.out.println(client.getInetAddress().getHostName() + " connected");
            ClientHandler newClient = new ClientHandler(client);
            clients.add(newClient);
            new SendMessage(clients);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
}

class ClientHandler {
protected Socket client;
protected PrintWriter out;
protected DataInputStream in;

public ClientHandler(Socket client) {
    this.client = client;
    try {
        this.out = new PrintWriter(client.getOutputStream());
        this.in = new DataInputStream(client.getInputStream());

    } catch (IOException e) {
        e.printStackTrace();
    }
}
}

class SendMessage extends Thread {
    protected List<ClientHandler> clients;
    protected String userInput;
    protected String sendMessage;
    protected BufferedReader stdIn;
    protected DataInputStream in;

    public SendMessage(List<ClientHandler> clients) {
        this.clients = clients;
        this.userInput = null;
        this.start();
    }

    public void run() {
        System.out.println("New Communication Thread Started");
        if (clients.size() == 1) {
            System.out.println("Enter message:");
        }
        try {
            if (clients.size() > 0) {
                this.stdIn = new BufferedReader(new InputStreamReader(System.in));

                while ((this.userInput = stdIn.readLine()) != null) {
                    if (userInput != null & userInput.length() > 0) {
                        for (ClientHandler client : clients) {
                            sendMessage = client.in.readUTF();
                            client.out.println(sendMessage);
                            client.out.flush();
                        Thread.currentThread();
                        Thread.sleep(1 * 1000);
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Код клиента:

package Group;
import java.net.*;
import java.io.*;
import java.util.logging.*;

public class GroupClient {
protected Socket client;
protected BufferedReader in;

public static void main(String[] args) {
    new GroupClient("Localhost", 9876);
}

public GroupClient(String hostName, int ip) {
    try {
        this.client = new Socket(hostName, ip);
        this.in = new BufferedReader(new InputStreamReader(
                this.client.getInputStream()));
        String buffer = null;
        while ((buffer = in.readLine()) != null) {
            System.out.println(buffer);
        }
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}       
}

Я думаю, что ошибка в сервере, более точно в классе SendMessage. Спасибо за внимание.

1 Ответ

0 голосов
/ 30 июня 2018

У вас есть только одна тема "SendMessage" для всех клиентов.

При первом вызове client.in.readUTF() в цикле поток блокируется, пока клиент не отправит что-либо. Так как все остальные клиенты обрабатываются одним потоком. Все они тоже заблокированы.

Либо у вас есть один поток на клиентском сокете, либо выберите способ выбора nio (предпочтительно).

Также исправьте проблемы, упомянутые @ jingx.

Для синхронизированного массива используйте CopyOnWriteArrayList. Он специально предназначен для таких случаев использования. Синхронизация помогает в одновременном добавлении и удалении, но не во время параллельной итерации. CopyOnWriteArrayList решает эту проблему.

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