Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.07.27;
Скачать: CL | DM;

Вниз

Свой протокол   Найти похожие ветки 

 
OrdJONY ©   (2007-08-24 21:22) [0]

Приветствую всех на этом форуме. Появилась идея сделать что-то подобное протоколу аськи. Тоесть написать сервак и клиент естесно)).
Столкнулся с множеством проблем, хочу написать на 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, тоесть данное подключение.


 
grisme ©   (2007-08-26 19:56) [1]


> +На компе юзера может запускатся несколько клиентов, как
> сделать чтобы сообщение клиенту отправлялось не на IP а
> именно на Thread, тоесть данное подключение.


ну что ты, что ты :) "так" и будет.


 
Сергей М. ©   (2007-08-27 08:48) [2]


> хочу написать на Indy. Хотелось бы увидеть простенький пример
> взаимодействия TIdTCPServer и TIdTCPClient


http://www.indyproject.org/Sockets/Demos/index.EN.aspx


> сообщение клиенту отправлялось не на IP а именно на Thread


В 9-ке в обработчике OnExecute:

PeerThread.Connection.SendXXX


 
OrdJONY ©   (2007-08-28 00:18) [3]


> В 9-ке в обработчике OnExecute:PeerThread.Connection.SendXXX

а если сообщение нужно отправить не по обработчику OnExecute, а вот что-то произошло на сервере и нужно юзеру отправить это???


 
Сергей М. ©   (2007-08-28 08:25) [4]

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


 
DVM ©   (2007-08-28 23:12) [5]


> хочу написать на Indy. Хотелось бы увидеть простенький пример
> взаимодействия TIdTCPServer и TIdTCPClient:

Не лучший имхо вариант.


 
DiamondShark ©   (2007-09-03 14:23) [6]

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


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


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


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

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


 
OrdJONY ©   (2007-09-25 14:27) [8]

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


 
DVM ©   (2007-09-25 14:49) [9]


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

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


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


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


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

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


 
DVM ©   (2007-09-25 16:01) [11]


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

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


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


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


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

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


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


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

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


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


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


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

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


 
OrdJONY ©   (2007-09-25 16:58) [15]

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


 
DVM ©   (2007-09-25 17:02) [16]


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

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

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

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

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

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


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


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

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


 
DVM ©   (2007-09-25 17:05) [18]


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

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


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


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


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


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


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


 
umbra ©   (2007-09-25 17:23) [20]

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


 
OrdJONY ©   (2007-09-25 19:50) [21]


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

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


 
DVM ©   (2007-09-25 21:39) [22]


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

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


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 23:17) [23]


>   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 23:19) [24]


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

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


 
OrdJONY ©   (2007-09-26 10:21) [25]

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



Страницы: 1 вся ветка

Текущий архив: 2008.07.27;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.02 c
2-1214480489
lewka-serdceed
2008-06-26 15:41
2008.07.27
Поиск слова в строке


6-1190719291
mefodiy
2007-09-25 15:21
2008.07.27
Скачивание информации о курсах валют


2-1214382141
Jimmy
2008-06-25 12:22
2008.07.27
RunTimeError 216


15-1212825413
Vlad Oshin
2008-06-07 11:56
2008.07.27
чем С# вкусна?


15-1212760713
Vlad Oshin
2008-06-06 17:58
2008.07.27
моя плакаю. Бросаем delphi, переходим на С под NET