Arkadaşlar merhaba;
Bir yazılım yapmaya çalışıyorum. Yazılım içinde normalde 1 adet tsock componenti kullanıp bir portu dinliyorum ve gelen mesajları listeliyorum. Buraya kadar bir problem yok.
Fakat kullanıcı birden fazla alıcı eklebilmeli. Her eklediği alıcı farklı portu dinleyecek. Bunu dizayn anında yapabilme imkanım varmı? Veya başka bir yolu varmıdır ?
Örnek olarak bir adet alıcı ekledim ve bu 10001 portunu dinliyor. Bir adet daha ekledim o da 10002 portunu dinliyor. Bu ayarları bir veritabanına kaydedip program açıldığı anda ayarlara göre ilgili portların dinlenmesini nasıl sağlayabilirim ? Sonuçta kullanıcının kaç adet alıcı ekleyeceğini bilmiyorum ve bununda 5-10 ile sınırlı olmayacağını düşünüyorum..
Herkese teşekkürler
Algoritma Önerileri
Forum kuralları
Forum kurallarını okuyup, uyunuz!
Forum kurallarını okuyup, uyunuz!
- fesiharslan
- Üye
- Mesajlar: 591
- Kayıt: 20 Eki 2006 11:37
- Konum: Erzurum
- İletişim:
Re: Algoritma Önerileri
Merhaba;
Üç adet tablo ile bu işlemleri gerçekleştirebilirsiniz.
Kullanıcı Tablosu: Uygulamayı kullanan son kullanıcı bilgilerini içerir.
Soket Tablosu: Aktif olan soket ve port bilgilerini içerir.
Kullanıcı_Soket Tablosu: Hangi kullanıcının hangi soketleri ve hangi portları dinlediğini içerir.
Yöntem olarak;
Aktif Tüm soketler için Ortak Receive metodu yazılır.
Uygulama başlatıldığı anda soket tablosu okunur.
Tablo sayısınca kayıtlar döngüye tabi tutulur.
Her döngüde dinamik bir Soket oluşturulur ve özellikleri Set edilir. (PortNo, OnReceive vb.)
Üç adet tablo ile bu işlemleri gerçekleştirebilirsiniz.
Kullanıcı Tablosu: Uygulamayı kullanan son kullanıcı bilgilerini içerir.
Soket Tablosu: Aktif olan soket ve port bilgilerini içerir.
Kullanıcı_Soket Tablosu: Hangi kullanıcının hangi soketleri ve hangi portları dinlediğini içerir.
Yöntem olarak;
Aktif Tüm soketler için Ortak Receive metodu yazılır.
Uygulama başlatıldığı anda soket tablosu okunur.
Tablo sayısınca kayıtlar döngüye tabi tutulur.
Her döngüde dinamik bir Soket oluşturulur ve özellikleri Set edilir. (PortNo, OnReceive vb.)
Re: Algoritma Önerileri
Merhaba,
Kullandığın Delphi versiyonunu belirtmemişsin. Benim aşağıda anlattıklarım Delphi 10 için geçerlidir. Yüksek ihtimalle birçok XE sürümünde de çalışacaktır.
Sadece tek bir nesne dinamik olarak çalışma zamanında kullanılacak ise şuradaki örneği inceleyebilirsin:
http://forums.devshed.com/delphi-progra ... 89039.html
Ancak birden fazla, farklı nesneler için TObjectList kullanabilirsin. İki farklı kullanımı var. Basit bir örnek için aşağıdaki kodu inceleyebilirsin. İnternette daha detaylı aramalar yapmanı tavsiye ederim.
Program çalıştığında dinamik olarak nesneleri oluşturmak için aşağıdaki gibi bir yöntem izleyebilirsin.
Nesneler oluşturulduktan sonra zamanı geldiğinde aşağıdaki gibi bir yöntem ile ilgili nesneyi TObjectList içinden bulup kullanabilirsin.
Önemli bir nokta da kapanırken hafızada kalıntı bırakmamaktır. Bunu OnDestroy olayında kontrol altına alabiliriz.
Alışkanlık olarak her programın geliştirme safhasında hafızada kaçak olmadığını anlamak adına proje dosyanın içine (Project->View Source) aşağıdaki satırı eklemeni tavsiye ederim.
Böylece uygulama kapatıldığında eğer bir hafıza kaçağı varsa sana bir mesaj içinde ne tür nesneleri hafızadan temizleyemediğini bildirecektir.
Kullandığın Delphi versiyonunu belirtmemişsin. Benim aşağıda anlattıklarım Delphi 10 için geçerlidir. Yüksek ihtimalle birçok XE sürümünde de çalışacaktır.
Sadece tek bir nesne dinamik olarak çalışma zamanında kullanılacak ise şuradaki örneği inceleyebilirsin:
http://forums.devshed.com/delphi-progra ... 89039.html
Ancak birden fazla, farklı nesneler için TObjectList kullanabilirsin. İki farklı kullanımı var. Basit bir örnek için aşağıdaki kodu inceleyebilirsin. İnternette daha detaylı aramalar yapmanı tavsiye ederim.
Program çalıştığında dinamik olarak nesneleri oluşturmak için aşağıdaki gibi bir yöntem izleyebilirsin.
Kod: Tümünü seç
uses System.Contnrs, // TObjectList
Vcl.ExtCtrls, // TTimer
IdFTP; // TIdFTP
// Farklı nesneler dinamik olarak oluşturulacağı için sınıf tanımı kullanılıyor.
type
TMyClass = class(TObject)
newTmr : TTimer;
newidFTP : TidFTP;
Active : Boolean;
end;
type
TfrmMain = class(TForm)
TrayIcon1: TTrayIcon;
ApplicationEvents1: TApplicationEvents;
Timer1: TTimer;
.
.
.
private
{ Private declarations }
var
fList:TObjectList; // Dinamik oluşturulacak nesneleri içinde saklayacağımız TObjectList değişkeni
public
{ Public declarations }
end;
var
frmMain: TfrmMain;
implementation
{$R *.dfm}
procedure TfrmMain.FormCreate(Sender: TObject);
var
cls:TMyClass;
begin
// Dinamik oluşturulan nesnelerin listesinin saklanacağı Obje Listesini oluştur
fList := TObjectList.Create(False);
// Yukarıdaki parametre anlamı:
// True = TObjectList.Free çalıştırıldığında içindeki nesneleri kendisi Free etsin.
// False = biz kendimiz Free edeceğiz.
// Daha önce True kullandığımda kendisi free edemediği için ben kod yazarak hafıza kontrolü yapmayı tercih ediyorum.
// FOR ... aşağıdaki kısımı bir döngü içine koyulduğu zaman istediğin kadar dinamik olarak nesne oluşturabilirsin.
cls := TMyClass.Create;
// CLASS içindeki değişkenlere direk atamalar yapabiliriz.
cls.Active := True;
// CLASS içindeki nesneler kullanılmadan önce create edilmeli
cls.newTmr := TTimer.Create(nil);
cls.newTmr.Interval := 0; // Normalde sıfır olarak ayarla
cls.newTmr.Interval := 5 * 60000; // 5 dakikada bir çalış
cls.newTmr.OnTimer := Timer1Timer; // Tüm Timer nesneleri aynı prosedürü paylaşsın. Yapacakları iş aynı
cls.newTmr.Enabled := False; // Hemen çalışmaya başlama
cls.newTmr.Tag := 20; // aradığın nesneyi bulmak adına nesnenin bir parametresine indeks bilgisini kaydetmek gerekecektir. FOR döngüsü kullanırsan döngü değişkenini burada kullanabilirsin.
// CLASS içindeki nesneler kullanılmadan önce create edilmeli
cls.newidFTP := TidFTP.Create(nil);
cls.newidFTP.Host := '192.168.1.5';
cls.newidFTP.Username := 'test@test.com';
cls.newidFTP.Password := 'anonymous';
cls.newidFTP.Passive := True;
// Gerekli tüm parametreler tanımlandıktan sonra nesneleri TObjectList içinde saklansın
fList.Add(cls);
// END FOR
end;
Kod: Tümünü seç
function TfrmMain.FindMyClass(idx:Integer; var cls:TMyClass): Boolean;
var i:Integer;
begin
Result := False;
for i := 0 to fList.Count-1 do begin
if TMyClass(fList[i]).newTmr.Tag = idx then begin
cls := TMyClass(fList[i]);
Result := True;
Break; // aradığımızı bulduk. artık çıkabiliriz.
end;
end;
end;
procedure TfrmMain.Timer1Timer(Sender: TObject);
var
cls:TMyClass;
begin
// TAG içine hangi Timer nesnesini kullanacağımıza dair bilgiyi OnFormCreate zamanında saklamış olmamız gerekli
// Bu noktada hangi Timer çalıştığını Timer.Tag parametresinden ayırt edebiliriz.
if not FindMyClass((Sender as TTimer).Tag, cls) then Exit;
// Artık cls içinde kullanacağımız bilgiler var. Ne istiyorsak yapabiliriz.
cls.newidFTP.Connect;
cls.newidFTP.Disconnect;
end;
Kod: Tümünü seç
procedure TfrmMain.ClearMemory;
var
i:Integer;
cls:TMyClass;
begin
for i := 0 to fList.Count-1 do begin
cls := (fList[i] as TMyClass);
cls.newTmr.Free;
cls.newidFTP.Free;
fList[i].Free;
end;
fList.Free;
end;
procedure TfrmMain.FormDestroy(Sender: TObject);
begin
ClearMemory;
end;
Alışkanlık olarak her programın geliştirme safhasında hafızada kaçak olmadığını anlamak adına proje dosyanın içine (Project->View Source) aşağıdaki satırı eklemeni tavsiye ederim.
Kod: Tümünü seç
ReportMemoryLeaksOnShutdown := True;
Re: Algoritma Önerileri
Bütün İletişimi tek bir port dinleyerek sağlaman daha doğru olur çünkü her açtığın port için, işletim sisteminin güvenlik duvarında belli izinler isteyecek ve bunları düzenlemen zorlaşacaktır. ( Örneğin açamaya çalıştığın portlardan birini yeni kurduğun bir program kullanıyor olması vs gibi sorunlar..)
Bunun yerine tek bir port kullan, her bağlanan kullanıcının mesajı içinde benzersiz kimlik tanımlayıcı ( id no ) numara ile mesaj göndersin. Veritabanını karşılaştırır bu id ye sahip biri yoksa yeni kullanıcımı , kayıtlı kullanıcımı olduğunu anlamış olursun.
Bunun yerine tek bir port kullan, her bağlanan kullanıcının mesajı içinde benzersiz kimlik tanımlayıcı ( id no ) numara ile mesaj göndersin. Veritabanını karşılaştırır bu id ye sahip biri yoksa yeni kullanıcımı , kayıtlı kullanıcımı olduğunu anlamış olursun.