-
Приветствую всех на этом форуме. Появилась идея сделать что-то подобное протоколу аськи. Тоесть написать сервак и клиент естесно)). Столкнулся с множеством проблем, хочу написать на 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, тоесть данное подключение.
-
> +На компе юзера может запускатся несколько клиентов, как > сделать чтобы сообщение клиенту отправлялось не на IP а > именно на Thread, тоесть данное подключение.
ну что ты, что ты :) "так" и будет.
-
> хочу написать на Indy. Хотелось бы увидеть простенький пример > взаимодействия TIdTCPServer и TIdTCPClient http://www.indyproject.org/Sockets/Demos/index.EN.aspx > сообщение клиенту отправлялось не на IP а именно на Thread
В 9-ке в обработчике OnExecute: PeerThread.Connection.SendXXX
-
> В 9-ке в обработчике OnExecute:PeerThread.Connection.SendXXX
а если сообщение нужно отправить не по обработчику OnExecute, а вот что-то произошло на сервере и нужно юзеру отправить это???
-
Тогда поток, ответственный за контроль над "что-то произошло на сервере", должен тем или иным образом известить PeerThread юзера о том, что "это" следует отправить юзеру.
-
> хочу написать на Indy. Хотелось бы увидеть простенький пример > взаимодействия TIdTCPServer и TIdTCPClient:
Не лучший имхо вариант.
-
Я всегда говорил, что компоненты поверх WinSock -- это искусственная сложность.
-
> DiamondShark © (03.09.07 14:23) [6]
Вот ведь беда !
Как же это Борланд и прочие разработчики забыли у тебя спросить ?)
-
Расскажите как собирать пакет, а потом его читать. Заголовок у пакета всегда должен быть фиксированной длинны 8 байт. VerProto (1 Байт, принимает значение от 1, 2, 3, 4...), NumCmd (2 байта, сдесь случайное число), IDService (1 байт, аналогично VerProto), SizeData (4 байта, размер данных); Далее следуют данные, размер их указывает в заголовке в SizeData. Это все надо собрать в один пакет и отослать. На приемнике нужно разобрать сначала зоголовок, а потом вытянуть из сокета SizeData байт. Помогите, кто чем может ))
-
> Это все надо собрать в один пакет и отослать.
пакеты тут не при чем. Собирай все в буфер array[0..xx] of byte и отсылай его. Причем желательно чтобы начало и конец буфера были как то помечены, чтобы знать, что получены полные данные.
-
> желательно чтобы начало и конец буфера были как то помечены, > чтобы знать, что получены полные данные
Совершенно лишнее это.
На транспортном уровне доставка потока гарантирована в оригинальной последовательности, а на прикладном уровне инф-ция о данных переменного размера, следующих за заголовком, фигурирует в самом заголовке фикс.размера. "Промахнуться" с приемом "пакета" в таких условиях практически невозможно. Для самоуспокоения и пущей уверенности можно в заголовке предусмотреть поля ид-ра сессии и контрольной суммы.
-
> Совершенно лишнее это.
Я думаю все же не лишнее. Например, не исключена ситуация, когда клиент подключится не к своему родному серверу а еще к чему то там. И этот левый сервер вышлет какой то набор байт, который клиент примет. Но этот набор байт будет содержать некорректную информацию. Если же начло и конец буфера будут помечены (например как у JPEG FFD8 FFD9), то это в какой то степени повысит вероятность того, что принятый нами блок данных это данные нашего формата, а не что то постороннее.
-
> DVM © (25.09.07 16:01) [11]
На и нужны поля ид-ра сессии и контр.суммы.
Вероятность их подделки ничтожна мала, а уж случайного совпадения и подавно. Если бы было иначе, то, к примеру, аськина сеть давным-давно бы перестала существовать как ненадежная в плане безопасности.
-
> На и нужны поля ид-ра сессии и контр.суммы.
Ну или так. Я правда не о безопасности толкую, а о том чтобы потом в принимаемом потоке данных блоки команд удобно было бы выделять по этим разделителям. Особенно если эти блоки не имеют фиксированного размера. Ведь при пересылке может получиться что в приемном буфере после очередной операции чтения окажется первая команда и половина второй. Вот чтобы первую отделить метки и понадобятся.
-
> при пересылке может получиться что в приемном буфере после > очередной операции чтения окажется первая команда и половина > второй. Вот чтобы первую отделить метки и понадобятся
А нафих читать пол-второй команды, если к первой она не относится ?)
Метки те самые нужны только тогда, когда протокол не предусматривает никакой инф-ции о полном размере инф.сообщений. Но это не случай автора.
-
напишите плиз такой примерчик. А то вот читаю и пока собственно непонял как реализовать мною написанное ))
-
> А нафих читать пол-второй команды, если к первой она не > относится ?)
Ну а как мы узнаем, что первая команда то кончилась? Мы читаем, читаем, когда остановиться то? Мы допустим не знаем длину очередной команды.
> Но это не случай автора.
А помоему это как раз случай автора. Допустим, один юзер шлет другому предложение. Команда в общем случае будет выглядеть как:
COMMAND: MESSAGE FROM: VASYA TO: PETYA MESSAGETEXT: BLA-BLA-BLA
вот размер этих BLA-BLA-BLA нам и неизвестен. Т.е. когда остановиться мы не знаем. Поэтому либо поле размер надо ввести, либо разделитель, а лучше и то и другое.
-
> напишите плиз такой примерчик.
тут не примерчик а примерище огромный.
-
> напишите плиз такой примерчик.
одна тема логина на сервер чего стоит, если безопасную проверку пароля организовать, т.е не пересылать пароль в открытом виде.
-
> Мы читаем, читаем, когда остановиться то?
Читать нужно ровно столько, сколько осталось прочитать до получения текущего пакета, размер которого указан в заголовке. Прочитанное аккумулируем, инкрементируем сч-к принятых байт тек.пакета на размер актуально прочитанных данных, сравниваем со значением в поле размера в заголовке, при обнаружении совпадения считаем тек.пакет полностью принятым, обрабатываем его и только после этого начинаем читать очер.пакет.
> Мы допустим не знаем длину очередной команды
Тогда те самые метки и нужны. Но, повторяю, это не случай автора, в его случае на принимающей стороне в каждый момент времени известно, сколько "весит" очередной принимаемый пакет.
-
для упрощения подобных изобретений в инди 9 у TIdTCPServer есть коллекция CommandHanlers , а в инди 10 - отдельный компонент TIdCmdTCPServer .
-
> одна тема логина на сервер чего стоит, если безопасную проверку > пароля организовать, т.е не пересылать пароль в открытом > виде.
Да не надо мне безопасная проверка пароля. Напишите простенький пример, как собрать такой пакет, а потом прочитать его. Пример относится только к пакету
-
> а потом прочитать его
Тебе через инди что ли? Ну вот совсем примитивно:
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;
-
> SendBuff[1] := $6; SendBuff[2] := $2; SendBuff[3] := > $0; SendBuff[4] := $A; SendBuff[5] := $0; SendBuff[6] > := $3; SendBuff[7] := $1;
а что это за значения??? Разъясните пожалуйста
-
> а что это за значения??? Разъясните пожалуйста
Это от балды взятые числа. Ты туда свои пиши.
-
Спасибо вам за помощь DVM!!!
|