Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2010.01.24;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.81 MB
Время: 0.013 c
3-1233556346
Sergey2
2009-02-02 09:32
2010.01.24
update таблицы в Paradox


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


2-1259779619
Danco
2009-12-02 21:46
2010.01.24
Смена запуска Unit


1-1233757927
jetus
2009-02-04 17:32
2010.01.24
Получить название метода


4-1227154029
Riply
2008-11-20 07:07
2010.01.24
IoCreateSymbolicLink. Требования к параметрам.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский