Пытаюсь разобраться, что не так, но не могу найти ошибки. Продолжаю поиски и, параллельно, решил сразу отправить вопрос, чтобы не терять время, если это очередная дурость валидатора. Помогите :)
И да, проблема где-то в блоке do-while, почему-то заедает на бесконечный цикл, но, вроде бы, логика в порядке: если это не имя пользователя или имя неправильное, то запросить имя снова. Логика метода для проверки правильности имени тоже вполне нормальная: имя не должно быть null, пустым или уже иметься у другого пользователя. Что не так?
Ярослав
40 уровень
Валидатор жалуется на "слишком долго работала" и бесконечный цикл, что не так?
Решен
Комментарии (16)
- популярные
- новые
- старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Ярослав Java Developer Master
20 февраля 2018, 17:05решение
Проблема решилась благодаря тому, что пошел смотреть новый вопрос другого человека по этой же самой задачи и увидел вместо проверки на null использование метода isEmpty. Сделал тоже через isEmpty и все заработало. Просьба кого-то выше хотя бы оставить подсказки, как именно должна быть выполнена проверка на пустоту сообщения, ибо я бы уже мог значительно продвинуться по задаче, но застрял на день из-за такой вот проверки.
+2
Gor Ivanov
20 февраля 2018, 11:45
Метод private String serverHandshake вообще не правильный. Не могу скинуть готовый код, нельзя.
Как минимум убери do -while,
Зачем тут так сложно?
Message nameAccepted = new Message(MessageType.NAME_ACCEPTED, "Ваше имя принято!");
connection.send(nameAccepted);
Например лучше так (проще код):
connection.send(new Message(MessageType.NAME_ACCEPTED, "Ваше имя принято!"));
А что если методе main если сокет будет нулевой?
В поле catch сокет не закроется, так как закрытие может кинуть еще один exception (IO) (на сколько я знаю), перенеси в блок finally
0
Ярослав Java Developer Master
20 февраля 2018, 11:59
Вы упустили объяснение, почему метод неправильный. Без этого дальнейшие слова бесполезные. Должна быть конкретика.
Принятый сокет не может быть нулевым, ведь если мы его приняли, то он уже есть. Серверный сокет тоже, ведь его мы создаем сами, и finally не гарантирует 100% закрытие ресурса, ведь в finally тоже может быть исключение, тогда нужно обработать исключение в finally и еще раз закрыть сокет, но ведь при этом закрытии тоже может быть исключение, и нам придется обработать уже его. Это бесконечная рекурсия. И валидацию то решение с закрытием прошло.
Про создание отдельной переменной: это я и так сделал, просто последнюю версию кода обновлять в вопросе не так удобно, ведь для этого нужно зафейлить еще раз валидацию.
И снова к первому: почему неправильный метод? И если нам нужно спрашивать имя пользователя до того, как он его скинет, то это в любом случае будет цикл, и из всех существующих циклов, тут удобнее всего использовать do-while.
0
Ярослав Java Developer Master
20 февраля 2018, 12:05
И суть finally как раз в том, чтобы если исключение выпало в catch-блоке, то все равно ресурсы закрылись. Если же единственная команда catch-блока - закрыть ресурс, то можно обойтись и без finally.
0
Ярослав Java Developer Master
20 февраля 2018, 11:45
Все ещё ломаю голову, ведь условие в while действительно правильное. Я опустил реализацию через отдельный метод, закомментировав его, сейчас условие такое:
Что на человеческом значит: "повторять запрос, пока полученное сообщение не будет равняться имени пользователя, так же не быть пустым, так же присутствовать уже у другого клиента".
Реально нужна помощь, потому что полностью застрял на этом задании и не могу двигаться дальше. 0
Gor Ivanov
20 февраля 2018, 11:50
Подсказка еще одна, нужно делать бесконечный цыкл while, где выход из него происходит только через return, при выполнении необходимых условий.
0
Ярослав Java Developer Master
20 февраля 2018, 12:02
Может быть, можно и так. Однако это уже осложнения, ведь код цикла будет довольно тяжеловесный. Суть цикла do-while в том, чтобы дождаться правильного ввода и сделать все нужные действия.
По сути, тут есть проверка на все данные: на тип сообщения и на правильность имени пользователя. После этого цикла, остается просто добавить пользователя, отправить ему сообщение, что все окей, и вернуть его имя из метода.
И если у вас правильность метода зависит от его совпадения с вашим решением, то это неправильно, ведь каждая задача может решаться разными способами. 0
Ярослав Java Developer Master
20 февраля 2018, 12:30
Вот решение на вашей подсказке, то же от валидатора: бесконечный цикл, не можем протестировать. Может, теперь подумаете о том, почему тут бесконечный цикл появляется, а не почему я сделал не так, как вы?
0
Gor Ivanov
20 февраля 2018, 15:41
По поводу serverSocket, я его как раз в finally с дополнительным try-catch и обрабатывал.
А в методе не то сообщение отправляется.
Условие -> После успешного проведения всех проверок, метод serverHandshake должен добавлять новую пару (имя, соединение) в connectionMap и отправлять сообщение о том, что имя было принято.
то есть не
cnnection.send(new Message(MessageType.USER_ADDED));
а
connection.send(new Message(MessageType.NAME_ACCEPTED));
О том что нужно отправлять сообщение, что пользователь добавлени нет ни слова в условии.
0
Ярослав Java Developer Master
20 февраля 2018, 15:54
Это последнее, на что нужно смотреть. Я еще раз акцентирую внимание: в программе почему-то появляется бесконечный цикл, и валидация падает с "слишком долго работала". Проблема не в пунктах валидации, что где-то не проходит требование, а в том, что тут почему-то зацикливается бесконечный цикл, чего быть не должно. И даже если сделать так, как будет далее, все равно проверка заедает.
0
Gor Ivanov
20 февраля 2018, 17:28
Если проблема именно в этом методе, тот может еще в условии answer.getData() != null, я проверял не на null а на if (!userName.getData().isEmpty())
Кстати в условии так и написано -> Достать из ответа имя, проверить, что оно не пустое и пользователь с таким именем еще не подключен (используй connectionMap)
0
Ярослав Java Developer Master
20 февраля 2018, 17:37
Да, в этом и был ответ :) Однако странно, что зависало с проверкой на null, ведь даже если переданная строка была эквивалентна "", то все равно проверку на нулл должно было проходить и должен был быть выход из цикла, ведь строка не равняется нуллу. Мне кажется, что это что-то с тестами у этой задачи.
0
Pavlo Plynko Java-разработчик в CodeGym Expert
23 февраля 2018, 10:11
Исправим, чтобы не зависало с проверкой на null.
0
Rihard1985Master
30 августа 2018, 13:05
Так и не исправили ,через empty прошло только((
0
Pavlo Plynko Java-разработчик в CodeGym Expert
31 августа 2018, 08:01
То решение которое здесь обсуждалось - сейчас проходит. ¯\_(ツ)_/¯
0
Rihard1985Master
31 августа 2018, 13:31
наверно я туповат и неправильно пишу скорее всего значит
0