Конференция "Сети" » TIdCmdTCPServer
 
  • Zalm © (06.09.09 16:47) [40]
    отправить через TidTCPServer, забыл уточнить
  • Сергей М. © (06.09.09 16:50) [41]

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


    Показывай что делал ..
    С подробными комментариями движений своей мысли для каждой строчки своего кода ..
  • Сергей М. © (06.09.09 16:51) [42]

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


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

    Ход своей мысли продемонстрируй ..
  • Zalm © (06.09.09 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.
  • Сергей М. © (07.09.09 09:01) [44]
    Тихий ужас..

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

    Ты в состоянии изложить формальное описание разработанного тобой протокола инф.обмена между клиентами и сервером ?
  • Сергей М. © (07.09.09 10:13) [45]
    За каким тебе понадобились хендлы, если у тебя есть список уникальных объектов IdTCP.Server.Connections, каждый из которых отражает контекст соединения сервера с одним из его активных клиентов ?
  • Zalm © (07.09.09 12:52) [46]
    да что есть? ничего там нет, просил же показать то о чем вы всё время говорите, так вы не можете.
    Зачем вам всё время нужен этот протокол я никак не понимаю, у меня проблема совсем в другом.
  • Zalm © (07.09.09 12:57) [47]

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

    У вас может быть и есть, а у меня нету. есть только Server.Contexts в котором есть LockList в котором уже я ничего не нашел.
    Вот просил же хоть что-то показать конкретное, а вы мне только наводящие вопросы задаете, которые ни на что не наводят меня(
  • Сергей М. © (07.09.09 13:13) [48]

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


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

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


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


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

    Взять хотя бы элементарное, о чем я у тебя уже спросил в [45] ..
  • Сергей М. © (07.09.09 13:21) [49]

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


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


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


    Что и где ты искал из того что не нашел ?
  • Сергей М. © (07.09.09 13:23) [50]

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


    Это печально. Очень.
  • Anatoly Podgoretsky © (07.09.09 13:24) [51]
    > Zalm  (07.09.2009 12:57:47)  [47]

    Так вопросы задаются, потому что от тебя не поступило полной информации,
    если не ты, то мы.
  • Сергей М. © (07.09.09 13:36) [52]

    > Zalm


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

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

    ты обязан это осознавать, ибо в режиме stThreadBlocking TServerSocket работает точно так же как и IdTCP-сервер.
    Если осознаешь, то почему не выполняешь обязательную синхронизацию доступа к потоконебезопасным ресурсам, таким как, например, массив Clients, переменную Clients_count ?
  • Zalm © (07.09.09 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 © (07.09.09 13:45) [54]

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

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

    не знаю, я такого раньше не делал, проблем как мне казалось из-за этого не было. да и как это синхронизацию я не знаю, я с этим не сталкивался к сожалению
  • Медвежонок Пятачок © (07.09.09 13:48) [55]
    Ну нету никакого протокола.  

    У тебя ничего не получится.
  • Сергей М. © (07.09.09 13:51) [56]

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


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

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

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


    > 'Welcame'


    ?

    Почему именно "велцаме" у тебя фигурирует, а не "Здарофф, чувак ! Ет я, сервер, с тобой разговариваю" ?
  • Сергей М. © (07.09.09 13:57) [57]

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


    Ну и что толку тебе объяснять про "дальше что", если межпоточная синхронизация и защита ресурсов для тебя что новые ворота ?
  • Сергей М. © (07.09.09 14:04) [58]

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


    В 10-ке элементами этого списка явл-ся объекты класса TIdContext
  • Медвежонок Пятачок © (07.09.09 14:04) [59]
    про ресурсы ему еще рано.
    он кажется самого главного не понял:
    если хочется, чтобы сервер имел возможность отправки сообщения в произвольный момент времени, то клиент такого сервера должен постоянно висеть в процедуре чтения буфера и ни на что иное не отвлекаться.
    При этом он теряет возможность отправлять на сервер что-либо по своей инициативе.
    Причем на все время своей сессии.
 
Конференция "Сети" » TIdCmdTCPServer
Есть новые Нет новых   [134437   +29][b:0][p:0.004]