Сокеты в Java - Как я могу написать в DataOutputStream для конкретного клиента? - PullRequest
0 голосов
/ 03 июня 2018

Я реализовал чат, используя модель клиент-сервер в Java.Однако у меня есть одна проблема с dos.writeUTF(msgout), где dos является объектом DataOutputStream.

Допустим, клиент 1 и клиент 2 подключаются к серверу.Сервер может обрабатывать сообщения от обоих клиентов в своем DataInputStream.Однако при обратной записи сервер отправит сообщение только клиенту last (в данном случае 2).Соединение с клиентом 1 остается установленным, но сервер как бы «забывает» о клиенте 1. Я не хочу вещать, но я просто хочу знать, как я могу dos.writeUTF(msgout), например, первый клиент?Вот мой кусок кода с сервера.

Статические переменные (я использую Swing в качестве GUI):

static DataOutputStream dos;
static DataInputStream dis;
static Vector<ClientHandler> ar = new Vector<>(); // Vector for active clients
static int i = 0; // Client counter

Часть основного метода, где устанавливается соединение:

ServerSocket ss = new ServerSocket(1234);
Socket s;

while (true) {
    s = ss.accept();    
    dis = new DataInputStream(s.getInputStream());
    dos = new DataOutputStream(s.getOutputStream());

    ClientHandler mtch = new ClientHandler(s, "Client" + (i+1), dis, dos);
    Thread t = new Thread(mtch);
    ar.add(mtch); // Add client to active clients
    t.start();
    i++;
}

Я создал метод для отправки сообщений (когда я нажимаю кнопку):

public void send() {
try {
    String msgout = "";
    msgout = txtChat.getText().trim();
    if (!msgout.equals("")) {
        dos.writeUTF(msgout); // Need to get specific here. How to write to Client's 1 DataInputStream?
    }
} catch (Exception e) {
       //
  }
}  

Здесь находится класс ClientHandler https://pastebin.com/NWms7TfF

1 Ответ

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

Это нехорошо:

static DataOutputStream dos;

с последующим:

dos.writeUTF(msgout);

Вы создаете одно статическое поле DataOutputStream и затем задаетесь вопросом, почему использование этого поля представляет только один выходной поток,Прежде всего, вы должны избавиться от статических полей, хотя это не решит вашу проблему (но это может помочь исправить другие).Вместо этого, если вы хотите записать в определенный поток вывода, вам нужен способ получить ссылку на него.Подумайте о создании HashMap для хранения ваших ClientHandler объектов и добавьте их на карту, используя любой уникальный идентификатор, который вы хотите использовать для их извлечения, например поле clientName String или поле clientId String (не используйте числа дляЯ бы).И предполагая, что ClientHandler имеет метод getDos(), который возвращает свой выходной поток (если у него его нет, он должен получить его).Затем при необходимости вы можете получить ClientHandler из карты, извлечь его выходной поток с помощью getDos(), а затем записать в него.

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

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