JavaRush
AI Academy
Акция
Университет
Java FullStack
Python FullStack
AI Native Developer
new
Web FullStack
Обучение
Курсы
Задачи
Опросы
Игры
Помощь
График пинков
Стажировка
Сообщество
Пользователи
Форум
Чат
Статьи
Истории успеха
Активности
Отзывы
Подписки
Светлая тема
Вопрос
  • Отзывы
  • О нас
  • CS50
Начать
Начать обучение
Начать обучение
  • Все вопросы
JavaRush/Помощь по Java задачам/такс-такс што тут у нас
Олег
31 уровень
  • 04.08.2018
  • 1093просмотров
  • 5комментариев

такс-такс што тут у нас

Вопрос по задаче Чат (16)
Java Multithreading,  6 уровень,  15 лекция
Решен

Теперь все готово, чтобы дописать необходимые методы класса SocketThread.

1) Добавь protected метод clientHandshake() throws IOException, ClassNotFoundException.
Этот метод будет представлять клиента серверу.

Он должен:
а) В цикле получать сообщения, используя соединение connection.
б) Если тип полученного сообщения NAME_REQUEST (сервер запросил имя), запросить ввод имени пользователя с помощью метода getUserName(), создать новое сообщение с типом MessageType.USER_NAME и введенным именем, отправить сообщение серверу.
в) Если тип полученного сообщения MessageType.NAME_ACCEPTED (сервер принял имя), значит сервер принял имя клиента, нужно об этом сообщить главному потоку, он этого очень ждет.
Сделай это с помощью метода notifyConnectionStatusChanged(), передав в него true.
После этого выйди из метода.
г) Если пришло сообщение с каким-либо другим типом, кинь исключение IOException("Unexpected MessageType").

2) Добавь protected метод void clientMainLoop() throws IOException, ClassNotFoundException.

Этот метод будет реализовывать главный цикл обработки сообщений сервера. Внутри метода:
а) Получи сообщение от сервера, используя соединение connection.
б) Если это текстовое сообщение (тип MessageType.TEXT), обработай его с помощью метода processIncomingMessage().
в) Если это сообщение с типом MessageType.USER_ADDED, обработай его с помощью метода informAboutAddingNewUser().
г) Если это сообщение с типом MessageType.USER_REMOVED, обработай его с помощью метода informAboutDeletingNewUser().
д) Если клиент получил сообщение какого-либо другого типа, брось исключение IOException("Unexpected MessageType").
е) Размести код из предыдущих пунктов внутри бесконечного цикла.
Цикл будет завершен автоматически если произойдет ошибка (будет брошено исключение) или поток, в котором работает цикл, будет прерван.

Требования:
  • Метод clientHandshake() должен отправлять новое сообщение (MessageType.USER_NAME, getUserName()) используя connection, если тип принятого сообщения равен MessageType.NAME_REQUEST.
  • Метод clientHandshake() должен вызывать метод notifyConnectionStatusChanged(true) и завершаться, если тип принятого сообщения равен MessageType.NAME_ACCEPTED.
  • Метод clientHandshake() должен бросать исключение IOException, если тип принятого сообщения не MessageType.NAME_ACCEPTED или не MessageType.NAME_REQUEST.
  • Метод clientHandshake() должен принимать сообщения от сервера до тех пор, пока тип сообщения равен MessageType.NAME_REQUEST.
  • Метод clientMainLoop() должен принимать сообщения от сервера до тех пор, пока тип сообщения равен MessageType.TEXT, MessageType.USER_REMOVED или MessageType.USER_ADDED.
  • Метод clientMainLoop() должен обрабатывать полученное сообщение с помощью метода processIncomingMessage(), если тип принятого сообщения равен MessageType.TEXT.
  • Метод clientMainLoop() должен обрабатывать полученное сообщение с помощью метода informAboutAddingNewUser(), если тип принятого сообщения равен MessageType.USER_ADDED.
  • Метод clientMainLoop() должен обрабатывать полученное сообщение с помощью метода informAboutDeletingNewUser(), если тип принятого сообщения равен MessageType.USER_REMOVED.
  • Метод clientMainLoop() должен бросать исключение IOException, если тип принятого сообщения не MessageType.TEXT, MessageType.USER_REMOVED или не MessageType.USER_ADDED.
