Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Сети > Совет по сокетам


Автор: Racer 28.3.2011, 21:29
Добрый день, сообщество кодеров.

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

Так вот это я и не пойму. Пишу на client / server socket. Есть событие, когда клиент соединяется. но как его применить для многоразовых запросов? Или сначала его подключить, а потом работать с ним на предмет паролей и  т.п.? 

Может кто уже делал такое? Прошу у Вас советов.

Заранее спасибо

Автор: Данкинг 28.3.2011, 21:40
Не совсем понял, какие многоразовые запросы? У сервера же есть свойство Socket.Connections - оно нужно, что ли?

Автор: kami 29.3.2011, 07:31
Цитата(Racer @  28.3.2011,  21:29 Найти цитируемый пост)
Пишу сетевое приложение. По условиям поставленной задачи надо клиентов авторизовать. То есть он конектиться, спросить у него юзернейм, пароль, проверочный код. Если все верно то подключить его. 

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

Цитата(Racer @  28.3.2011,  21:29 Найти цитируемый пост)
Есть событие, когда клиент соединяется. но как его применить для многоразовых запросов?

Событие OnConnect может служить только сигналом "можно начинать сетевой обмен", то есть - спрашивать логин, пароль и т.п. В дальнейшем работа (в режиме ctNonBlocking) ведется через события OnRead и OnWrite. И хоть сотню запросов сразу отправляй корреспонденту. Если грамотно организован протокол обмена, т.е. принимающий (без разницы - клиент или сервер) сможет без труда отличить конец одних данных от начала других, то никаких проблем с "многоразовыми запросами" не возникнет.

Автор: Racer 30.3.2011, 08:34
On connect я понимаю. А вот когда возникает on accept?

Автор: kami 30.3.2011, 11:37
Цитата(Racer @  30.3.2011,  08:34 Найти цитируемый пост)
 А вот когда возникает on accept?

А справку почитать?

Автор: Racer 6.4.2011, 22:17
Возможно я не так задал вопрос(скорее всего). Попытаюсь объяснить еще раз.

К серверу можно подключиться. У юзера есть имя и пароль. Когда он соединяется, надо у него запросить их, сравнить с БД, и работать с ним если допускается системой или отклонить соединение.

Что я не могу понять? Он соединяется - сработал onConnect. что мне дальше делать? Как мне спрашивать пароли? Как отсоединить его? 

И вот еще что: есть как бы 2 системы независимых. согласно БД пользователя можно подключить либо к 1 либо ко 2. Как лучше сделать? 1 приветственный сокет, 2 для 1системы, 3 для 2 системы? Но тогда выходит что 3 порта открыто...

Автор: kami 6.4.2011, 22:55
Racer, нужен свой протокол обмена. Я давно уже пользуюсь только одним соединением между клиентом и сервером, через которое передается всё что угодно, начиная от запроса авторизации, заканчивая файлами. И всё - с соблюдением приоритетов передачи.
Если вкратце, словесный алгоритм :
1. произошло OnConnect. Сервер в этом событии отправляет клиенту запрос "ты кто". Клиент - тупо ждет (ну, тут всё зависит от того, что нужно, например, клиент может сказать первым "я готов к обмену", и только в ответ на это сервер даст запрос).
2. Клиент, приняв запрос, спрашивает логин и пароль у пользователя, после чего передает их серверу. (тут - отдельная тема про безопасность передачи учетных данных).
3. Сервер, приняв учетные данные, отправляет клиенту "ты подключен, спрашивай что нужно", или "какая-то ошибка при авторизации, вернемся на шаг 2"
4. Клиент, приняв "ты подключен", решает, к какой системе ему нужно подключиться и отправляет запрос "хочу систему №Х".
и так далее.

Само собой - не нужно передавать все эти команды "словами", т.е. - в строковом виде. Вполне достаточно присвоить каждой численный идентификатор ("ты кто" = 1; "я такой-то" = 2 и так далее), что значительно упростит их обработку (case of вместо кучи if ).

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

Например, данные могут представляться так:
Заголовок:
1. Номер_команды: integer;
2. Дополнительный_параметр команды: integer;
3. Длина_сопровождаемых_этим_заголовком_данных: integer ( или int64, в зависимости от предполагаемого объема к передаче);
4. Контрольная_сумма: ... (можно и без нее)
5. Сами_данные_в_удобном_для_работы_виде.

Вся работа по непосредственной передаче/приему подготовленных таким образом (и "сброшенных" в спец.буфер) данных производится в событиях OnWrite и OnRead. За дальнейшими пояснениями (действительно, это в 2 словах не расскажешь) - http://forum.vingrad.ru/forum/topic-290376/anchor-entry2090440/0.html.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)