Модераторы: Snowy, MetalFan, bems, Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Самоуничножаюшийся класс :) 
V
    Опции темы
Ak47black
Дата 10.12.2007, 18:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2205
Регистрация: 2.12.2005

Репутация: нет
Всего: 0



Здравствуйте.
Столкнулся с проблемой.
Хочу сделать класс в котором был бы компонент TClientSocket. 
При создании класса происходил Connect и если неудавалось подсоединится то класс сам уничтожал себя.  smile 
Вот код как я пытаюсь сделать
Unit1
Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ScktComp, Con_Unit;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public

  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  TestClass: TTestClass;
begin
  TestClass:= TTestClass.Create('127.0.0.1', 1200);
end;

end.

Con_Unit
Код

unit Con_Unit;

interface

uses
  SysUtils, Windows, Classes, ScktComp;

type
  TTestClass = class
  public
    Socked: TClientSocket;
    constructor Create(Address: String; Port: Integer);
    procedure SocketConnect(Sender: TObject; Socket: TCustomWinSocket);
    procedure SocketDisconnect(Sender: TObject; Socket: TCustomWinSocket);
    procedure SocketError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
    procedure SocketRead(Sender: TObject; Socket: TCustomWinSocket);
    destructor Destroy; override;
  end;

implementation

constructor TTestClass.Create(Address: String; Port: Integer);
begin
  Socked:= TClientSocket.Create(nil);
  with Socked do
  begin
    Address:= Address;
    Host:= Address;
    Port:= Port;
    OnConnect:= SocketConnect;
    OnDisconnect:= SocketDisconnect;
    OnError:= SocketError;
    OnRead:= SocketRead;
    Active:= True;
  end;
end;

destructor TTestClass.Destroy;
begin
  FreeAndNil(Socked);
end;

procedure TTestClass.SocketConnect(Sender: TObject; Socket: TCustomWinSocket);
begin
 // Если подсоеденияемся то начинаем посылать чтонибудь
end;

procedure TTestClass.SocketDisconnect(Sender: TObject; Socket: TCustomWinSocket);
begin

end;

procedure TTestClass.SocketError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
  ErrorCode:= 0;
  Destroy;
end;

procedure TTestClass.SocketRead(Sender: TObject; Socket: TCustomWinSocket);
begin

end;

end.

Естественно вылетает (потомучто Destroy делается одновременно с Create)
Цитата

Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address 7C918FEA in module 'ntdll.dll'. Write of address 00000010'. Process stopped. Use Step or Run to continue.

А как тут можно сделать без ошибки (я чтото запутался)? Какие есть идеи?

Присоединённый файл ( Кол-во скачиваний: 3 )
Присоединённый файл  SelfDestruct.rar 2,66 Kb
PM MAIL   Вверх
bems
Дата 10.12.2007, 19:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 18
Всего: 88



Цитата(Ak47black @  10.12.2007,  18:55 Найти цитируемый пост)
Какие есть идеи?
вместо прямого вызова деструктора выкидывай исключение. Если в конструкторе возникает исключение то деструктор будет вызван автоматом. Поэтому деструктор должен уметь уничточтожать недосозданные объекты



--------------------
Обижено школьников: 8
PM MAIL   Вверх
Ak47black
Дата 10.12.2007, 19:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2205
Регистрация: 2.12.2005

Репутация: нет
Всего: 0



А если ошибка подсоединения произойдет после Create.
Как правильно тут сделать, без ошибок.

Это сообщение отредактировал(а) Ak47black - 10.12.2007, 21:22
PM MAIL   Вверх
Ak47black
Дата 10.12.2007, 21:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2205
Регистрация: 2.12.2005

Репутация: нет
Всего: 0



У когонибудь можеть есть идея как правильно убить TClientSocket  smile ?

Это сообщение отредактировал(а) Ak47black - 10.12.2007, 21:38
PM MAIL   Вверх
Sanchezzz
  Дата 10.12.2007, 22:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1670
Регистрация: 19.11.2006
Где: Voronezh

Репутация: 1
Всего: 60



сделать отдельные процедуры для конекта типа myconect и в ней создовать сразу класс сокета подставлять все процедуры к классу сокета ну естественно в процедуре у сокета в события если ерор то уничтожаем класс сокета . если дисконект то уничтожаем класс сокета. 
я делал подобное только с ицс если у меня сечаз нет не кончится отвечу еше.

Добавлено через 14 минут и 31 секунду
аналогично также и на сокетах...
но лучше ICS подержка проксе и слл итд возможностей все желучше чем обычный сокет клиент

Код

private
    { Private declarations }
public
FWsocket:tWsocket; // это у меня ICS у вас сокетслиент...
procedure FWSCreate;
procedure FWSDestroy;
procedure SessionClosed(Sender: TObject; ErrCode: Word);
procedure SessionConnected(Sender: TObject; ErrCode: Word);
procedure SessionClosed(Sender: TObject; ErrCode: Word);
procedure ERORS (Sender: TObject; ErrCode: Word);

end;

