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

Вниз

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

 
Anatoly Podgoretsky ©   (2009-09-18 13:34) [120]


> MSG : string;
> I, J : integer;
> List : Tlist;
> _ip : string;
> _port : word;
> key : string;

Слова плохие будут, вот здесь плохие имена, почти все, ну ладно это дело компилятора, а вот типы уже не дело компилятора - нельзя использовать тип string generic, а не fundamental - особенно для сетевых протоколов. В Инди с этим уже много дел натворили.


 
Zalm ©   (2009-09-18 16:52) [121]


> нельзя использовать тип string generic, а не fundamental

а побольше про это слов скажете?)

Сергей, прошу тыкать пальцем, где ошибки



    _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;

 Procedure Send (ip:string;port:word;str:string);
 Procedure Server_clear;

var

 Link_file : TEXTFILE;
 RAM_file : TEXTFILE;

 Form1: TForm1;
 Clients : _Clients;
 _null : _pack;
 CriticalSection : TCriticalSection;

 _Start_time : TDATETIME;

 Last_ram : real;

implementation

{$R *.dfm}

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Server.StopListening;
APPLICATION.Terminate;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
AssignFIle(Link_file,"link.sf");
AssignFIle(RAM_file,"ram.sf");
Rewrite(link_file);
Rewrite(ram_file);
CloseFile(link_file);
CloseFile(Ram_file);

_Start_time:=now;
CriticalSection:=TCriticalSection.Create;
CriticalSection.Enter;
Clients:=_Clients.Create;
CriticalSection.Leave;
Server.MaxConnections:=Limits.Value;
cl_limit.Caption:=IntTOstr(limits.Value);
end;

procedure TForm1.limitsClick(Sender: TObject);
begin
Server.MaxConnections:=Limits.Value;
cl_limit.Caption:=IntToStr(limits.Value);
end;

procedure TForm1.logTimer(Sender: TObject);
Var
pmc:PPROCESS_MEMORY_COUNTERS;
rm : real;
state : string;
begin
state:="";
Append(ram_file);
GetMem(pmc, SizeOf(_PROCESS_MEMORY_COUNTERS));
pmc.cb:=SizeOf(_PROCESS_MEMORY_COUNTERS);
If GetProcessMemoryInfo(GetCurrentProcess(), pmc, pmc.cb) then rm:=(pmc^.WorkingSetSize)/1024/1024;
if (rm>last_ram) then
 begin
  state:="+"+FloatToStrF(rm-Last_ram,ffFixed,15,3);
 end;
if (rm<last_ram) then
 begin
  state:="-"+FloatToStrF(last_ram-rm,ffFixed,15,3);
 end;
if rm=last_ram then State:="0";
Last_ram:=rm;
Writeln(ram_file,DateToStr(now)+" "+TimeToStr(now)+" \ RAM: "+FloatTOStrF(rm,ffFixed,15,3)+"\ "+state);
CloseFile(ram_file);
end;

procedure TForm1.displayClick(Sender: TObject);
var
str : string;
begin
RichEdit1.Clear;
if display.ItemIndex=0 then
 begin
   RichEdit1.Lines.Add("not supported");
 end;
