Многопоточный чат на сокетах

601
04 сентября 2017, 05:15

Пытаюсь реализовать графический многопоточный чат на сокетах с использованием JavaFX, но не могу понять, как происходить обмен сообщениями между клиентами и сервером. Окно приложение элементарное: TextArea, TextField и Button. Вообщем, пишешь текст в TextField, нажимаешь кнопку и отправляешь сооб. на сервер. А сервер отправляет сооб. на TextArea. Вот как я попытался это сделать:

Client.java

package objects;
import controllers.stageController;
import java.io.*;
import java.net.Socket;
public class Client implements Runnable {
    private Socket clientSocket;
    public Client(Socket clientSocket) {
        this.clientSocket = clientSocket;
        System.out.println("New client connected.\r\n\tInetAdress: " + clientSocket.getInetAddress());
    }
    @Override
    public void run() {
        try(InputStream in = clientSocket.getInputStream();
            OutputStream out = clientSocket.getOutputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in));
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(out))) {
            stageController sc = new stageController();
            String string1 = null;
            String string2 = null;
            while(clientSocket.isConnected()) {
                System.out.println("hello");
                /* По нажатию на кнопку отправлять сообщение серверу */
//                try{
//                    string1 = sc.getMsg(); // Вот тут NPE
//                } catch(NullPointerException e) {continue;}
//                if(!string1.isEmpty() && string1 != null) {
//                    bufferedWriter.write(string1);
//                    System.out.println("Client has send the message");
//                }
                /*****************************************************/
                /* Принимать сообщение от сервера */
//                if((string2 = bufferedReader.readLine()) != null) {
//                    sc.receive(string2 + "\r\n");
//                    System.out.println("Client received the message");
//                }
                /**********************************/
            }
        } catch (IOException e) {
            System.err.println("IOException in Client class!");
        }
    }
}

Server.java

package objects;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class Server implements Runnable {
    private ServerSocket serverSocket;
    public final static int port = 5555;
    private static Map<String, String> clientInfo = new LinkedHashMap<>();
    private static List<Client>        clientList = new ArrayList<>();
    public Server() {
        try {
            serverSocket = new ServerSocket(port);
            System.out.println("Server created.\r\n\tPort: " + port + "\r\n\tInetAdress: " + serverSocket.getInetAddress());
        } catch (IOException e) {
            System.err.println("IOException in server`s constructor");
        }
    }
    @Override
    public void run() {
        try {
            while(true) {
                Client client = new Client(serverSocket.accept());
                Thread clientThread = new Thread(client);
                clientList.add(client);
                clientThread.setDaemon(true); // Теперь этот поток будет завершаться при закрытии главного окна
                clientThread.start();
            }
        } catch(IOException e) {
            System.err.println("IOException in Server.run()");
        }
    }
    public final static void addClient(String login, String parol) {
        clientInfo.put(login, parol);
    }
    public final static boolean isPresent(String login, String parol) {
        return clientInfo.get(login) != null && (clientInfo.get(login)).equals(parol);
    }
}

stageController.java

package controllers;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
public class stageController {
    @FXML
    private TextArea ta;
    @FXML
    private TextField tf;
    private String msg;
    public String getMsg() {
        return msg;
    }
    public final void send(ActionEvent actionEvent) {
        msg = tf.getText();
        tf.clear();
    }
    public final void receive(String msg) {
        ta.setText(msg + "\r\n");
    }
}

Метод main

Server server = new Server();
        Thread serverThread = new Thread(server);
        serverThread.setDaemon(true); // Теперь этот поток будет завершаться при закрытии главного окна
        serverThread.start();
        launch(args);
Answer 1

У тебя сервер хранит список всех подключений в clientList. Соответственно, чтобы отправить всем сообщения, нужно в цикле пройтись по этому списку, и записать в OutputStream каждого клиента очередное сообщение, которое пришло серверу. Как-то так...

READ ALSO
Class&lt;List&lt;T&gt;&gt; != Class&lt;T&gt; или как в Unirest массив дессериализовать

Class<List<T>> != Class<T> или как в Unirest массив дессериализовать

Есть у меня вот такой обобщённый метод для отправки запроса и получения сразу десериализованного объекта

445
Захват звука с мишкера

Захват звука с мишкера

Доброго времени суток , Нужна помощь как захватить звук с мишкера системы?

471
Передача оъекта из фрагмента в активити

Передача оъекта из фрагмента в активити

Есть фрагмент, в котором находится ListViewПри клике на элемент списка идет вызов другого активити

446
Вывести не полный список товаров jsp

Вывести не полный список товаров jsp

Мне нужно вывести не полный список товаров на страницеТо есть их, например, в сумме 40, и я хочу, чтобы первоначально показывалось 10, и нажимая...

350