Отправка всем клиентам в многопоточном клиент-сервере

У меня в настоящее время проблема с моим кодом. Клиент должен иметь возможность отправить строку «messge # Somestring», и если сервер замечает, что она содержит подстроку «message #», он должен отправить ее всем пользователям. Однако происходит то, что он отправляется только одному пользователю, который отправил «псевдозапрос», который я пытаюсь реализовать. Вот мои коды для справки:

import java.io.*;
import java.net.*;
import java.util.Vector;

public class server {
    static ServerSocket ss;
    static Socket s;
    static DataInputStream dis;
    static DataOutputStream dos;
    static Integer maxNumofUsers=4;
    static Vector<UserHandler> users;
    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        Integer currNumofUsers=0;
        ss=new ServerSocket(7777);
        users=new Vector<UserHandler>();

        while(currNumofUsers<maxNumofUsers) {
            s=ss.accept();
            UserHandler uh= new UserHandler(s, "Player "+Integer.toString(currNumofUsers+1));
            users.add(uh);
            users.get(users.size()-1).start();//start a thread
            currNumofUsers++;
            for(int i=0; i<users.size(); i++) {//updates number of users present pero userhandler
                users.get(i).updateUserSet(users);
            }
        }

        System.out.println("Maximum number of players reached.");
    }

}

class UserHandler extends Thread{
    Socket s;
    DataInputStream dis;
    DataOutputStream dos;
    Vector<UserHandler> users=new Vector<UserHandler>();
    String username;
    public UserHandler(Socket s, String username) {
        // TODO Auto-generated constructor stub
        this.s=s;
        this.username=username;
    }

    public void run(){
        try {
            dis=new DataInputStream(s.getInputStream());
            dos=new DataOutputStream(s.getOutputStream());

            while(true) {
                String message=dis.readUTF();
                if (message.contentEquals("exit")) {
                    dos.writeUTF("exit granted");
                    close();
                    break;
                }else if (message.contains("message#")){//group sms
                    for(int i=0; i<users.size(); i++) {
                            users.get(i).dos.writeUTF("henlo");
                            System.out.println("Wrote to "+users.get(i).username);
                    }

                }else {
                        dos.writeUTF("Some String");
                }
            }

        } catch (IOException e) {
            // TODO Auto-generated catch block
            try {
                s.close();
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            e.printStackTrace();
        }

    }

    public void close() {
        try {
            for(int i=0; i<users.size(); i++) {
                if (users.get(i).username==this.username) {
                    users.remove(i);
                    System.out.println("out");
                    for(int j=0; j<users.size(); j++) {
                        users.get(j).updateUserSet(users);
                    }
                    break;
                }
            }
            dis.close();
            dos.close();
            s.close();
        }catch(IOException e) {
            e.printStackTrace();
        }

    }

    public void updateUserSet(Vector<UserHandler> users) {
        // TODO Auto-generated method stub
        this.users=users;
    }


}

Для сервера. для клиента,

import java.net.*;
import java.util.Scanner;
import java.io.*;

public class client {
    static Socket s;
    static DataInputStream dis;
    static DataOutputStream dos;
    static gameWindow GUI;
    static String username;
    public static void main(String[] args) throws Exception {

        try {
            s=new Socket();
            s.connect(new InetSocketAddress("127.0.0.1",7777), 5000);
            System.out.println("Socket "+s.getInetAddress()+" has connected.");
            username= JOptionPane.showInputDialog("Please input username: ");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            System.out.println("Cannot connect to server. Either the Server was not established or maximum number of players was reached.");
        }

        if (s.isConnected()){
            try {
                dis=new DataInputStream(s.getInputStream());
                dos=new DataOutputStream(s.getOutputStream());
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            Scanner sc=new Scanner(System.in);
            String msg;
            while(true) {

                msg=sc.nextLine();
                dos.writeUTF(msg);
                String rcv=dis.readUTF();
                if (rcv.contentEquals("exit granted")) {
                    System.out.println("Socket "+s.getInetAddress()+" is closed.");
                    close();
                    break;
                }else if (rcv.contains("array#")) {
                    String tobearr=rcv;
                    String[] arred=tobearr.split("#");
                    for(int i=0; i<arred.length; i++) {
                        System.out.println(arred[i]);
                    }
                    tobearr = "";
                }else if (rcv.contains("message#")) {
                    String grpsms=rcv.substring(8, rcv.length());
                    System.out.println(grpsms);
                }
                System.out.println(rcv);
                rcv = "";
            }
        }

    }

    private static void close() {
        // TODO Auto-generated method stub
        try {
            dis.close();
            dos.close();
            s.close();
        }catch(IOException e) {
            e.printStackTrace();
        }

    }

}

Вы не отправляете данные на сервер, скорее клиент печатает сообщение на своей консоли, создавая впечатление, что сервер получил сообщение и отправил его обратно пользователю. Сервер никогда не получает сообщение в вашем коде. Кроме того, даже если сервер получил сообщение, он ничего не делает, если message.contains("message#"), поскольку в цикле нет логики. Вместо System.out.println(grpms) вы должны использовать dos.writeUTF(grpms). Затем вам нужно будет заставить сервер что-то сделать с этим сообщением.

Dioxin 25.10.2018 02:47

@VinceEmigh users.get(i).dos.writeUTF("henlo") должен обрабатывать это, поскольку я сохранил их внутри вектора, и он находится внутри цикла for. Но я не уверен, правильно ли я делаю это, так как я только новичок.

user311699 25.10.2018 02:49

Я вижу, вы отредактировали логику сервера для обработки message#. break в этой логике выходит из цикла после первой итерации. Обычно вы используете его при каком-то условии: if (i == 3) break;, но для вашего break условия нет. Он сработает, вызывая выход из цикла после отправки сообщения первому человеку в коллекции. Я не вижу смысла иметь break в этом цикле.

Dioxin 25.10.2018 02:55

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

user311699 25.10.2018 03:06

настройка Vector<UserHandler> users=new Vector<UserHandler>(); в потоке не является потокобезопасной.

Scary Wombat 25.10.2018 03:13
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
5
30
0

Другие вопросы по теме