Подходы к программированию протоколов прикладного уровня? - PullRequest
0 голосов
/ 20 апреля 2011

Я занимаюсь простым программированием сокетов на C #.Я пытаюсь аутентифицировать пользователя, считывая имя пользователя и пароль с клиентской консоли, отправляя учетные данные на сервер и возвращая статус аутентификации с сервера.Основные вещи.У меня вопрос: как мне обеспечить, чтобы данные были в формате, который сервер и клиент ожидают ?

Например, вот как я читаю учетные данные пользователя на клиенте:

                Console.WriteLine("Enter username: ");
                string username = Console.ReadLine();
                Console.WriteLine("Enter plassword: ");
                string password = Console.ReadLine();

                StreamWriter clientSocketWriter = new StreamWriter(new NetworkStream(clientSocket));
                clientSocketWriter.WriteLine(username + ":" + password);
                clientSocketWriter.Flush();

Здесь я разделяю имя пользователя и пароль двоеточием (или другим символом) на стороне клиента,На сервере я просто разделяю строку, используя «:» в качестве токена.Это работает, но кажется вроде ... небезопасно.Разве не должно быть какого-то токена-разделителя, который является общим между клиентом и сервером, поэтому мне не нужно просто жестко кодировать его вот так?

Это похоже наответ сервера.Если аутентификация прошла успешно, как мне отправить ответ обратно в формате, который ожидает клиент?Могу ли я просто отправить строку «SUCCESS» или «AuthSuccessful = True / False»?Как бы я мог убедиться, что клиент знает, в каком формате сервер отправляет данные (кроме простого кодирования их в клиент)?

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

Ответы [ 4 ]

1 голос
/ 20 апреля 2011

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

Ваши сообщения, безусловно, будут длиннее, но с Gigabyte Ethernet и ADSL это вряд ли имеет значение в наши дни. То, что вы получаете, - это протокол, в котором все проблемы с наборами символов, сложными структурами данных уже решены, а также смущающий выбор инструментов и библиотек для поддержки и облегчения вашей разработки.

0 голосов
/ 14 июня 2011

Я настоятельно рекомендую использовать простой текст ASCII , если это вообще возможно.Это значительно упрощает обнаружение и исправление ошибок.

Некоторые распространенные, машиночитаемые текстовые протоколы ASCII (примерно в порядке сложности):

Мир уже достаточно сложен, поэтому я пытаюсь использовать наименее сложный протокол, который будет работать.Отправка двух сгенерированных пользователем строк с одного компьютера на другой - netstrings - это самый простой протокол в моем списке, который бы сработал, поэтому я выбрал netstrings.(netstrings будет работать нормально, даже если пользователь введет несколько двоеточий или точек с запятой или двойные кавычки или табуляции - в отличие от других форматов, которые задыхаются от некоторых часто вводимых символов).

Я согласен, что этобыло бы неплохо, если бы существовал какой-либо способ описания протокола в одном общем файле, чтобы и сервер, и клиент могли как-то «#include» или иным образом использовать этот протокол.Затем, когда я исправляю ошибку в протоколе, я могу исправить ее в одном месте, перекомпилировать сервер и клиент, и тогда все будет просто работать - вместо того, чтобы копаться в связке аппаратных констант с обеих сторон.

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

Скажите, если вы обнаружите что-нибудь подобное, хорошо?

0 голосов
/ 20 апреля 2011

Я работал с двумя основными подходами.

Сначала протокол ascii.

Протокол на основе Ascii обычно основан на наборе текстовых команд, которые заканчиваются на некотором определенном разделителе (например, возврат каретки или точка с запятой, xml или json). Если ваш протокол является протоколом, основанным на командах, где не так много данных передается туда и обратно, тогда это лучший способ.

FIND\r
DO_SOMETHING\r

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

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

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

0 голосов
/ 20 апреля 2011

По сути, вы ищете стандарт.«Самое замечательное в стандартах - это то, что есть из чего выбирать».Выбери один и иди с ним, это намного проще, чем прокатить свой собственный.В этой конкретной ситуации рассмотрим «базовую» аутентификацию Apache, которая объединяет имя пользователя и пароль и кодирует base64 как одну из возможностей.

...