Форум: "Начинающим";
Текущий архив: 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