Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Свой протокол [D7, WinXP]


Страницы:   1 2

OrdJONY ©   (2007-08-24 21:22:00) 

Приветствую всех на этом форуме. Появилась идея сделать что-то подобное протоколу аськи. Тоесть написать сервак и клиент естесно)).
Столкнулся с множеством проблем, хочу написать на Indy. Хотелось бы увидеть простенький пример взаимодействия TIdTCPServer и TIdTCPClient:
Login <Name User> <Password>;{Это авторизация, после успешной авторизации, данному юзеру отправляется сообщение LoginOK, а остальным UserOnline}
SendMessage <Name User> <Text Msg>;{Имя Юзера и текст сообщения посылается на серв, а потом после обработки должно прийти второму юзеру командой incomingMessage}
Disconect;{С этим все понятно и какой ответ будет на это сообщение}
Это команды на сервере, а вот команды на клиенте:
LoginOK;{Это когда принят логин и пароль ответ сервера}
UserOnline <Name User>;{Когда Юзер входит в сеть}
incomingMessage <Name User> <Text Msg>;{Пришло сообщение, тут видимо разделители нужно использовать не пробелы, чтобы сообщение он нормально в параметры загнал}
+На компе юзера может запускатся несколько клиентов, как сделать чтобы сообщение клиенту отправлялось не на IP а именно на Thread, тоесть данное подключение.


OrdJONY   (2007-09-26 10:21:00) [1]

Спасибо вам за помощь DVM!!!


DVM   (2007-09-25 23:19:00) [2]


> а что это за значения??? Разъясните пожалуйста

Это от балды взятые числа. Ты туда свои пиши.


OrdJONY   (2007-09-25 23:17:00) [3]


>   SendBuff[1] := $6;  SendBuff[2] := $2;  SendBuff[3] :=
> $0;  SendBuff[4] := $A;  SendBuff[5] := $0;  SendBuff[6]
> := $3;  SendBuff[7] := $1;

а что это за значения??? Разъясните пожалуйста


DVM   (2007-09-25 21:39:00) [4]


> а потом прочитать его

Тебе через инди что ли? Ну вот совсем примитивно:


procedure TfrmMain.btnSendTCPCommandClick(Sender: TObject);
var
 SendBuff: array[1..14] of byte;
 RecvBuff: array[1..12] of byte;
 res: string;
 i: integer;
begin
 IdTCPClient.Host := edtHost.Text;
 IdTCPClient.Port := spnedtPort.Value;
 try
   IdTCPClient.Connect;
 except
   // ошибка
 end;
 
 SendBuff[1] := $6;
 SendBuff[2] := $2;
 SendBuff[3] := $0;
 SendBuff[4] := $A;
 SendBuff[5] := $0;
 SendBuff[6] := $3;
 SendBuff[7] := $1;
 .....
 .....
 .....

 if IdTCPClient.Connected then
   begin
     IdTCPClient.WriteBuffer(SendBuff, SizeOf(SendBuff), true);
     IdTCPClient.ReadBuffer(RecvBuff, SizeOf(RecvBuff));
   end;

 IF IdTCPClient.Connected then IdTCPClient.Disconnect;
end;


OrdJONY   (2007-09-25 19:50:00) [5]


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

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


umbra   (2007-09-25 17:23:00) [6]

для упрощения подобных изобретений в инди 9 у TIdTCPServerесть коллекция CommandHanlers, а в инди 10 - отдельный компонент TIdCmdTCPServer.


Сергей М.   (2007-09-25 17:19:00) [7]


> Мы читаем, читаем, когда остановиться то?


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


> Мы допустим не знаем длину очередной команды


Тогда те самые метки и нужны. Но, повторяю, это не случай автора, в его случае на принимающей стороне в каждый момент времени известно, сколько "весит" очередной принимаемый пакет.


DVM   (2007-09-25 17:05:00) [8]


> напишите плиз такой примерчик.

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


DVM   (2007-09-25 17:03:00) [9]


> напишите плиз такой примерчик.

тут не примерчик а примерище огромный.


DVM   (2007-09-25 17:02:00) [10]


> А нафих читать пол-второй команды, если к первой она не
> относится ?)

Ну а как мы узнаем, что первая команда то кончилась? Мы читаем, читаем, когда остановиться то? Мы допустим не знаем длину очередной команды.

> Но это не случай автора.

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

COMMAND: MESSAGE FROM: VASYA TO: PETYA MESSAGETEXT: BLA-BLA-BLA

вот размер этих BLA-BLA-BLA нам и неизвестен. Т.е. когда остановиться мы не знаем. Поэтому либо поле размер надо ввести, либо разделитель, а лучше и то и другое.


OrdJONY   (2007-09-25 16:58:00) [11]

напишите плиз такой примерчик. А то вот читаю и пока собственно непонял как реализовать мною написанное ))


Сергей М.   (2007-09-25 16:30:00) [12]


> при пересылке может получиться что в приемном буфере после
> очередной операции чтения окажется первая команда и половина
> второй. Вот чтобы первую отделить метки и понадобятся


А нафих читать пол-второй команды, если к первой она не относится ?)

Метки те самые нужны только тогда, когда протокол не предусматривает никакой инф-ции о полном размере инф.сообщений. Но это не случай автора.


DVM   (2007-09-25 16:16:00) [13]


> На и нужны поля ид-ра сессии и контр.суммы.

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


Сергей М.   (2007-09-25 16:08:00) [14]


> DVM ©   (25.09.07 16:01) [11]


На и нужны поля ид-ра сессии и контр.суммы.

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


DVM   (2007-09-25 16:01:00) [15]


> Совершенно лишнее это.

Я думаю все же не лишнее. Например, не исключена ситуация, когда клиент подключится не к своему родному серверу а еще к чему то там. И этот левый сервер вышлет какой то набор байт, который клиент примет. Но этот набор байт будет содержать некорректную информацию. Если же начло и конец буфера будут помечены (например как у JPEG FFD8 FFD9), то это в какой то степени повысит вероятность того, что принятый нами блок данных это данные нашего формата, а не что то постороннее.


Сергей М.   (2007-09-25 15:44:00) [16]


> желательно чтобы начало и конец буфера были как то помечены,
>  чтобы знать, что получены полные данные


Совершенно лишнее это.

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


DVM   (2007-09-25 14:49:00) [17]


> Это все надо собрать в один пакет и отослать.

пакеты тут не при чем. Собирай все в буфер array[0..xx] of byte и отсылай его. Причем желательно чтобы начало и конец буфера были как то помечены, чтобы знать, что получены полные данные.


OrdJONY   (2007-09-25 14:27:00) [18]

Расскажите как собирать пакет, а потом его читать. Заголовок у пакета всегда должен быть фиксированной длинны 8 байт. VerProto (1 Байт, принимает значение от 1, 2, 3, 4...), NumCmd (2 байта, сдесь случайное число), IDService (1 байт, аналогично VerProto), SizeData (4 байта, размер данных); Далее следуют данные, размер их указывает в заголовке в SizeData. Это все надо собрать в один пакет и отослать. На приемнике нужно разобрать сначала зоголовок, а потом вытянуть из сокета SizeData байт.
Помогите, кто чем может ))


Сергей М.   (2007-09-03 14:40:00) [19]


> DiamondShark ©   (03.09.07 14:23) [6]


Вот ведь беда !

Как же это Борланд и прочие разработчики забыли у тебя спросить ?)


DiamondShark   (2007-09-03 14:23:00) [20]

Я всегда говорил, что компоненты поверх WinSock -- это искусственная сложность.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо