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

Вниз

TIdCmdTCPServer   Найти похожие ветки 

 
Zalm ©   (2009-09-06 16:47) [40]

отправить через TidTCPServer, забыл уточнить


 
Сергей М. ©   (2009-09-06 16:50) [41]


> у меня не получается


Показывай что делал ..
С подробными комментариями движений своей мысли для каждой строчки своего кода ..


 
Сергей М. ©   (2009-09-06 16:51) [42]


> отправить через TidTCPServer, забыл уточнить


Хоть через луну !

Ход своей мысли продемонстрируй ..


 
Zalm ©   (2009-09-06 21:13) [43]


unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, IdBaseComponent, IdComponent, IdCustomTCPServer, IdTCPServer, Buttons,
 idContext;

type
 TForm1 = class(TForm)
   Server: TIdTCPServer;
   procedure ServerConnect(AContext: TIdContext);
   procedure ServerExecute(AContext: TIdContext);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

 _Pack = Record
         Primary_handle : Cardinal;
         Secondary_handle : Cardinal;
         Primary_index : string[8];
         Secondary_index : string[8];
        End;

 {функция для того что бы составить пару из подключений}
 Function Connect_to_Clients( Handle : cardinal; index : string):boolean;
 {получение хэндла "соседа" пары, отправили свой handle, в ответе     получили его handle}
 Function GetHandleByHandle(Handle : cardinal):Cardinal;
 { "переброс" команд, отправляем свой handle, и что хотели отправить "соседу"}
 Procedure Transfer(handle : cardinal; str: string);

var
 Form1: TForm1;
 Pack : _Pack;
 Clients : Array of _Pack;
 Clients_count : integer;

implementation

{$R *.dfm}