if display.ItemIndex=1 then
 begin
  reset(ram_file);
  while not(eof(ram_file)) do
   begin
    readln(ram_file,str);
    RichEdit1.Lines.Add(str);
   end;
  RichEdit1.Lines.Add("---------------------"+#13+" END");
  closeFIle(ram_file);
 end;
end;

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;



 
Zalm ©   (2009-09-18 16:53) [122]


Procedure Server_clear;
var
list : TList;
i : integer;
begin
try
 LIst:=Form1.Server.Contexts.LockList;
 for I := 0 to List.Count - 1 do
  with TidContext(List[i]) do Connection.Disconnect;
finally
 Form1.Server.Contexts.UnlockList;
end;
Clients.Count:=0;
SetLength(Clients.Clients,0);
end;

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();
{----------------------------------------}
if msg="\reset\" then
 begin
  Server_clear;
 end;
if msg="\сhKOL\" then
 begin

 end;
if msg="\chKEY\" then
 begin
  AContext.Connection.Socket.Writeln("KEY");
  key:=AContext.Connection.Socket.Readln();
  if KEY<>Edit2.Text then
   begin
    AContext.Connection.Socket.WriteLn("ikr");   {invalid key read}
    Acontext.Connection.Disconnect;
    exit;
   end
  else
   begin
    AContext.Connection.Socket.WriteLn("NK");    {new key}
    KEY:=AContext.Connection.Socket.ReadLn();
    if Length(key)>10 then
     begin
      AContext.Connection.Socket.WriteLn("iks"); {invalid key set}
      AContext.Connection.Disconnect;
      exit;
     end
    else
     begin
      Acontext.Connection.Socket.Write("oks");    {ok key set}
      Edit1.Text:=key;
      exit;
     end;
   end;
 end;
if msg="\clients\" then
 begin
  Acontext.Connection.Socket.WriteLn(IntToStr(Clients.Count));
  exit;
 end;
if msg="\exit\" then
 begin
  AContext.Connection.Disconnect;
  exit;
 end;
if msg="\data\" then
 begin
  for i := 0 to Clients.Count - 1 do
   begin
    Acontext.Connection.Socket.WriteLn("SIP: "+Clients.Clients[i].SIP);
    AContext.Connection.Socket.WriteLn("SPort: "+IntToStr(Clients.Clients[i].SPort));
    AContext.Connection.Socket.WriteLn("PIP: "+Clients.Clients[i].PIP);
    AContext.Connection.Socket.WriteLn("PPort: "+IntToStr(Clients.Clients[i].PPort));
    AContext.Connection.Socket.WriteLn("Index: "+Clients.Clients[i].Index);
   end;
  exit;
 end;
if msg="\i\" then
 begin
  AContext.Connection.Socket.WriteLn(AContext.Connection.Socket.Binding.PeerIP+":"+IntToStr(AContext.Connection.Socket.Binding.PeerPort));
  exit;
 end;
{----------------------------------------}
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 TForm1.SpeedButton1Click(Sender: TObject);
begin
form2.show;
end;

procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
Application.Terminate;
end;

procedure TForm1.SpeedButton3Click(Sender: TObject);
begin
Tray.Visible:=True;
Form1.Hide;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
day : integer;
pmc:PPROCESS_MEMORY_COUNTERS;
begin
cl.Caption:=IntToStr(Clients.Count*2);
Start_time.Caption:=TimeToStr(_Start_time);

if Abs(_Start_time-now)>1 then
  begin
   day:=Abs(Trunc(_Start_time-now));
   form1.work_time.Caption:=FloatToStr(day)+" д. "+TimeToStr(_Start_time-now);
  end
 else form1.work_time.Caption:=TimeToStr(now-_Start_time);

GetMem(pmc, SizeOf(_PROCESS_MEMORY_COUNTERS));
pmc.cb:=SizeOf(_PROCESS_MEMORY_COUNTERS);
If GetProcessMemoryInfo(GetCurrentProcess(), pmc, pmc.cb) then
 begin
  ram.Caption:=FloatToStrF((pmc^.WorkingSetSize)/1024/1024,ffFixed,15,3)+" Мб";
  FreeMem(pmc);
 end;
end;

procedure TForm1.TrayClick(Sender: TObject);
begin
Form1.Show;
Tray.Visible:=False;
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);
      break;
     end;
   end;
finally
 Form1.Server.Contexts.UnlockList;
end;
end;


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

Я ж палец сломаю, если буду в каждую тыкать : весь этот код - одна сплошная большая ошибка)

