Skip to content

Latest commit

 

History

History
138 lines (101 loc) · 14.1 KB

File metadata and controls

138 lines (101 loc) · 14.1 KB

OSI

Памятка к домашнему заданию

Перед тем, как отправить своё решение на проверку преподавателю, сверьтесь с чеклистом

Что делать, если возникли сложности?

И это здорово! Если их преодолевать правильно, то можно получить большую образовательную пользу для себя. Периодическое возникновение вопросов, недопонимание пройденного материала - нормальная и неотъемлемая часть обучения. А мы здесь, чтобы помочь вам пройти этот путь.

Что делать, если непонятна теория?

  1. Если подобный вопрос разбирался на лекции, посмотрите еще раз раздел с этой темой в видеозаписи.
  2. Если вопрос не решился, попробуйте поискать ответ самостоятельно в интернете, этот навык пригодится вам в работе.
  3. Если самостоятельно разобраться не удалось, задайте вопрос в общем чате, мы обязательно поможем.

Что делать, если непонятно условие задания?

  1. Прежде чем задать вопрос по условию задачи, перечитайте его ещё раз и убедитесь, что в тексте условия нет прямого ответа на этот вопрос. Умение работать с текстом - важный навык работы с информацией.
  2. Если ответа на свой вопрос в тексте условия не увидели, задайте его в общем чате, мы раскроем детали условия подробнее. Не забудьте при этом скинуть и ссылку на условие задания, про которую у вас вопрос.

Что делать,если не получается задача?

Если ваша проблема это ошибка компиляции (подчёркивает красным, не даёт запустить программу), сборки проекта, CI и прочие подобные ошибки, то:

  1. Найдите и прочитайте текст ошибки, который вам подсвечивает реплит, идея (или логи); "подчёркивает красным" - это не описание ошибки.
  2. Попробуйте понять текст ошибки, при необходимости воспользуйтесь переводчиком. Нестрашно, если вы переведёте неточно, тут главное сам процесс: со временем и с нашей помощью вы будете это делать лучше и лучше, но, пропуская этот этап, вы не сможете научиться это делать.
  3. Если не получилось понять ошибку по её тексту, попробуйте её загуглить и изучить подобную ошибку у других людей. Попробуйте примерить решения их проблем на свой код. Соотнесите найденные описания ошибки с пройденной теорией.
  4. Если все равно вашу трудности не разрешились, напишите в общий чат, обязательно указав:
    1. Название задачи и ссылку на условие
    2. Ссылку на вашу работу
    3. Текст и скриншот (не фотография) ошибки.
    4. Ваши размышления и описание шагов, которые вы совершили для решения.

Если ваша проблема это ошибка исполнения (программа умирает уже после запуска) или она отрабатывает неправильно, то:

  1. Воспользуйтесь отладчиком для пошагового анализа работы вашей программы. Так вы либо убедитесь в неправильности придуманного вами алгоритма или найдёте конкретное место, где ожидаемое поведение программы разошлось с фактическим.
  2. Если проблему найти не получилось, напишите в общий чат, обязательно указав:
    1. Название задачи и ссылку на условие
    2. Ссылку на вашу работу
    3. Конкретное и подробное описание проблемы или затруднения при решении задачи ("Помогите что не так" - это не описание)
    4. Подробное описание вашего анализа программы с помощью отладчика вместе со скринами
    5. Ваши размышления и описание шагов, которые вы совершили для решения.

В решении выполнены все требования задания

Убедитесь, что все требования задания выполнены. Для этого перед отправкой внимательно прочтите весь текст условия задания и соотнесите сказанное в нём с вашим решением. Навык самопроверки работы перед ревью пригодится вам как при обучении, так и на работе.


Сдаём через гитхаб

Время пришло познакомиться с профессиональными инструментами для контроля версий вашего кода. Теперь мы не сдаём домашние задания в реплите, а заливаем проект из идеи сразу же в публичный гитхаб-репозиторий. Одна задача - один репозиторий.

Для того чтобы в репозитории не отслеживался всякий мусор, не забывайте добавлять .gitignore. В нём должны игнорироваться файлы идеи (правила *.iml и .idea), папки для автогенерируемых результатов сборки (out, позже - target). Этот файл должен находиться в корне вашего репозитория, а сам репозиторий должен быть инициализирован в корне вашего проекта. Т.е. открывая репозиторий вы должны сразу видеть папку src. Если вы забыли проигнорировать какие-либо файлы и они попали в репозиторий, используйте команду git rm.

Работаем с мавен-проектами

Эту и последующие задачи делаем в мавен-проектах. Gradle нельзя, как и сдавать без систем сборки. Убедитесь, что все нужные файлы закоммичены (pom.xml, src,..), а мусор проигнорирован (например, автосгенеренная target).


Задача 1 (обязательная)

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

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

Вместе с этим в другом методе (это может быть другой класс со вторым main методом или отдельный поток) подключитесь к этому серверу и отправьте ему одну строку.

Реализация

Запускаем сервер на определенном порту и принимаем соединение:

try (ServerSocket serverSocket = new ServerSocket(port);) { // порт можете выбрать любой в доступном диапазоне 0-65536. Но чтобы не нарваться на уже занятый - рекомендуем использовать около 8080
  try (Socket clientSocket = serverSocket.accept(); // ждем подключения
       PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
       BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
      ) {
      // ваш код
  }

Читаем строку и выводим её на экран вместе с номером порта клиента, с которого пришло соединение:

System.out.println("New connection accepted");

final String name = in.readLine();

out.println(String.format("Hi %s, your port is %d", name, clientSocket.getPort()));

Далее пишем клиента. Клиентом должна быть другая программа (просто ещё один метод main в другом классе, запускаемый параллельно, во время работы сервера) или второй поток. Обратите внимание, что хостом подключения будет localhost - это зарезервированный адрес для подключения к текущему компьютеру (то есть это ваш компьютер - там, где запущена программа). Также можно использовать 127.0.0.1 - это ip адрес, соответствующий доменному имени localhost

Задача 2 (НЕ обязательная)

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

Давайте непомним её правила. Игроки по очереди называют города, главное правило - следующий город должен начинаться на ту же букву, на которую заканчивался последний названный город.

В нашей игре игроками являются клиенты, подключающиеся к серверу; сервер лишь контролирует игру, сам в неё не играя.

Первый игрок (первый подключающийся после старта сервера клиент) на вход от сервера получает строку "???" - так клиент понимает, что он первый игрок и может назвать любой город. Назвать = отправить город в виде одной строки на сервер, сервер в ответ отправляет строку "OK".

Все остальные игроки (т.е. подключающиеся не первыми) получают при подключении на вход строку - последний введённый город в игре. Клиент в ответ отправляет город в виде одной строки; в ответ сервер отправляет либо строку "OK", если отправленный город начинался на букву на которую заканчивался последний город, иначе "NOT OK". В последнем случае введённый игроком город не учитывается для последующих игроков.

Каждый игрок подключается один раз и вводит только один город. Мы доверяем, что слово, введённое игроком - название города. Можно считать, что все города вводятся с маленькой буквы.

В этой задаче сервер будет принимать подключения в цикле:

      try (ServerSocket serverSocket = new ServerSocket(8989);) { // стартуем сервер один(!) раз
          while (true) { // в цикле(!) принимаем подключения
              try (
                      Socket socket = serverSocket.accept();
                      BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                      PrintWriter out = new PrintWriter(socket.getOutputStream());
                  ) {
                  // обработка одного подключения
              }
          }
      } catch (IOException e) {
          System.out.println("Не могу стартовать сервер");
          e.printStackTrace();
      }