....
package com.javarush.task.task30.task3008; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; public class Server { private static Map<String, Connection> connectionMap = new ConcurrentHashMap<>(); public static void main(String[] args) throws IOException { ConsoleHelper consoleHelper = new ConsoleHelper(); ServerSocket serverSocket = new ServerSocket(consoleHelper.readInt()); System.out.println("Server is running"); try { while(true) { Socket socket = serverSocket.accept(); Handler handler = new Handler(socket); handler.start(); } } catch(Exception ex) { System.out.println("Catch exception"); serverSocket.close(); } } public static void sendBroadcastMessage(Message message) { for(Connection con : connectionMap.values()) { try { con.send(message); }catch(IOException ex) { System.out.println("Error to send message"); } } } private static class Handler extends Thread { private Socket socket; public Handler(Socket socket) { this.socket = socket; } private String serverHandshake(Connection connection) throws IOException, ClassNotFoundException { while (true) { connection.send(new Message(MessageType.NAME_REQUEST)); Message answer = connection.receive(); if (answer.getType() == MessageType.USER_NAME) { if (!answer.getData().isEmpty()) { if (!connectionMap.containsKey(answer.getData())) { connectionMap.put(answer.getData(), connection); connection.send(new Message(MessageType.NAME_ACCEPTED)); return answer.getData(); } } } } } private void sendListOfUsers(Connection connection, String userName) throws IOException { for(Map.Entry<String, Connection> map : connectionMap.entrySet()) { String name; if(userName != (name = map.getKey())) { connection.send(new Message(MessageType.USER_ADDED,name)); } } } private void serverMainLoop(Connection connection, String userName) throws IOException, ClassNotFoundException { while(true) { Message message = connection.receive(); if (message.getType() == MessageType.TEXT) { StringBuilder sb = new StringBuilder(); sb.append(userName+": "+message.getData()); sendBroadcastMessage(new Message(MessageType.TEXT,sb.toString())); } else if(message.getType() != MessageType.TEXT) { ConsoleHelper.writeMessage("It is not a message"); } } } public void run() { if(socket != null && socket.getRemoteSocketAddress() != null) { ConsoleHelper.writeMessage("Connection with remote address is established. " + socket.getRemoteSocketAddress() ); } String userName = null; try (Connection connection = new Connection(socket)) { userName = serverHandshake(connection); sendBroadcastMessage(new Message(MessageType.USER_ADDED,userName)); sendListOfUsers(connection,userName); serverMainLoop(connection,userName); }catch (IOException | ClassNotFoundException ex) { ConsoleHelper.writeMessage("Error to communicate data to remote address."); }finally { if(userName != null) { connectionMap.remove(userName); sendBroadcastMessage(new Message(MessageType.USER_REMOVED,userName)); } ConsoleHelper.writeMessage("Connection of remote address is closed."); } } } }
0
Комментарии (5)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
KRonst Backend Developer
5 августа 2018, 13:43полезный
Перепиши метод clientHandshake: вместо switch используй if-else.
+1
Олег
Уровень 31
5 августа 2018, 14:30
та уже допер хоть и не понял чем кейс не по нраву.. Спасибо.
0
s1tcomsfan
Уровень 40
5 августа 2018, 17:46полезный
Я не понимаю почему метод пробрасывает исключения и в нем же вы эти же исключения ловите try...catch
+1
WikkoDoc
Уровень 30
25 марта 2019, 21:18
Здравствуйте. Не могли бы вы прислать мне код из упражнения. Я уже устал от 35 попыток... Это мой код что не так?
protected void clientMainLoop() throws IOException, ClassNotFoundException{
            while(true){
                Message message = connection.receive();
                if(message.getType()==MessageType.TEXT) processIncomingMessage(message.getData());
                else if (message.getType()==MessageType.USER_ADDED) informAboutAddingNewUser(message.getData());
                else if (message.getType()==MessageType.USER_REMOVED) informAboutDeletingNewUser(message.getData());
                else throw new IOException();
            }
        }
+1
Aleksej Kudrawets
Уровень 31
7 июня 2020, 10:38
у меня похожая версия и все равно ругается на последний пункт, думаю, в таких случаях проще с гитхаба скопировать, нежели тратить время и нервы в угоду валидатору, я вот убедился, все так, но он как то хочет по своему
0
Обучение
  • Курсы программирования
  • Регистрация
  • Курс Java
  • Помощь по задачам
  • Цены
Сообщество
  • Пользователи
  • Статьи
  • Форум
  • Чат
  • Истории успеха
  • Активности
Компания
  • О нас
  • Контакты
  • Отзывы
  • FAQ
  • Поддержка
JavaRushJavaRush — это интерактивный онлайн-курс по изучению Java-программирования c нуля. Он содержит 1200 практических задач с проверкой решения в один клик, необходимый минимум теории по основам Java и мотивирующие фишки, которые помогут пройти курс до конца: игры, опросы, интересные проекты и статьи об эффективном обучении и карьере Java‑девелопера.
Подписывайтесь
Язык интерфейса
Русский
English Українська
"Программистами не рождаются" © 2026 JavaRush
MastercardVisa
"Программистами не рождаются" © 2026 JavaRush