Вот скажи, ты за каким создал объект CriticalSection, если нигде кроме как в Form1.OnCreate его в последствии не используешь для защиты ресурса Clients ?
И от кого ты защищаешь ресурс Clients при обработке события Form1.OnCreate, если в этот момент не существует ни единого потока кроме основного ?


 
Zalm ©   (2009-09-18 17:16) [124]


> Я ж палец сломаю, если буду в каждую тыкать : весь этот
> код - одна сплошная большая ошибка)

ну так дело никуда не сдвинется... не хорошо так..


> Вот скажи, ты за каким создал объект CriticalSection, если
> нигде кроме как в Form1.OnCreate его в последствии не используешь
> для защиты ресурса Clients ?

Раньше использховал, в ONConnect и OnDisconnect, но с ним вылазили ошибки, а без него всем стало хорошо xD
Я попробую это исправить.


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


> так дело никуда не сдвинется


Конечно не сдвинется..
Думать-то ты по-прежнему не хочешь..


> с ним вылазили ошибки, а без него всем стало хорошо


Чего ж ты тогда продолжаешь топик и постишь код, при котором "всем стало хорошо" ?)


 
Zalm ©   (2009-09-19 01:25) [126]


> Чего ж ты тогда продолжаешь топик и постишь код, при котором
> "всем стало хорошо" ?)

))))

Так с крит секциями правильно?


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;
CriticalSection.Enter;
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");
      CriticalSection.Leave;
      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");
      CriticalSection.Leave;
      exit;
     end;
    AContext.Connection.Disconnect;
    CriticalSection.Leave;
    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;
CriticalSection.Leave;
Acontext.Connection.Socket.WriteLn("srd");
end;


 
Медвежонок Пятачок ©   (2009-09-19 01:30) [127]

неправильно. причем неправильно не из за секций.


 
Сергей М. ©   (2009-09-19 15:23) [128]


> edit1.Text


Это тоже потоконебезопасное обращение.

Ты, кстати, про try..finally что-нибудь слышал ?


 
Anatoly Podgoretsky ©   (2009-09-19 20:48) [129]

> Сергей М.  (19.09.2009 15:23:08)  [128]

select from insert to
 "Сергей М."
сообщил/сообщила в
новостях следующее:
news:1251710046.128@delphimaster.ru...
 Сергей М. © (19.09.2009 15:23) [128]

 > edit1.Text


 Это тоже
потоконебезопасное
обращение.

 Ты, кстати, про try..finally
что-нибудь слышал ?


 
Zalm ©   (2009-09-19 22:23) [130]


> неправильно. причем неправильно не из за секций.

а почему не сказал из-за чего :(

Сергей, вы так и не сказали секции правильно или нет...

Про try..finally слышал, я его обычно для ошибок использую Try..Except


 
Сергей М. ©   (2009-09-21 08:31) [131]


> секции правильно или нет


С учетом того, что обращение к Edit1 не защищено - нет, не правильно.


> Про try..finally слышал, я его обычно для ошибок использую
> Try..Except


Что за бред ?
finally - это finally, а except - это except.
Две разные разницы.


 
Сергей М. ©   (2009-09-21 08:42) [132]

CS.Enter;
try
.. обращение к потоконебезопасному ресурсу ..
finally
 CS.Leave;
end;


 
Zalm ©   (2009-10-28 17:36) [133]

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


 
Сергей М. ©   (2009-10-29 10:31) [134]

Куда не пишет ?
И разве он обязан куда-то что-то писать ?


 
Zalm ©   (2009-10-29 11:53) [135]

О, Сергей опять вы) Прям рад что вы мне снова отвечаете))

А как мне тогда убирать не работающие подключения? или как можно сделать что бы сервер сам следил за тем что работатет, а что нет? Посоветуйте пожалуйста как лучше сделать


 
Dennis I. Komarov ©   (2009-10-29 12:07) [136]

Детский сад продолжается? :)

> А как мне тогда убирать не работающие подключения?

