Домашнее задание: TCP чат

В рамках данной работы необходимо разработать сетевой протокол для чата. Для его проверки нужно разработать серверное и клиентское Программное Обеспечение (ПО).

Стоит помнить, что вы разрабатываете в первую очередь протокол. Это значит, что автор клиента для одного и того же протокола (вашего) волен реализовать любую форму отображения сообщения. В случае консольного клиента:

<4:20> [Kenobi] Hello there!

А в случае графического:

An image of a chat bubble

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

Требования к протоколу:

  • Пользователь может отправлять сообщения только от своего имени
  • Время в сообщение должно соответствовать реальному времени отправления сообщения
  • Пользователи разных временных зон должны видеть корректное для себя время

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

Требования к ПО:

  • ПО имеет консольный интерфейс
  • Прямое использование TCP сокетов (без дополнительных абстракций)
  • К одному серверу может подключаются множество клиентов
  • Отправляемое сообщение отображается у каждого подключенного в этот момент клиента (т.е. хранение и отображение истории реализовывать не требуется)
  • Всем пользователям приходит уведомление о подключение/отключение очередного пользователя

Требования к отчёту:

  • Инструкция по использованию (конфигурационные файлы, переменные окружения, аргументы командной строки, данные передаваемые в stdin)
  • Инструкции по сборке/установке
  • Описание используемого сетевого протокола

Life pro tips

  • Пользовательский интерфейс - дело не последнее, но он не является центром данной лабораторной работы
  • Ваш протокол будет проверятся на способность справляться с различными данными (содержание и объём)
  • Преподавательский состав данного курса позитивно относится к бережному отношению к ресурсам

Типичные ошибки

Ваши коллеги уже наступали на эти грабли, учитесь на чужих ошибках.

Использование строк вместо протокола

Основой данного задания является разработка протокола, а код - лишь проверка его работоспособности. Существование протокола в отрыве от конкретной имлементации позволяет легко создать новую. Например, с вашим сервером одновременно могут общаться совершенно разные клиенты: консольные, графические, вэб и боты, которым пользовательский интерфэйс чата совсем не нужен. Каждый из этих клиентов может по своему отображать данные. Так графические интерфейсы обычно не указывают имя автора у каждого из его подряд отправленных сообщений, а время отображают отдельно от текста сообщения. Наличие протокола позволяет им легко этого добиться, ведь в нём все эти элементы “разложены по полочкам”, а не спрятаны в рамках огромной строки.

Вторая проблема - подтверждение подлинности. В строке можно указать любое имя пользователя и другие клиенты не смогут отличить реального пользователя от самозванца. Время тоже никак не подтверждается. Вам студенты будут рассказывать, что сдали свою работу до дедлайна, ссылаясь на сообщение с отчётом, в котором указана дата ещё до выдачи задания о.О Ведь никто не мешает составить сообщение с любым временем, хоть <half past nine>

Ещё одна проблема на ровном месте - искусственное ограничение используемых символов в сообщение. Теперь в имени пользователя не может быть как минимум символ и ], ведь с точки зрения клиента это специальный символ окончания имени пользователя.

Одно сообщение - одно чтение буфера

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

Методика проверки

  • Запуск
    • сервера и клиента на разных узлах
    • минимум 2х клиентов на одном узле
  • Отправление сообщения
    • от имени другого пользователя
    • со временем на 3 часа раньше текущего
    • с текстом на 5 мегабайт

TODO: добавить описание типичных тестов, для проверки реализации (например, минимальный объём для большого текста, атака на протокол)