Здравствуйте. Имеется код: Code: procedure TForm1.OnAuthTimer(Sender: TObject); begin end; procedure TForm1.ServerClientConnect(Sender: TObject; Socket: TCustomWinSocket); begin Timer := TTimer.Create(Form1); Timer.Interval := 5000; Timer.OnTimer := OnAuthTimer; end; Суть его такова: при подключении клиента к серверу создается таймер с событием OnAuthTimer. По истечении определенного времени таймер должен разрывать соединения с теми клиентами от которых не пришли данные для авторизации. Вопрос. Как процедуре OnAuthTimer передать Socket из процедуры ServerClientConnect, что бы таймер мог отключить клиента?
создай объект наследник таймера найди в TTimer процедуру в которые осуществляется вызов OnTimer. Предположим что называется TimerProc тогда можно сделать то так: Code: TMyTimer = class(TTimer) private fMySender : TObject fMyOnTimer : TProc<TObject> //delphi 2010 (procedure(Sender:TObject) of object в delphi 7) procedure TimerProc; published property MyOnTimer write fMyOnTimer; Property MySender write fMySender; end; ... ... procedure MyTimer.TimerProc; begin //копирайт TimerProc If assigned(fMyOnSender) then fMyOntimer(fMySender); end; ... procedure TForm1.ServerClientConnect(Sender: TObject; Socket: TCustomWinSocket); begin Timer := TMyTimer.Create(Form1); Timer.Interval := 5000; Timer.MySender := Sender; Timer.MyOnTimer := OnAuthTimer; end; проверить не имею возможности ...
или просто Code: TMyTimer = class(TTimer) MySender:Tobject; end; procedure TForm1.OnAuthTimer(Sender: TObject); begin Timer.MySender................ end; procedure TForm1.ServerClientConnect(Sender: TObject; Socket: TCustomWinSocket); begin Timer := TMyTimer.Create(Form1); Timer.Interval := 5000; Timer.Mysender:=sender; ///<<<<<<<<<<<<<< Timer.OnTimer := OnAuthTimer; end; и при таймере читай MySender ...
Спасибо, но мне это кажется слишком сложным) а что если сделать так: Code: procedure TForm1.OnAuthTimer(Sender: TObject; Socket: TCustomWinSocket); begin end; procedure TForm1.ServerClientConnect(Sender: TObject; Socket: TCustomWinSocket); begin Timer := TTimer.Create(Form1); Timer.Interval := 5000; Timer.OnTimer := OnAuthTimer([B][что сюда передать?][/B],Socket); end; что надо передать в функцию что бы это работало? и вообще можно ли так делать?)
так как ты написал делать нельзя ... свойство Timer.OnTimer это лишь указатель на процедуру, а ты хочешь передать ему параметры) да еще и не совместимы
пробую сделать предложенным вариантом. все ок, но я не понял последнего шага, куда, например, мне необходимо записать действия которые будут выполняться по таймеру? например: Code: Socket.Disconnect(0); что бы отключить клиента.
Code: procedure TForm1.OnAuthTimer(Sender: TObject); begin <Имя об’єкта>(Timer.MySender).disconect; // напр если бы это был TMemo то TMemo(Timer.MySender).text:='ffff'; //<Название объекта>(<указатель на объект>).<методы объекта> end; procedure TForm1.ServerClientConnect(Sender: TObject; Socket: TCustomWinSocket); begin Timer := TMyTimer.Create(Form1); Timer.Interval := 5000; Timer.Mysender:=sender; ///<<<<<<<<<<<<<< Timer.OnTimer := OnAuthTimer; end; какие методы и какого объекта нужно выполнить?
нужно выполнить ServerSocket1.Socket.Disconnect(i); // i - номер клиента я так понимаю ServerSocket1.Socket это объект, а Disconnect(0) это метод...)
Code: procedure TForm1.OnAuthTimer(Sender: TObject); begin TServerSocket(Timer.MySender).Socket.Disconnect; //що за і ??? end; procedure TForm1.ServerClientConnect(Sender: TObject; Socket: TCustomWinSocket); begin Timer := TMyTimer.Create(Form1); Timer.Interval := 5000; Timer.Mysender:=sender; ///<<<<<<<<<<<<<< Timer.OnTimer := OnAuthTimer; end; для чего 'i'? это действительно такое есть (. disconect (i)) или ты приписал? если нет то как ты создаешь несколько клиентов?? для чего указатель ServerSocket1? ты накинул компонент на форму?? ПС ServerSocket1 - это указатель на объект TServerSocket а все что после точки (ServerSocket1. *) - это методы или свойства объекта (Процедуры объекта называют его методами а то что объявлено как `Property MyProperty write SetProperty read GetProperty это свойства '(свойства можно задавать либо читать)) сейчас посмотрим как переведет гугл то что я написал))
Спасибо за развернутый ответ. i - это номер клиента. я отключаю конкретного клиента который не прошел авторизацию в течение 5 секунд. У меня возникла еще одна идея реализации данной функции... Можно ли к динамически создаваемому таймеру прикрепить дополнительное свойство в котором будет хранится к примеру IP адрес клиента? Тогда можно было бы просто создать таймер, указать ему в свойстве IP. По истечении времени таймер уничтожает сам себя, и смотрит в специальный список, в котором IP адреса авторизовавшихся клиентов, и если не находит того IP который прописан в его свойстве то дает серверу команду отключить его. Мне кажется этот метод хорош тем что нет необходимости следить за каждым таймеро посредством поля Tag. Просто при работе сервера одновременно будут создаваться десятки таких таймеров одновременно.
значит ServerSocket1 не должен быть динамичным. тогда так: Code: TMyTimer = class(TTimer) i:integer; IP:string; //пиши тут що ще треба напр Port:integer; end; procedure TForm1.OnAuthTimer(Sender: TObject); begin ServerSocket1.Socket.Disconnect(i); end; procedure TForm1.ServerClientConnect(Sender: TObject; Socket: TCustomWinSocket); begin Timer := TMyTimer.Create(Form1); Timer.Interval := 5000; Timer.i:=// i:=??? Timer.IP:=//IP:=??? Timer.OnTimer := OnAuthTimer; end; АЛЕ так задавати властивості в такий спосіб не рекомендується! (правильно так: Code: TMyTimer = class(TTimer) private fi:integer; fIP:string; published [B] property I:integer write fi read fi; property IP:string write fIP read fIP;[/B] end; ) но в данном случае это не важно так как ты все равно не используешь переменные внутри объекта.
не много ошибся. конкретный клиент отключается таким образом: Code: Server.Socket.Connections[I].Disconnect(0);
Code: TMyTimer = class(TTimer) i:integer; IP:string; //пиши тут що ще треба напр Port:integer; end; procedure TForm1.OnAuthTimer(Sender: TObject); begin [b] Server.Socket.Connections[I].Disconnect(0);[/b] //<<<<<<<<<<<< end; procedure TForm1.ServerClientConnect(Sender: TObject; Socket: TCustomWinSocket); begin Timer := TMyTimer.Create(Form1); Timer.Interval := 5000; Timer.i:=// i:=??? Timer.IP:=//IP:=??? Timer.OnTimer := OnAuthTimer; end; могу написать класс (объект) чтобы не надо было создавать процедуры и т.д. а просто TObjectName.Create (ip, i, sender) и все PS ти розумієш українську? схарився перекладати)
да, буду весьма признателен за класс. Українську розумію нормально)) в классе достаточно будет параметра IP, т.к. удаление клиента будет производится таким образом Code: procedure TForm1.OnAuthTimer(Sender: TObject); var i: integer; begin for i := 0 to Server.Socket.ActiveConnections - 1 do if Server.Socket.Connections[i].RemoteAddress = IP then begin Server.Socket.Connections[i].Destroy; Exit; end; Sender.Free; // После одного цикла таймер должен уничтожиться end; главное необходимо сделать так что бы когда например будет создано 20 таймеров они не мешали друг другу) т.е. каждый работает независимо от друго...
ось: (вибачай за затримку) ) Code: type PServerSocket = ^TServerSocket; //можливо цього і [B]не[/B] треба { TTimerConnect } TTimerConnect = class private FTimer:TTimer; FIP:string; FServer:PServerSocket; procedure fOnTimer(Sender:TObject); public constructor GoTimer(const IP:string; ServerSocket:TServerSocket); destructor destroy; end; implementation { TTimerConnect } procedure TTimerConnect.fOnTimer(Sender: TObject); var i:integer; begin for i := 0 to FServer.Socket.ActiveConnections - 1 do if FServer.Socket.Connections[i].RemoteAddress = FIP then begin FServer.Socket.Connections[i].Destroy; Break; //потрібно вийти з циклу а не з процедури! end; self.destroy; end; constructor TTimerConnect.GoTimer(const IP: string; ServerSocket: PServerSocket ); begin inherited Create; FIP := ip; FServer := ServerSocket; FTimer := TTimer.create(nil); FTimer.interval:=5000; FTimer.OnTimer:=fOnTimer; //не пам’ятаю можливо ще щось потрібно зробити щоб запустити таймер end; destructor TTimerConnect.destroy; begin FTimer.Free; inherited destroy; end; щось то дуже просто вийшло) запускаєш так TTimerConnect.GoTimer(Ip,server);// вказівник на цей об’єкт (timer:=TTimerConnect.GoTimer(Ip,server); ) не потрібно (метод Create виділяє пам’ять під об’єкт тобто кожний виклик цієї функції створює новий об’єкт) не маю можливості перевірити цей код... ПС а немає підсвідки синтаксису? типу Code: nil