procedure FWSCreate;
 begin
 inherited;
 FWsocket:=TWsocket.Create(nil);
 FWsocket.Proto:='tcp';
 FWsocket.LineLimit:=65384;//65384
// FWsocket.KeepAliveOnOff:=wsKeepAliveOff;
// FWsocket.KeepAliveTime:=0;
// FWsocket.FlushTimeout:=0;
// FWsocket.KeepAliveInterval:=0;
 FWsocket.LineEnd:=#13#10;
//приписываю процедурки
 FWsocket.OnDataAvailable:=    DataAvailable;
 FWsocket.OnSessionClosed:=    SessionClosed;
 FWsocket.OnSessionConnected:= SessionConnected;
FWsocket.onErorr:= ERORS;
 end;

procedure FWSDestroy;
begin
 FWsocket.Close;
 FWsocket.Free;
end;

procedure SessionClosed(Sender: TObject; ErrCode: Word);
begin
//тут если отсоеденились от прокси

end;

procedure TDataModule1.DataAvailable(Sender: TObject; Error: word);
var
  buf : array[0..65384] of char;
   ls,
   len ,it: integer;
begin
   len := FWsocket.Receive(@buf, sizeof(buf));
while len > 0 do
   begin
 //тут читаем код я свой удалил так как он здесь не уместен
end;
end;


procedure TDataModule1.FWsoketConnect;
begin
  if FProxyUSE=true then begin
 case FProxyType of
 0: begin
  FWsocket.SocksLevel:='4';
  FWsocket.SocksServer:=DataModule1.FProxHost;
  FWsocket.SocksPort:=DataModule1.FProxPort;
  end;
 1:begin
  FWsocket.SocksLevel:='4A';
  FWsocket.SocksServer:=DataModule1.FProxHost;
  FWsocket.SocksPort:=DataModule1.FProxPort;
  end;
 2: begin
  FWsocket.SocksLevel:='5';
  FWsocket.Addr := DataModule1.FHost;
  FWsocket.Port := DataModule1.FPort;
 end;
 end;
 if FProxyAuthorize=true then begin
 FWsocket.SocksAuthentication:=socksAuthenticateUsercode;
 FWsocket.SocksUsercode:=DataModule1.FProxyUser;
 FWsocket.SocksPassword:=DataModule1.FProxyUserPass;
 end else begin
 FWsocket.SocksAuthentication:=socksNoAuthentication;
 FWsocket.SocksUsercode:='';
 FWsocket.SocksPassword:='';
 end;
  FWsocket.Addr := FHost;
  FWsocket.Port := FPort;
  FWsocket.Connect;
  end else begin
  FWsocket.Addr := FHost;
  FWsocket.Port := FPort;
  FWsocket.SocksLevel:='5';
  FWsocket.SocksServer:='';
  FWsocket.SocksPort:='';
  FWsocket.SocksAuthentication:=socksNoAuthentication;
  FWsocket.SocksUsercode:='';
  FWsocket.SocksPassword:='';
  FWsocket.Connect;
  end;
end;

procedure ERORS (Sender: TObject; ErrCode: Word);//не правельно написал это но основная идея 
begin
FWSDestroy;
end;



--------------------
Понравился ответ "+" по репе, не забываем закрывать тему, заказы в LS.
PM MAIL Skype GTalk   Вверх
Ak47black
Дата 11.12.2007, 15:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2205
Регистрация: 2.12.2005

Репутация: нет
Всего: 0



Sanchezzz, в вышеприведенном коде, я вижу одно главное отличие (если не считать поддержку proxy)
Код

procedure FWSDestroy;
begin
 FWsocket.Close;
 FWsocket.Free;
end;

тоесть ты вначале закрываешь сокет, а после освобождаешь.
Попробовал я это сделать с  TClientSocket но тоже ошибка 
Цитата

Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address 7C918FEA in module 'ntdll.dll'. Write of address 00000010'.

Возможно я неправ.
PM MAIL   Вверх
Sanchezzz
  Дата 11.12.2007, 20:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1670
Регистрация: 19.11.2006
Где: Voronezh

Репутация: 1
Всего: 60



а ты можешь сразу уничтожать free должно работать или делать проверку на ICS он такого вроде не выдавал у меня.
ой я забыл в ставить FWsoketConnect; в создание...

В дестрое можно написать такое 
Код

procedure FWSDestroy
begi
if  FWsocket.Active=true then  FWsocket.close;
FWsocket.Free;
end;


подчти во всех события советую проверять активен ли? сокет 

Это сообщение отредактировал(а) Sanchezzz - 11.12.2007, 20:05


--------------------
Понравился ответ "+" по репе, не забываем закрывать тему, заказы в LS.
PM MAIL Skype GTalk   Вверх
Ak47black
Дата 12.12.2007, 17:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2205
Регистрация: 2.12.2005

Репутация: нет
Всего: 0



Дестрой то он делает.
Но класс юзает потоки и чтобы благополучно завершить нужно дождаться окончания их работы.
Тут надо другой выход искать мне.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0560 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.