Форум: "Сети";
Текущий архив: 2008.07.27;
Скачать: [xml.tar.bz2];
ВнизСвой протокол Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.008 c