procedure TForm1.ServerConnect(AContext: TIdContext);
var
str : string;
begin
AContext.Connection.Socket.WriteLn("Welcame"+#13+"Index[8]: ");
Str:=AContext.Connection.Socket.ReadLn();
if length(str)<>8 then
 begin
  AContext.Connection.Socket.WriteLn("Error length index");
  AContext.Connection.Disconnect;
 end
else
 begin
  if Connect_to_clients(Acontext.Connection.Socket.Binding.Handle,str) then
   begin
    Acontext.Connection.Socket.WriteLn("Start transfer");
   end
  else
   begin
    Acontext.Connection.Socket.WriteLn("Error registration");
    AContext.Connection.Disconnect;
   end;
 end;
end;

Function Connect_to_Clients( Handle : cardinal; index : string):boolean;
var
i : integer;
register_ : boolean;
begin
Result:=false;
for i:=0 to Clients_count-1 do
 begin
  if ((Clients[i].Primary_index=index)or(Clients[i].Secondary_index=index)) then
   begin
    if Clients[i].Primary_index=index then
     begin
      Clients[i].Secondary_handle:=Handle;
      Clients[i].Secondary_index:=index;
      result:=true;
      exit;
     end;
    if Clients[i].Secondary_index=index then
     begin
      Clients[i].Primary_handle:=Handle;
      Clients[i].Primary_index:=index;
      result:=True;
      exit;
     end;
   end;
 end;
inc(clients_count);
SetLEngth(Clients,Clients_count);
Clients[Clients_count-1].Primary_handle:=handle;
Clients[Clients_count-1].Primary_index:=Index;
Result:=True;
end;

procedure TForm1.ServerExecute(AContext: TIdContext);
var
msg : string;
i : integer;
begin
msg:=AContext.Connection.Socket.ReadLn();
if msg="\handle\" then
 begin
  AContext.Connection.Socket.WriteLn(IntTOStr(AContext.Connection.Socket.Binding.H andle));
  exit;
 end;
if msg="\clients\" then
 begin
  for i:=0 to CLients_count-1 do
   begin
    AContext.Connection.Socket.WriteLn(
    "-----------------"+#13+"Couple "+IntToStr(i+1)+#13+
    "PH: "+IntToStr(Clients[i].Primary_handle)+#13+
    "PI: "+Clients[i].Primary_index+#13+
    "SH: "+IntToStr(Clients[i].Secondary_handle)+#13+
    "SI: "+Clients[i].Secondary_index);
   end;
   AContext.Connection.Socket.WriteLn("Done. "+IntToStr(Clients_count)+" couples.");
  exit;
 end;
if msg="\couples\" then
 begin
  AContext.Connection.Socket.WriteLn(INtToStr(Clients_count)+" couples.");
  exit;
 end;
if msg="\GetHandleByHandle\" then
 begin
  AContext.Connection.Socket.WriteLn(IntToStr(GetHandleByHandle(AContext.Connectio n.Socket.Binding.Handle)));
 end;
Transfer(AContext.Connection.Socket.Binding.Handle,msg);
end;

Procedure Transfer(handle : cardinal; str: string);
var
_handle : cardinal;
begin
_handle:=GetHandleByHandle(handle);
{...по идее тут отправка str подключению с известным нам _handle,
 это и есть товарищ из пары, вот только как отправить таким спобом
 этого я не знаю..:( }
end;

Function GetHandleByHandle(Handle : cardinal):Cardinal;
var
i : integer;
begin
result:=0;
for i:=0 to Clients_count-1 do
 begin
  if Clients[i].Primary_handle=handle then
   begin
    result:=Clients[i].Secondary_handle;
    exit;
   end;
  if Clients[i].Secondary_handle=handle then
   begin
    Result:=Clients[i].Primary_handle;
    exit;
   end;
 end;
end;

end.


вот, вроде как бы всё работает, но до определенного затыка в процедуре Transfer.


 
Сергей М. ©   (2009-09-07 09:01) [44]

Тихий ужас..

Хендлы какие-то куда-то отправляются ..

Ты в состоянии изложить формальное описание разработанного тобой протокола инф.обмена между клиентами и сервером ?


 
Сергей М. ©   (2009-09-07 10:13) [45]

За каким тебе понадобились хендлы, если у тебя есть список уникальных объектов IdTCP.Server.Connections, каждый из которых отражает контекст соединения сервера с одним из его активных клиентов ?


 
Zalm ©   (2009-09-07 12:52) [46]

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


 
Zalm ©   (2009-09-07 12:57) [47]


> если у тебя есть список уникальных объектов IdTCP.Server.
> Connections

У вас может быть и есть, а у меня нету. есть только Server.Contexts в котором есть LockList в котором уже я ничего не нашел.
Вот просил же хоть что-то показать конкретное, а вы мне только наводящие вопросы задаете, которые ни на что не наводят меня(


 
Сергей М. ©   (2009-09-07 13:13) [48]


> Зачем вам всё время нужен этот протокол я никак не понимаю


Для того чтобы понять "язык", на котором ты пытаешься заствить разговаривать своих клиентов со своим сервером - что, кому, когда, в каком формате и при каких условиях передается/принимается

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


> у меня проблема совсем в другом


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

Взять хотя бы элементарное, о чем я у тебя уже спросил в [45] ..


 
Сергей М. ©   (2009-09-07 13:21) [49]


> у меня нету. есть только Server.Contexts


Да ну какая разница ?
пусть будет не Connections, а Contexts - суть свойства от  этого не меняется.


> LockList в котором уже я ничего не нашел


Что и где ты искал из того что не нашел ?


 
Сергей М. ©   (2009-09-07 13:23) [50]


> вопросы задаете, которые ни на что не наводят меня


Это печально. Очень.


 
Anatoly Podgoretsky ©   (2009-09-07 13:24) [51]

> Zalm  (07.09.2009 12:57:47)  [47]

Так вопросы задаются, потому что от тебя не поступило полной информации,
если не ты, то мы.


 
Сергей М. ©   (2009-09-07 13:36) [52]


> Zalm


Ты вообще осознаешь, что работу с каждым из своих клиентов IdTCP-сервер осуществляет в отдельном дополнительном треде ?
Судя по

> У TServerSocket было проще всё, ну или понятней

ты обязан это осознавать, ибо в режиме stThreadBlocking TServerSocket работает точно так же как и IdTCP-сервер.
Если осознаешь, то почему не выполняешь обязательную синхронизацию доступа к потоконебезопасным ресурсам, таким как, например, массив Clients, переменную Clients_count ?


 
Zalm ©   (2009-09-07 13:39) [53]

Ну нету никакого протокола. В коде же видна идея как осуществляется обмен. При подключении "зарегистрировали" клиента, и всё, потом другой клиент подключается, такая же процедура, если они вводят один и тот же индекс, они получаются в паре, и сервер сразу передает между ними абсолютно всё что шлют (текст). Клиенты к этому серверу-посреднику обратиться никак не могут, ибо незачем.


> За каким тебе понадобились хендлы, если у тебя есть список
> уникальных объектов IdTCP.Server.Connections, каждый из
> которых отражает контекст соединения сервера с одним из
> его активных клиентов ?

а как записывать какие-то данные о клиенте что бы потом знать кто с кем в паре? Записать хендл мне показалось более целесообразно так как я видел функцию BindingByHandle, я подумал что можно по обработчику пробиться до сокета который он обрабатывает. Но идея завалилась.
А толку записать порт и адрес как вы говорили? что мне потом с ними делать?


> > LockList в котором уже я ничего не нашелЧто и где ты искал
> из того что не нашел ?

Ну вот Server.Contexts.LockList  а дальше что? есть Items[index:integer]:pointer, это единственное что вызывает какое-то внимание, но сделать тоже ничего не получается с этим. Так что чем может помочь этот LockList я не понимаю, и вы подсказать не можете.

видел кусок из примера для инди 9


List := tcpServer.Threads.LockList;
 try
   for Count := 0 to List.Count -1 do
   try
     TIdPeerThread(List.Items[Count]).Connection.WriteLn(Msg);
   except
     TIdPeerThread(List.Items[Count]).Stop;
   end;
 finally
   tcpServer.Threads.UnlockList;
 end;

Они себе в переменную типа TList копируют себе этот LockList и рассылают всем сообщение. ТОлько что такое  TIdPeerThread я не знаю, у меня такого нет. У них есть еще IdThreadMgrDefault1: TIdThreadMgrDefault; это в описании, тоже не знаю что это, у меня ткого нет.
Вобщем жаль что не хотите ничего конкретного подсказать.


 
Zalm ©   (2009-09-07 13:45) [54]


> Ты вообще осознаешь, что работу с каждым из своих клиентов
> IdTCP-сервер осуществляет в отдельном дополнительном треде
> ?

это да, это я знаю.
> почему не выполняешь обязательную синхронизацию доступа
> к потоконебезопасным ресурсам, таким как, например, массив
> Clients, переменную Clients_count ?

не знаю, я такого раньше не делал, проблем как мне казалось из-за этого не было. да и как это синхронизацию я не знаю, я с этим не сталкивался к сожалению


 
Медвежонок Пятачок ©   (2009-09-07 13:48) [55]

Ну нету никакого протокола.  

У тебя ничего не получится.


 
Сергей М. ©   (2009-09-07 13:51) [56]


> Ну нету никакого протокола


Ты прикидываешься или где ?

Как это "нету" ?

А это, к примеру, что по-твоему


> "Welcame"


?

Почему именно "велцаме" у тебя фигурирует, а не "Здарофф, чувак ! Ет я, сервер, с тобой разговариваю" ?


 
Сергей М. ©   (2009-09-07 13:57) [57]


> Ну вот Server.Contexts.LockList  а дальше что?


Ну и что толку тебе объяснять про "дальше что", если межпоточная синхронизация и защита ресурсов для тебя что новые ворота ?


 
Сергей М. ©   (2009-09-07 14:04) [58]


> что такое  TIdPeerThread я не знаю, у меня такого нет


В 10-ке элементами этого списка явл-ся объекты класса TIdContext


 
Медвежонок Пятачок ©   (2009-09-07 14:04) [59]

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


 
Сергей М. ©   (2009-09-07 14:12) [60]


> про ресурсы ему еще рано


Тогда и делать ему пока нефига в индейских серверах. Не по сеньке шапка.
Есть TServerSocket, есть stNonBlocking - там ему "было проще всё, ну или понятней".
Какого лешего ему понадобилось лезть в индейские мультипоточные блокирующие дебри - до сих пор не понятно.
Было бы хотя бы вразумительное обоснование выбора Инди - был бы тогда и стимул вдалбливать ему про синхронизацию и прочую мультипоточную требуху. А так  - что о стенку горох)


 
Медвежонок Пятачок ©   (2009-09-07 14:57) [61]

правильная конфигурация:
сервер постоянно читает запросы клиентов.
получив запрос клиента, отправляет ему ответ, затем снова читает/ждет следующий запрос.

рассылка всем клиентам сообщения по инициативе сервера:
сервер получает текст сообщения от администратора и ничего никуда не посылает. Запоминает его и ждет, когда клиент запросит " А нет ли для меня какого-нить сообчения?"
Получив подобный запрос клиента, сервер отдаети ему сообщение прямо в обработчике команд, без всяких локлистов и прочей ерунды.


 
Сергей М. ©   (2009-09-07 15:09) [62]


> без всяких локлистов и прочей ерунды


В мультипоточном сервере без lock-тряхомудии вряд ли обойтись)
Другой вопрос - она нада ли автору, мультипоточность та самая ..
Впрочем, он и сам не знает.


 
Медвежонок Пятачок ©   (2009-09-07 15:14) [63]

локлист нужен для операций по инициативе сервера.
допустим что клиент у нас "событийный", а сервер "процедурный".
то есть все построено задом наперед.
тогда да.
лочим список коннектов, засылаем клиентам мессаджи и разлочиваем.
если же сервер посторить как строят его нормальные герои (ожидание запроса->обработка->посылка ответа ), то лочить ничего не надо.
все происходит либю в OnExecute, либо в диспетчерах прикладных команд.

Но нах юный друг хочет чтобы и сервер и клиент были одновременно и сервером им клиентом.


 
Сергей М. ©   (2009-09-07 15:34) [64]


> лочить ничего не надо


Ну как же не надо ?


> все происходит либю в OnExecute, либо в диспетчерах прикладных
> команд


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


 
Медвежонок Пятачок ©   (2009-09-07 15:45) [65]

Ну это само собой разумеется.
Но я-то про Среадс.ЛокЛист говорил конкретно.
Точнее про то, что он почти никогда не нужен правильному серверу.


 
Сергей М. ©   (2009-09-07 15:47) [66]


> про то, что он почти никогда не нужен правильному серверу


С этим солидарен.


 
Zalm ©   (2009-09-07 17:05) [67]

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


 
Медвежонок Пятачок ©   (2009-09-07 17:17) [68]

фигасе заявки. "помощи не будет".


 
Сергей М. ©   (2009-09-07 17:18) [69]


> я бы вобще не назвал то что мне нужно сервером


Обзови его хоть горшком - как он был сервером, так он им и останется.
Его задача - обслуживать (to serve) клиентов, если они не в состоянии сами себя обслужить.


> помощи не будет


Тебе уже 68 постов только и делают, что помогают, а ты все не внемлешь.


 
Сергей М. ©   (2009-09-07 17:30) [70]


> если бы я писал через TServerSocket  я бы не задавал таких
> тупых вопросов


Глубоко в этом сомневаюсь.
Были бы другие, но не менее тупые.


 
Zalm ©   (2009-09-07 17:48) [71]

Server.Bindings.BindingByHandle(handle : cardinal)

а это что делает?


 
Zalm ©   (2009-09-07 17:51) [72]

вот что сложного ответить на вопрос как отправить клиенту строку зная либо хендл, либо его адрес, либо его индекс подключения?)


 
Zalm ©   (2009-09-07 18:07) [73]