Это каких таких?


 
Сергей М. ©   (2009-10-29 12:19) [137]


> Dennis I. Komarov ©   (29.10.09 12:07) [136]


> Это каких таких?


Ну, наверно, тех, которые уборщица Тётьклава случайно оборвала орудуя шваброй)


> Zalm ©   (29.10.09 11:53) [135]
> А как мне тогда убирать не работающие подключения?


Надо обратиться к такому подключению.
При отсутствии петли подключения попытка вызова метода передачи должна привести к исключению соотв.класса.


 
Dennis I. Komarov ©   (2009-10-29 12:37) [138]


> Ну, наверно, тех, которые уборщица Тётьклава случайно оборвала
> орудуя шваброй)

Дома уборщица тетя Клава, а на программиста денег нету...


 
Zalm ©   (2009-10-29 16:05) [139]

хех... детский сад\не детский... зачем вот это всё говорить надо.


 
Dennis I. Komarov ©   (2009-10-29 16:14) [140]


> Zalm ©   (29.10.09 16:05) [139]

Ну, может совесть проснется, так не книжку какую-нить почитать, а хотя бы вопросы формулировать понятно будем...


 
Zalm ©   (2009-10-29 21:58) [141]

вот, если отправит не работающему подключение функция должна вернуть false, однако не возвращает. Или где я не правильно написал?


Function Send(ip:string;port:word;str:string):boolean;
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
      try
       TidContext(list[i]).Connection.Socket.WriteLn(str);
      except
       Result:=False;
      end;
      Result:=True;
      break;
     end;
   end;
finally
 Form1.Server.Contexts.UnlockList;
end;
end;


 
Сергей М. ©   (2009-10-29 22:12) [142]


>       except
>        Result:=False;
>       end;
>       Result:=True;


Сам-то понял, что ты тут творишь ?)


 
Dennis I. Komarov (htc)   (2009-10-29 22:29) [143]

а что? прогресс на лицо ;) и логика появилась...


 
Zalm ©   (2009-11-28 02:57) [144]

Как можно изнутри сервера вызвать эвент обработчика комманды как будто клиент прислал такую команду?


Procedure pr;
var
command : TidCommand;
begin
 command.CommandHandler.Command:="0x18";
 Form1.Client.CommandHandlers.Items[13].OnCommand(command);
end;


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


 
Zalm ©   (2009-12-01 13:16) [145]

Забанили тему что ли?...


 
Сергей М. ©   (2009-12-01 13:30) [146]

Да просто надаела уже эта тягомотина хуже горькой редьки)


 
Zalm ©   (2009-12-02 20:46) [147]

Ну давайте я новую создам?)
У меня больше нет вопросов кроме этого... может всё же ответите пожалуйста если знаете?)


 
Сергей М. ©   (2009-12-02 21:27) [148]


> давайте я новую создам?


Думаешь новая редька будет слаще ?)
Сомневаюсь)


> Как можно изнутри сервера вызвать эвент обработчика комманды


Как обычный метод обычного объекта.


 
Zalm ©   (2009-12-03 12:37) [149]

Вы смотрели мой пример? когда я так делаю ничего не происходит вобще


 
Сергей М. ©   (2009-12-03 12:46) [150]

Ну поставь брейкпойнт да посмотри что у тебя там не там или не так на самом деле происходит ..



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

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

Наверх




Память: 0.83 MB
Время: 0.014 c
1-1234562486
v1keeee
2009-02-14 01:01
2010.01.24
Неактивная форма как Виртуальная клавиатура Windows


2-1259683232
serhiyiv
2009-12-01 19:00
2010.01.24
FILE / FOLDER


2-1259929176
oleg1963lora
2009-12-04 15:19
2010.01.24
CreateDir. Анализ ошибки


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


15-1258146808
POOP
2009-11-14 00:13
2010.01.24
Редакторы кода в несколько колонок.