![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
TIdCmdTCPServer
Zalm © (2009-08-31 13:14:00)Здравствуйте, как у TIdCmdTCPServer можно всем клиентам разослать сообщение? Надо например каждому отослать команду. Это должно быть естественно в цикле, только я не знаю как и где. У TServerSocket было проще всё, ну или понятней.
1)Вот например у меня есть кнопка на сервере, как сделать чтоб ы при нажатии на кнопку каждому подключению что-то отправить, и что бы узнать его адрес там и тд?
2) Как узнать ip и handler подключения? и в каком евенте... если в OnConnect то я не опнля как...
3) Как вне событий отправить текст на подключение с известным адресом\обработчкиом?
Буду очень благодарен за помощь.
Zalm (2009-09-17 16:51:00) [41]
> Зато почему-то с радостью согласился разместить на сервере
> совершенно сырой, абсолютно не продуманный софт)
Софт отвечает всем требованиям которые я к нему предъявляю)
> Что мешает Васе отправить Пете строку \data\ ?Ничто не мешает.
> И Петя эту самую \data\ никогда получит, ибо сервер, по
> твоим же словам, распознает это сочетание последовательно
> идущих символов как команду.
Сервер не предназначем для чата) так что никто не пришлет того что не предусмотрено... Трафик между парами определен протоколом другим (клиента, и псевдо-сервера), а в этом протоколе нет команд которые равнозначны "техническим" командам сервера)
Вобщем меня теперь больше интересует код, знаю у вас будет кучу плохих слов на счет моего кода, но всё же я тут для того что бы научиться)
procedure TForm1.ServerExecute(AContext: TIdContext);
var
MSG : string;
I, J : integer;
List : Tlist;
_ip : string;
_port : word;
key : string;
begin
msg:=AContext.Connection.Socket.ReadLn();
{----------------------------------------}
for i := 0 to Clients.Count - 1 do
begin
if ((Clients.Clients[i].SIP=AContext.Connection.Socket.Binding.PeerIP)and(Clients.C lients[i].SPort=AContext.Connection.Socket.Binding.PeerPort))or
((Clients.Clients[i].PIP=Acontext.Connection.Socket.Binding.PeerIP)and(Clients.C lients[i].PPort=AContext.Connection.Socket.Binding.PeerPort)) then
begin
if (Clients.Clients[i].SIP=AContext.Connection.Socket.Binding.PeerIP)and
(Clients.Clients[i].SPort=AContext.Connection.Socket.Binding.PeerPort) then
begin
_ip:=Clients.Clients[i].PIP;
if _ip='' then
begin
AContext.Connection.Socket.WriteLn('No send.');
exit;
end;
_port:=Clients.Clients[i].PPort;
Send(_ip,_port,msg);
exit;
end
else
begin
_ip:=Clients.Clients[i].SIP;
if _ip='' then
begin
AContext.Connection.Socket.WriteLn('No send.');
exit;
end;
_port:=Clients.Clients[i].SPort;
Send(_ip,_port,msg);
exit;
end;
end
else
begin
{...}
end;
end;
end;
Procedure Send (ip:string;port:word;str:string);
var
i : integer;
List : Tlist;
begin
try
LIst:=Form1.Server.Contexts.LockList;
for I := 0 to List.Count - 1 do
with TidContext(List[i]) do
begin
if (connection.Socket.Binding.PeerIP=ip)and(connection.Socket.Binding.PeerPort=port ) then
begin
TidCOntext(list[i]).Connection.Socket.WriteLn(str);
exit;
end;
end;
finally
Form1.Server.Contexts.UnlockList;
end;
end;
Вопросы такие, что будет если кто-то из клиентов соберется что-то отправить, в то время как УЖЕ будет работать процедура Send вызванная предыдущим клиентом?
Type
_Pack = record
SIP : string[15];
SPort : WORD;
PIP : string[15];
PPort : Word;
Index : String[10];
end;
_Clients = class
pack : _pack;
Clients : Array of _pack;
Count : integer;
end;
var
Form1: TForm1;
Clients : _Clients;
procedure TForm1.ServerConnect(AContext: TIdContext);
var
str, IP : string;
I : integer;
Port:Word;
KEY_CHECK : String;
begin
KEY_CHECK:=Acontext.Connection.Socket.Readln();
if edit1.Text<>KEY_CHECK then Acontext.Connection.Disconnect;
AContext.Connection.Socket.Writeln('Index[<=10]');
str:=Acontext.Connection.Socket.ReadLn();
if length(str)>10 then Acontext.Connection.Disconnect;
for I := 0 to Clients.Count - 1 do
begin
if Clients.Clients[i].Index=str then
begin
if Clients.Clients[i].SIP='' then
begin
Clients.Clients[i].SIP:=Acontext.Connection.Socket.Binding.PeerIP;
Clients.Clients[i].SPort:=AContext.Connection.Socket.Binding.PeerPort;
Acontext.Connection.Socket.WriteLn('srd');
exit;
end;
if Clients.Clients[i].PIP='' then
begin
Clients.Clients[i].PIP:=Acontext.Connection.Socket.Binding.PeerIP;
Clients.Clients[i].PPort:=AContext.Connection.Socket.Binding.PeerPort;
Acontext.Connection.Socket.WriteLn('srd');
exit;
end;
AContext.Connection.Disconnect;
exit;
end;
end;
inc(Clients.Count);
SetLength(Clients.Clients,Clients.Count);
Clients.Clients[Clients.Count-1].SIP:=AContext.Connection.Socket.Binding.PeerIP;
Clients.Clients[Clients.Count-1].SPort:=AContext.Connection.Socket.Binding.PeerPort;
Clients.Clients[Clients.Count-1].Index:=str;
Acontext.Connection.Socket.WriteLn('srd');
end;
procedure TForm1.ServerDisconnect(AContext: TIdContext);
var
i, j : integer;
begin
for i := 0 to Clients.Count - 1 do
begin
if (Clients.Clients[i].SIP+':'+IntToStr(Clients.Clients[i].SPort)=AContext.Connection.Socket.Binding.PeerIP+':'+IntToStr(AContext.Connection.Socket.Binding.PeerPort)) then
begin
Clients.Clients[i].SIP:='';
Clients.Clients[i].SPort:=0;
break;
end;
if (Clients.Clients[i].PIP+':'+IntToStr(Clients.Clients[i].PPort)=AContext.Connection.Socket.Binding.PeerIP+':'+IntToStr(AContext.Connection.Socket.Binding.PeerPort)) then
begin
Clients.Clients[i].PIP:='';
Clients.Clients[i].PPort:=0;
break;
end;
end;
if (clients.Clients[i].SIP='')and(clients.Clients[i].PIP='') then
begin
for j := i to clients.Count - 1 do
Clients.Clients[j]:=Clients.Clients[j+1];
dec(clients.Count);
SetLength(clients.Clients,Clients.Count);
end;
end;
Процедуры подключения и отключения клиентов используют один и тот же массив, что будет когда неск клиентов столкнутся на одном и том же массиве, в том смысле то есть что он им обоим будет нужен сразу?
Сергей М. (2009-09-17 15:56:00) [42]
> а какая разница?
По твоему значит нет разницы ?
Ну раз нет, тогда почему твои "пары" должны ходить через твой сервер ?
Пусть напрямую друг к другу и ходят, ничто ведь им не мешает : адреса им выделены, а маршрутизируемы ли эти адреса в условиях глобальнойсети - тебе по барабану))
> команды \<Превед !>\ по протоколу он не знает, а знает команду
> Превед !
Как это не знает ?
Цитирую твое же высказывание:
> команды имеют такой синтаксис \<команда>\
Чем строка \< Превед !>\ не команда Превед !?
Синтаксис соблюден, строковый идентификатор соответствует ожтидаемому..
> Например есть команда \data\, он выполнит и не отошлет её
> дальше, а если написать /data/ или \data\\ то он сраже передаст
> их без всякого
Что мешает Васе отправить Пете строку \data\ ?
Ничто не мешает.
И Петя эту самую \data\ никогда получит, ибо сервер, по твоим же словам, распознает это сочетание последовательно идущих символов как команду.
> команды \<Превед !>\ по протоколу он не знает, а знает команду
> Превед !
Опять же, Васе взбрендило послать не \< Превед !>\, а Превед !..
Чем не команда, по твоим словам, ожидаемая сервером ?
> наш администратор сказал что VPN у нас нет и никогда не
> будет на сервере, почему, он внятно и не объяснил
Зато почему-то с радостью согласился разместить на сервере совершенно сырой, абсолютно не продуманный софт)
Zalm (2009-09-17 15:22:00) [43]
> Т.е. свой сервер ты не планируешь использовать нигде кроме
> как именно в этих условиях ?
он именно для этих условий и предназначен, следовательно ответ будет "да, кроме этих условий нигде не планирую"
> достаточно поднять на вашем сервере-шлюзе любой готовый
> подходящий VPN-сервис.
достаточно, но наш администратор сказал что VPN у нас нет и никогда не будет на сервере, почему, он внятно и не объяснил.
> А где ранее по топику ты сподобился уточнить, что всю эту
> петрушку ты расчитываешь использовать именно в глобальной
> сети ?Нигде не сподобился.И как прикажешь реагировать на
> это ?
а какая разница? именно там и использую.
> Пусть в твоем протоколе имеется команда со строковым значением
> 'Превед !'.Пусть Васе взбрендило передать Пете строку \<Превед
> !>\Как твой сервер изволит поступить в этой ситуации ?
В этом случае, сервер без всяких угрызений совести передаст пете строку \<Превед !>\ потомму то команды \<Превед !>\ по протоколу он не знает, а знает команду Превед !. Если он увидит четко то что он знает, то он выполнит. Например есть команда \data\, он выполнит и не отошлет её дальше, а если написать /data/ или \data\\ то он сраже передаст их без всякого.
Сергей М. (2009-09-17 09:16:00) [44]
> телефон и мой компьютер легко могут кантактировать друг с другом
Для этого и писать-то ничего не нужно - достаточно поднять на вашем сервере-шлюзе любой готовый подходящий VPN-сервис.
Тогда любой узел (по обе стороны шлюза), которому этот сервис технологически и административно доступен, будет находиться в едином маршрутизируемом адресном пространстве.
Сергей М. (2009-09-17 09:03:00) [45]
> Zalm © (16.09.09 22:41) [105]
> Что ж вы так к словам-то всегда прям цепляетесь
Объясняю : неразбериха в голове с терминологией - это, прежде всего, неспособность сформулировать свою задачу или проблему кратко, точно, внятно.
Нет нормальной формулировки - нет и помощи в решении проблемы.
Тебя это устраивает ?
Думаю, вряд ли ..
> написать, или там еще какие другие варианты, набить например,
> тут имеется ввиду что это дело, написанное, набитое, напечатанное,
> надо отправить потом на сервер
И к чему это словоблудие ?
Неужели так трудно сказать "клиент отправляет серверу идентификатор" ?
Язык что ли не поворачивается ?)
> команды хелп нет и не предвидится
Ты сам-то чего к словам цепляешься ?)
Какая нафих разница, есть она у тебя или нет ее ?
Ну другая какая-то вместо нее найдется, которую твой сервер точно так же не будет трактовать как команду, ибо с некоторого момента, как ты говоришь, он у тебя гонит через себя транзитом весь без исключения трафик "пары" ..
> эти все команды имеют такой синтаксис \<команда>\
Пусть в твоем протоколе имеется команда со строковым значением 'Превед !'.
Пусть Васе взбрендило передать Пете строку \<Превед !>\
Как твой сервер изволит поступить в этой ситуации ?
Это же знакомая ему команда и он обязан ее выполнить !
А бедный Вася сидит и ждет, когда же Петя ответит на "преведствие")
А Петя ни сном ни духом не ведает, что Вася его поприветствовал, ибо сервер по недомыслию взял да встрял в их интимный разговор)
> У моего компьютера в локальной сети адрес 10,0,0,28
По барабану какой он.
Адрес выделен.
А то что этот адрес локальный- это совсем из другой оперы.
> среди всего интернета
А где ранее по топику ты сподобился уточнить, что всю эту петрушку ты расчитываешь использовать именно в глобальной сети ?
Нигде не сподобился.
И как прикажешь реагировать на это ?
> Однако у нас есть сервер который (не знаю как выразить опять
> прицепетесь к словам) всему нашему дому обеспечивает инет,
> на нем и работает моя программа, в следствии чего, телефон
> и мой компьютер легко могут кантактировать друг с другом
Т.е. свой сервер ты не планируешь использовать нигде кромекак именно в этих условиях ?
Zalm (2009-09-16 22:41:00) [46]
> Значит "ключ" - это определенная в твоем протоколе команда,
> на которую сервер при получении не должен отвечать.
именно так))
> > Ввести значит написать
> Где написать ? На бумаге ?
Что ж вы так к словам-то всегда прям цепляетесь) всё равно где ввести, написать, или там еще какие другие варианты, набить например, тут имеется ввиду что это дело, написанное, набитое, напечатанное, надо отправить потом на сервер.
> Когда сервер получает команду, он обязан ее выполнить, если
> таковая предусмотрена протоколом. И не важно техническая
> она или гуманитарная. На то он и сервер, чтобы выполнять
> знакомые ему команды или игнорировать выполнение незнакомых
> ему команд.
так и есть, только команды хелп нет и не предвидится
> Как твой сервер должен будет понять, кому адресована эта
> строка ?То ли это команда 'HELP', адресованная самому серверу,
> то ли это один конец "пары" кричит другому концу 'HELP'
> ...
Да просто, сервер понимает всего 5 каманд, которые он не передаст дальше, эти все команды имеют такой синтаксис \<команда>\, если он находит знакомую команду, то он её выполняет, и парному клиенту уже не передает, если он не нашел то передает...
> > без выделенного адреса
>Что значит "без выделенного" ?Кем
> и кому он, по-твоему, д.б. выделен ?
У моего компьютера в локальной сети адрес 10,0,0,28, как вы предполагаете возможным телефону найти такой адрес среди всего интернета? Однако у нас есть сервер который (не знаю как выразить опять прицепетесь к словам) всему нашему дому обеспечивает инет, на нем и работает моя программа, в следствии чего, телефон и мой компьютер легко могут кантактировать друг с другом.
Сергей М. (2009-09-16 21:06:00) [47]
> без выделенного адреса
Адрес неможет быть не выделен - он обязателендля любого устройства, взаимодействующего с другими устройствами по IP.
Сергей М. (2009-09-16 20:29:00) [48]
> Zalm © (16.09.09 18:26) [101]
> ключ это строка которая указана на сервере, вот и всё
> ничего не возвращает, отключает сразу и всё
Значит "ключ" - это определенная в твоем протоколе команда, на которую сервер при получении не должен отвечать.
И всё.
> не может быть если не отключится, сервер принудительно разрывает
> соединение
Вот этоты и должен был указать в протоколе - при получении такой-то команды сервер немедленно разрывает соединение по своей инициативе.
Какого лешего ты указываешь разрыв со стороны клиента, если дальнейшее состояние соединение от него уже не завистит, ибо в этом случае его определяет сервер ?
> Ввести значит написать
Где написать ? На бумаге ?
> Когда сервер получает какую либо команду, он сначала проверяет
> нет ли такой команды из списка так сказать технических
Когда сервер получает команду, он обязанее выполнить, если таковая предусмотрена протоколом. И не важно техническая она или гуманитарная. На то он и сервер, чтобы выполнять знакомые ему команды или игнорировать выполнение незнакомых ему команд.
Предположим, твой сервер по команде со стороковым кодом 'HELP' обязан передать клиенту некую справочную инф-цию.
Предположим, "пара" уже состоялась, и теперь твой сервер обязан, как ты говоришь, транслировать прямиком инф.поток от одного клиента "пары" другому клиенту, не вникая в содержимое потока.
Предположим, одному клиенту состоявшейся "пары" взбрело в голову послать серверу строку 'HELP', в расчете получить от сервера ту самую справочную инф-цию.
Как твой сервер должен будет понять, комуадресована эта строка ?
То ли это команда 'HELP', адресованная самому серверу, то ли это один конец "пары" кричит другому концу 'HELP' ...
> я вам пришлю программу сервера, псмотрите как он работает
У меня нет ни малейшего желания глазеть на нечто лишенное вразумительного описания протокола.
> без выделенного адреса
Что значит "без выделенного" ?
Кем и кому он, по-твоему, д.б. выделен ?
Zalm (2009-09-16 18:28:00) [49]
> Этому есть вразумительное объяснение ? Чем продиктовано
> такое требование - обмен только через твой сервер-посредник
> ?
если вы знаете как можно быстрее и проще соеденить телефон и компьютер без выделенного адреса, то подскажите.
-----------
> Если хотите напишите свою почту, я скажу вам адрес сервера,
> посмотрите как всё работает.
вернее я вам пришлю программу сервера, псмотрите как он работает
Zalm (2009-09-16 18:26:00) [50]
> > надо ввести ключ
Что за "ключ" ?Чем "ключ" не команда ?
> Где описание формата этой команды ?
нет описания, ключ это строка которая указана на сервере, вот и всё.
> > если ключ не верный
> Клиент сам догадывается, что ключ
> не верный ?Или же сервер в ответ на это возвращает нечто,
> информирующее клиента о валидности или невалидности "ключа"
> ?
ничего не возвращает, отключает сразу и всё
> > то сразу клиент отключается
> А если не отключится ? Если
> продолжит инф.обмен ?Что делать серверу с этим "невалидным"
> соединением ?
не может быть если не отключится, сервер принудительно разрывает соединение
> > Index[10]
>Это чего, строка ? Что это означает ?
означает она только что что теперь нужно вводить индекс, что ключ был введен правильный. После ввода ключа, если он подходит, сервер отсылает эту строку.
> > нужно ввести идентификатор, по которому составляется пара
>Кому
> "нужно" ? Что значит "ввести" ? Где и куда его "ввести"
> ?
Нужно клиенту. Ввести значит написать и отправить на сервер.
> Согласно этому выходит, что клиент посылает "еще командочки
> для обслуживания", а серверу на их исполнение уже начхать
> - он прямиком посылает эти "еще командочки" тому самому
> "второму члену пары, если таковой имеется".
так и выходит, после того как составлена пара кроме конкретных команд сервер ничего не воспринимает, или другими словами как вы сказали ему начхать на всё что он получает. Это так потому, что серверу не нужно знать что он получает и передает.
Когда сервер получает какую либо команду, он сначала проверяет нет ли такой команды из списка так сказать технических, если такой нет, то он всё что получил кидает другому клиенту, вот и вся работа сервера.
Если хотите напишите свою почту, я скажу вам адрес сервера, посмотрите как всё работает.
Сергей М. (2009-09-16 08:57:00) [51]Кстати, а зачем понадобилось участие сервера в инф.обмене между "парами" ?
Почему участники "пары" не могут или не имеют права установить соединение друг с другом напрямую (P2P = Peer To Peer), как это реализуется в ряде известных программных продуктов схожего назначения ?
Этому есть вразумительное объяснение ? Чем продиктовано такое требование - обмен толькочерез твой сервер-посредник ?
Сергей М. (2009-09-16 08:42:00) [52]
> надо ввести ключ
Что за "ключ" ?
Чем "ключ" не команда ?
Где описание формата этой команды ?
> если ключ не верный
Клиент сам догадывается, что ключ не верный ?
Или же сервер в ответ на это возвращает нечто, информирующее клиента о валидности или невалидности "ключа" ?
> то сразу клиент отключается
А если не отключится ? Если продолжит инф.обмен ?
Что делать серверу с этим "невалидным" соединением ?
> Index[10]
Это чего, строка ? Что это означает ?
Почему не Index[ 5555555] ?
И зачем числовые параметры 5555555передавать в строковом, а не в бинарном виде ?
> нужно ввести идентификатор, по которому составляется пара
Кому "нужно" ? Что значит "ввести" ? Где и куда его "ввести" ?
> сервер шлет команду
> сервер присылает команду
Ты опять за своё ?) Какая еще "команда" ? Ну сколько можно, а ?
Командует клиент, а не сервер !
Серверполучает команды от клиентов (а не клиенты получают команды от сервера), обрабатывает их и возвращает клиентам результаты обработки команд, а не команды !
> Есть еще всякие командочки для обслуживания
> не интересует потому что на ход работы это не влияет уже
Это как это не влияет ?!
Каким, спрашивается, образом клиент получит результаты обработки посылаемых им "еще командочек", если ты утверждаешь, что
> после этой команды сервер перестает обрабатывать то что
> получает, а сразу кидает второму члену пары, если таковой
> имеется
??
Согласно этому выходит, что клиент посылает "еще командочки для обслуживания", а серверу на их исполнение уже начхать - он прямиком посылает эти "еще командочки" тому самому "второму члену пары, если таковой имеется".
Одним словом, курам на смех такой протокол)
Переделывай, доводи до ума.
Zalm (2009-09-16 01:17:00) [53]Ну что тут показывать-то? показывать особо нечего.
При подключении к серверу надо ввести ключ, затем если ключ не верный то сразу клиент отключается от сервера, если верный то клиент шлет
Index[10]
это означает что нужно ввести идентификатор, по которому составляется пара. После того как идентификатор получен сервер шлет команду
srd(да, тупая, но ничего не пришло на ум другого, рашифровывается как server ready)
после этой команды сервер перестает обрабатывать то что получает, а сразу кидает второму члену пары, если таковой имеется, если нет то сервер присылает команду
No send
вот и всё.
Есть еще всякие командочки для обслуживания, типа проверить сколько клиентов щас подключено, сменить ключ, показать адрес там и тд, думаю вас это уже не интересует потому что на ход работы это не влияет уже
Сергей М. (2009-09-15 08:59:00) [54]
> команды всякие сделать
> как надо отвечать на них?
Это у тебяхотелось бы спросить - ты же разработчик, за тебя это никто не сделает)
Пока ты не разработаешь протокол (читай - подробнуюсхему) взаимодействия между своми клиентами и сервером, ничего путного у тебя не получится, и помочь тебе в его реализации конкретными инструментальнымим средстваминевозможно при всем к тому желании)
> у меня это есть
Ну так приведи в божеский и представь здесь имеющееся у тебя, в чем проблема-то ?
Великий секрет что ли
Zalm (2009-09-15 01:17:00) [55]это как я давно и думаю команды всякие сделать и как надо отвечать на них? у меня это есть
Сергей М. (2009-09-14 20:33:00) [56]
> вот хоть пример предложите
Примеров - как грязи.
Возьми за пример хотя бы тот что у тебя прямо перед носом - HTTP
http://ru.wikipedia.org/wiki/HTTP
Zalm (2009-09-14 20:21:00) [57]
> Не царское это дело - разработка протокола.Быстрей бы "пАры"
> "окучить"
Да Сергей, сколько можно уже, вот какой там должен быть протокол обмена? вот хоть пример предложите.
> если что-то написать первая команда просто где-то теряется
она теряется не сразу, если что-то всё время слать то всё нормально, она теряется спустя какое-то время если ничего е слать...
Так что лучше ридэлен не использовать? просто рид?
Сергей М. (2009-09-14 15:05:00) [58]Не царское это дело - разработка протокола.
Быстрей бы "пАры" "окучить"
Медвежонок Пятачок (2009-09-14 14:56:00) [59]если что-то написать первая команда просто где-то теряется
не где-то, а конкретно в чьем-то неучтенном ридэлэне.
кто-то ждал в нем данных, а данных не было.
затем кто-то послал данные, который пошли на погашение этого ридэлэна.
и создалась иллюзия, что данные исчезли в черной дыре.
PS
надо было слушать дядей, которые говорили что первым делом следует разработать протокол обмена.
Сергей М. (2009-09-14 14:18:00) [60]
> какая может быть ошибка предположительно?
Какая угодно. И где угодно.
Но факт, что это ошибка в твоем коде.