что вобще сложного в том сервере который мне нужен? та же структура что и у сервера аси, получил передал сразу вот и всё...


 
Медвежонок Пятачок ©   (2009-09-07 18:10) [74]

получил передал сразу вот и всё...

не сразу, а только по запросу того, кому это предназначалось.


 
Медвежонок Пятачок ©   (2009-09-07 18:14) [75]

Вот я клиент твоей аси.
И Сергей М. тоже клиент.

Я нажимаю кнопку и запрашиваю инфо о контакте Сергея М.
В это время он мне шлет сообщение "Превет Медвет"
Сервер его получает и тут же сразу же мне его шлет.
А я в это время отправил запрос о его профиле и жду его.
А в ответ мне вместо данных его профиля приходит "Превет Медвет".
Я (точнее твой чудо-клиент аси) при этом в полной уверенности что:
1. Получил не сообщение, а инфу о профиле Сергея М
2. Мне не пришло текстовое сообющение от Сергея М

дальше разжевывать надо?


 
Zalm ©   (2009-09-07 18:23) [76]

ася что ли сидит и спрашивает у сервера есть ли для неё сообщения?

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


 
Медвежонок Пятачок ©   (2009-09-07 18:27) [77]

ася что ли сидит и спрашивает у сервера есть ли для неё сообщения?

Ты лучше спроси как она вообще получает сообщения ничего не запрашивая (якобы) и ничего не читая (якобы).


 
Медвежонок Пятачок ©   (2009-09-07 18:29) [78]

Хотя этот вопрос лишний.
Ты попробуй сначала выкрутится из ситуации, что описана у меня в [75].

Когда в ответ на запрос информации о контакте приходит не инфа о контакте, а "Превет Медвет".


 
Zalm ©   (2009-09-07 18:34) [79]

ну а что там выкручиться, сложности никакой.
например синтаксис для собщения MSG_<сообщение>, а для инфы INFO_<инфа>, и какой тут напряг? придет себе сообщение, будет оно как сообщение, а инфу по-прежнему ждем


 
Сергей М. ©   (2009-09-07 18:38) [80]


> Zalm ©   (07.09.09 17:51) [72]


А что ты хотел видеть в кач-ве ответа на этот вопрос ?


> а это что делает?


"Это" возвращает binding-структуру с интересующим значением поля handle.


> та же структура что и у сервера аси, получил передал сразу
> вот и всё


Это тебе "сервер ася" сказал ?
Или ты изучил документацию ?


> вот что сложного ответить на вопрос как


А что ты хотел увидеть в кач-ве ответа на вопрос ?
Код ?
Он тебе не поможет, уверяю тебя.
Ты нишиша в нем не поймешь.
Даже если ты сдуешь его "один в один", он у тебя работать не будет.



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

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

Наверх




Память: 0.66 MB
Время: 0.016 c
2-1259749020
Anastasia
2009-12-02 13:17
2010.01.24
Как задать интервал строк на QReport?


2-1259179871
sloosar
2009-11-25 23:11
2010.01.24
Удаление пустой строки


1-1233774692
wolfRAMM
2009-02-04 22:11
2010.01.24
вместо кирилицы - "????"


2-1258096612
xtd
2009-11-13 10:16
2010.01.24
почему в TWebBrowser не работает JavaScript ?


15-1258742459
POOP
2009-11-20 21:40
2010.01.24
Djvu просмоторщик для мобильника?