Veritabanı oluşturma. Delphi: ağ programlama

  • 28.06.2019

Bugün, bilgi teknolojisi alanındaki konu, istemci-sunucu mimarisinin geliştirilmesi ve dağıtımına adanmış olarak çok alakalı olmaya devam etmektedir. Bunun nedeni, çeşitli ölçeklerdeki bilgi sistemlerinin çeşitli alanlarda giderek daha fazla kullanılmasıdır. Ayrıca, herhangi bir veritabanının yapısı, belirli parametrelere göre ve yalnızca özel uygulamaların kullanımıyla normal modda onunla çalışmak mümkün olacak şekilde oluşturulur. Bu nedenle, "istemci-sunucu" mimarisinin uygulanması, çeşitli tesislerdeki bilgi teknolojisi departmanlarının karşı karşıya olduğu çok önemli bir görevdir ve başarılı çözümü işletmenin optimum ve sorunsuz çalışmasını sağlayacaktır.

Soket tabanlı sunucu

Soket tabanlı bir sunucu, çok sayıda kullanıcıdan gelen isteklerin aynı anda işlenmesine izin verir. Bu durumda, yönetici aynı anda hizmet verilen kullanıcı sayısına bir sınır getirmek için istediği zaman ayarlarda değişiklik yapabilir. Varsayılan olarak, bu parametre herhangi bir kısıtlama içermez.

İstemci sunucuya bağlandıktan sonra, veri alışverişinin yapıldığı soketli ayrı bir kanal açılır. Ancak, her yeni bağlantı için özel bir ayrı süreç dağıtmak en uygun ve en güvenli yöntemdir.

"Müşteri - sunucu" mimarisinin şeması

Sık kullanılan tanımları sırayla analiz ederek mimari uygulama şemasını daha ayrıntılı olarak ele alalım:

1. Özellikler Sunucu Türü ve Bağlantı Noktası. Kullanıcının sunucuya bağlanabilmesi için hem sunucu hem de istemci tarafından kullanılan bağlantı noktasının aynı olması önemlidir. Port özelliğinde yapılan bu parametrenin amacıdır. Bağlantı türü, ServerType parametresi tarafından belirlenir.

2. Soket açma işlemi. İstemci/sunucu oturumu başlatmak için bir soket ve bağlantı noktası açmak önemlidir. Listen özelliği kullanılır.

3. Ayrıca kullanıcı ile veri alışverişi yapılır. Kapatıldığında, istemcinin bağlantısı kesilir. Uygun olduğunda, sunucu, kurulan tüm bağlantıları keserek ve yeni bağlantılar için bekleme sürecini sonlandırarak işini bitirir.

Delphi İstemci-Sunucu Uygulamalarında TServerSocket Kullanımı

Kullanıcıdan bilgi göndermek ve almak için OnClientWrite ve OnClientRead olayları kullanılır. Bu durumda ClientSocket gibi bir parametre üzerinden kullanıcı ile etkileşime girebilirsiniz. Çalışırken, aşağıdaki yöntemler ve özellikler sıklıkla kullanılır:

Şu anda bağlı olan kullanıcıların sayısı;

Aktif süreçlerin sayısı;

Ücretsiz işlem sayısı;

Bağlantı noktası, ana bilgisayar adı ve yerel IP adresi;

Bir soketin blokesini kaldırma ve engelleme.

Sonuç olarak, sık kullanılan özel özelliğe - Data'ya dikkat edelim. Bu özellik aşağıdaki durumda geçerlidir. Kural olarak, sunucu çok sayıda kullanıcıya hizmet vermek için kullanılır, bu da her istemci hakkında bilgi depolamaya ihtiyaç olduğu ve bu bilgilerin belirli bir sokete bağlanması gerektiği anlamına gelir. Bu gibi durumlarda, manuel bağlama kullanmak çok sakıncalıdır ve bu nedenle Data özelliği yaygın olarak kullanılır. Ancak, Data'nın bir işaretçi olduğunu hatırlamak önemlidir ve bu nedenle işaretçilerle çalışmak için tüm kuralların karşılanıp karşılanmadığını kontrol etmek önemlidir (tür göstergesi, bellek ayırma vb.)

belgeler

Bugüne kadar, soketlerin geliştirilmesi ve kullanılmasıyla ilgili Delphi istemci/sunucu uygulamaları geliştirmeye ilişkin çok az literatür bulunmaktadır. Bu nedenle, bu yönün ayrıntılı bir incelemesi için Linux ve Unix sistemleri hakkındaki belgelere başvurabilirsiniz, çünkü Bununla birlikte, bir kural olarak, Perl veya C ++ dillerinde, soketleri kullanarak uygulamaları dağıtma teknolojisini biraz ayrıntılı olarak tartışır.

menüyü seçin: Bileşen - Paketleri Yükle ... - Ekle., ardından ... \ bin \ dclsockets70.bpl dosyasını belirtmeniz gerekir.

Başlangıç ​​olarak, ağ sohbeti örneğini kullanarak doğrudan bir istemci-sunucu projesi oluşturmaya devam edelim.

İki kullanıcı için çevrimiçi sohbet

Kural olarak, herhangi bir programın geliştirilmesi, gerçekleştirmesi gereken görevlerin tanımlanmasıyla ve bu aşamada gerekli bileşenlerin tanımlanmasıyla başlar. Programımız, her biri hem sunucu hem de istemci olabilen iki kullanıcı için bir sohbettir, yani bileşenleri forma atıyoruz. SunucuSoketi ve İstemciSoketi... Port her ikisi için de önemli bir parametredir. Sadece aynı özellik değerine sahip Liman, aralarındaki bağlantı kurulacaktır. Bileşenleri forma atalım Düzenlemek, portu hızlı bir şekilde değiştirmek için hadi diyelim LimanDüzenle... Sunucuya bağlanmak için sunucunun IP'sini veya adını belirtmeniz gerekiyor, o halde bir tane daha atalım Düzenlemek, diyelim Ana BilgisayarDüzenle... Ayrıca iki taneye daha ihtiyacımız var Düzenlemek"ve takma adı belirtmek ve mesajın metnini girmek için onları arayalım NikDüzenle ve MetinDüzenle, sırasıyla. Alınan ve gönderilen mesajların metni şurada görüntülenecektir: Hafıza, şeklin içine atalım ve onu arayalım SohbetNotu... Dikey kaydırma çubuğunu bir kerede ayarlayalım: kaydırma çubukları = ssDikey ve mülk Sadece oku = NS... Kontrol tuşları ekle Buton: SunucuBtn- sunucuyu oluşturmak / kapatmak için, MüşteriBtn- bir istemciyi bir sunucuya bağlamak / bağlantısını kesmek için, GönderBtn- mesaj göndermek için. Değiştirmek Altyazı bu tuşlar " Sunucu oluştur", "Bağlamak" ve " göndermek", sırasıyla. Son dokunuş, yazıt eklemektir. Etiket forma uygun formu vermek (bu isteğe bağlıdır).

Ana amaç bu olmadığı için kodlara değer girmenin doğruluğu için herhangi bir kontrol olmayacağı konusunda sizi hemen uyaracağım. Çekleri kendiniz kolayca kaydedebilirsiniz.

Form oluştururken ne olması gerektiğini tanımlayalım. İşlemi anlatalım OnCreate:


başlamak
// önerilen bağlantı noktası değeri
PortEdit.Text: = "777";
// programı bir PC'de kontrol ederken adres ("kendisine")
HostEdit.Text: = "127.0.0.1";
// sadece kalan alanları temizle
NikEdit.Clear;
TextEdit.Clear;
ChatMemo.Lines.Clear;
son;

Sunucu modunun seçildiğini varsayalım. Programın sunucu moduna aktarılması " tuşuna basılarak gerçekleştirilir. Sunucu oluştur" (SunucuBtn)... Bu modu veya benzeri bileşenleri devre dışı bırakmak için ekstra tuşlar kullanmamak için Radyo düğmesi, aynı özelliği kullanabilirsiniz Etiket anahtarlar SunucuBtn değer belirtilenle eşleşirse, değerlerini değiştirmek ve belirli işlemleri gerçekleştirmek. Bir tuşa basma prosedürü şöyle görünür SunucuBtn (Tıklamada):

prosedür TForm1.ServerBtnClick (Gönderen: TObject);
başlamak
ServerBtn.Tag = 0 ise
Başlamak
// ClientBtn anahtarı ve HostEdit, PortEdit alanları engellendi
ClientBtn.Enabled: = Yanlış;
HostEdit.Enabled: = Yanlış;
PortEdit.Enabled: = Yanlış;
// belirtilen portu ServerSocket'a yaz
ServerSocket.Port: = StrToInt (PortEdit.Text);
// sunucuyu başlat
ServerSocket.Active: = Doğru;
// ChatMemo'ya oluşturma zamanı ile birlikte bir mesaj ekleyin
ChatMemo.Lines.Add ("[" + TimeToStr (Zaman) + "] Sunucu oluşturuldu");
// etiketi değiştir
ServerBtn.Tag: = 1;
// anahtar etiketini değiştir
ServerBtn.Caption: = "Sunucuyu Kapat";
son
Başka
Başlamak
// ClientBtn anahtarının ve HostEdit, PortEdit alanlarının engellemesini kaldırın
ClientBtn.Enabled: = Doğru;
HostEdit.Enabled: = Doğru;
PortEdit.Enabled: = Doğru;
// sunucuyu kapat
ServerSocket.Active: = Yanlış;

ChatMemo.Lines.Add ("[" + TimeToStr (Zaman) + "] Sunucu kapalı.");

ServerBtn.Tag: = 0;

ServerBtn.Caption: = "Sunucu Oluştur";
son;
son;

Belirli bir durum altında gerçekleşmesi gereken olayları bulalım. SunucuSoketi"a. İstemci sunucuya bağlandığında bir prosedür yazalım ( OnClientConnect):

prosedür TForm1.ServerSocketClientConnect (Gönderen: TObject;
Soket: TCustomWinSocket);
başlamak
// ChatMemo'ya istemcinin bağlantı zamanı ile bir mesaj ekleyin
ChatMemo.Lines.Add ("[" + TimeToStr (Zaman) + "] İstemci bağlandı.");
son;

İstemci bağlantısı kesildiğinde bir prosedür yazalım ( OnClientBağlantıyı Kes):

prosedür TForm1.ServerSocketClientDisconnect (Gönderen: TObject;
Soket: TCustomWinSocket);
başlamak
// İstemci bağlantısının kesildiği süre ile ChatMemo'ya bir mesaj ekleyin
ChatMemo.Lines.Add ("[" + TimeToStr (Zaman) + "] İstemcinin bağlantısı kesildi.");
son;

İstemciden bir sonraki mesaj sunucuya ulaştığında, hemen göstermeliyiz. Bir müşteriden gelen mesajı okumak için bir prosedür yazalım ( OnClientRead):


Soket: TCustomWinSocket);
başlamak


son;

En önemli şey mesaj göndermektir. Burada "Gönder" düğmesine basılarak gerçekleştirilir ( GönderBtn), ancak sunucu veya istemci program modunu kontrol etmek gereklidir. Prosedürünü yazalım ( Tıklamada):

prosedür TForm1.SendBtnClick (Gönderen: TObject);
başlamak
// programın hangi modda olduğunu kontrol et

// sunucudan bir mesaj gönder (sadece bir tane olduğundan 0 olarak numaralandırılmıştır)
ServerSocket.Socket.Connections.SendText ("[" + TimeToStr (Zaman) + "]" + NikEdit.Text + ":" + TextEdit.Text)
Başka
// istemciden bir mesaj gönder
ClientSocket.Socket.SendText ("[" + TimeToStr (Zaman) + "]" + NikEdit.Text + ":" + TextEdit.Text);
// mesajı ChatMemo'da göster
ChatMemo.Lines.Add ("[" + TimeToStr (Zaman) + "]" + NikEdit.Text + ":" + TextEdit.Text);
son;

Şimdi müşteri modu ile ilgilenelim. Burada, aksine, "Bağlan" tuşuna bastığınızda ( MüşteriBtn) engellendi SunucuBtn ve etkinleştirildi İstemciSoketi... İşte prosedür ClientBtn (OnClick):

prosedür TForm1.ClientBtnClick (Gönderen: TObject);
başlamak
ClientBtn.Tag = 0 ise
Başlamak
// ServerBtn anahtarı ve HostEdit, PortEdit alanları engellendi
ServerBtn.Enabled: = Yanlış;
HostEdit.Enabled: = Yanlış;
PortEdit.Enabled: = Yanlış;
// belirtilen portu ClientSocket'a yaz
ClientSocket.Port: = StrToInt (PortEdit.Text);
// host ve adres yaz (her ikisi için bir HostEdit değeri)
ClientSocket.Host:=HostEdit.Text;
ClientSocket.Address: = HostEdit.Text;
// istemciyi başlat
ClientSocket.Active: = Doğru;
// etiketi değiştir
ClientBtn.Tag: = 1;
// anahtar etiketini değiştir
ClientBtn.Caption: = "Bağlantıyı Kes";
son
Başka
Başlamak
// ServerBtn anahtarı ve HostEdit, PortEdit alanlarının engellemesi kaldırıldı
ServerBtn.Enabled: = Doğru;
HostEdit.Enabled: = Doğru;
PortEdit.Enabled: = Doğru;
// istemciyi kapat
ClientSocket.Active: = Yanlış;
// mesajı ChatMemo'da göster
ChatMemo.Lines.Add ("[" + TimeToStr (Zaman) + "] Oturum kapandı.");
// orijinal değeri etikete döndür
ClientBtn.Tag: = 0;
// orijinal anahtar etiketini döndür
ClientBtn.Caption: = "Bağlan";
son;
son;

Prosedürleri belirlemek için kalır OnConnect, Açık Bağlantıyı Kes, OnRead müşteri İstemciSoketi... İlk olarak, sunucudan gelen mesajı okumak için ( OnRead):


Soket: TCustomWinSocket);
başlamak
// alınan mesajı ChatMemo'ya ekle
ChatMemo.Lines.Add (Socket.ReceiveText());
son;

prosedür TForm1.ClientSocketConnect (Gönderen: TObject;
Soket: TCustomWinSocket);
başlamak
// sunucuya ChatMemo'ya bağlanma hakkında bir mesaj ekleyin
ChatMemo.Lines.Add ("[" + TimeToStr (Zaman) + "] Sunucuya bağlanılıyor.");
son;

prosedür TForm1.ClientSocketDisconnect (Gönderen: TObject;
Soket: TCustomWinSocket);
başlamak
// ChatMemo'ya kayıp bir bağlantı mesajı ekleyin
ChatMemo.Lines.Add ("[" + TimeToStr (Zaman) + "] Sunucu bulunamadı.");
son;

İşte yapılması gereken minimum miktar. Bazı değerlerin girişinin doğruluğunu kontrol etmek için biraz daha algoritma tanıtmak için kalır.
Soru ortaya çıkıyor: Ya veri aktarmanız gerekiyorsa ve dize değil de bir tür dizi aktarmanız gerekiyorsa? Bunun için özel komutlar var. Bir oyun için komut olarak bir dizi göndermek için bir algoritma yazmaya çalışalım.

Toplu veri gönderme

Aynı sohbet formunu kullanalım, aşağıya birkaç bileşen eklemeniz yeterli. Görevin bir tür nesneyi yönetmek olmasına izin verin Şekil, geometrik şekil, renk, boyut türünü değiştirin. Bileşeni forma yerleştirin Grup Kutusu, ve içine Şekil, isimleri aynı olacak. Geometrik şeklin türünü değiştirmek için listeyi kullanın. Açılan kutu, diyelim ŞekilCBox... Hemen doldurmayacağız, bunu yapacağız OnCreate formlar. Ardından, aynı şeye ihtiyacınız var Açılan kutu bir renk seçmek için ve iki Düzenlemek"ve şeklin boyutunu belirtmek için (dikdörtgen olması durumunda iki değerimiz var, ilkini daire için kullanacağız). RenkCBox, Değer1Düzenle, Değer2Düzenle, sırasıyla. Bileşenlerin şeklini alan son kişi Buton, diyelim GönderBufBtn, Altyazı değişmek " arabellek gönder".
Girdi verilerinin bir veri arabelleği biçiminde nasıl temsil edileceği hakkında biraz. Tamponda hangi değerin hangi değerden sonra geldiğini hemen sırayla belirlemek gerekir. Önce şekil türü, ardından renk ve ardından her iki boyut değeri olsun. Bu amaçlar için, bir dizi uzunluk kullanın 4 ve yazın Bayt... bölüme ekleyelim var dizi:

Buf: Bayt dizisi;

Şeklin boyutu ile her şey açıktır, ancak tür ve renk için bir "doğruluk tablosuna" ihtiyacınız vardır. Bunu aşağıdaki gibi temsil edelim:

parametre kodu
dikdörtgen 0
daire 1
-------------------
kırmızı 0
yeşil 1
mavi 2

Bu bir gösteri için yeterlidir. İsteğe bağlı olarak, parametre aralığını genişletebilir, dolgu tipini, kontur tipini, ofseti girebilir veya örneği başka amaçlar için kullanabilirsiniz.
Listeleri doldurarak kayıt olacağız OnCreate formlar:

prosedür TForm1.FormCreate (Gönderen: TObject);
başlamak

// ... sohbetin bir parçası ...

// listeleri doldurun
ShapeCBox.Items.Add ("dikdörtgen");
ShapeCBox.Items.Add ("daire");
ColorCBox.Items.Add ("kırmızı");
ColorCBox.Items.Add ("yeşil");
ColorCBox.Items.Add ("mavi");
son;

" tuşuna bastığınızda arabellek gönder"alanlardan veri toplayacağız ve bilinen uzunlukta bir dizi oluşturacağız ve ardından sunucu / istemci modunu kontrol edip göndereceğiz. İşte prosedür SendBufBtn (OnClick):

prosedür TForm1.SendBufBtnClick (Gönderen: TObject);
başlamak
// gönderilecek verileri topla
Buf: = ShapeCBox.ItemIndex;
Buf: = ColorCBox.ItemIndex;
Buf: = StrToInt (Value1Edit.Text);
Buf: = StrToInt (Value2Edit.Text);
// program modunu kontrol et
ServerSocket.Active = True ise
// sunucudan bir arabellek gönder (uzunluk biliniyor - 4)
ServerSocket.Socket.Connections.SendBuf (Buf, 4)
Başka
// istemciden bir arabellek gönder
ClientSocket.Socket.SendBuf (Buf, 4);
// ChatMemo'ya bir veri aktarım mesajı ekleyin
ChatMemo.Lines.Add ("[" + TimeToStr (Zaman) + "] Veri aktarıldı.");

Shape.Height: = Buf;
Shape.Width: = Buf;

Eğer Buf>


Vaka Buf'u
0: Shape.Brush.Color: = clRed;

2: Shape.Brush.Color: = clBlue;
son;
// alanlardaki verileri değiştir
ShapeCBox.ItemIndex: = Buf;
ColorCBox.ItemIndex: = Buf;


son;

İstemciden bir mesaj okuma prosedürünü biraz değiştirelim, mesaj alma özelliğini kapatalım ve bir arabellek alacak şekilde ayarlayalım ( OnClientRead):

prosedür TForm1.ServerSocketClientRead (Gönderen: TObject;
Soket: TCustomWinSocket);
var
uzunluk: Bayt;
başlamak
// ChatMemo'ya bir istemci mesajı ekleyin


len: = Socket.ReceiveLength;
Socket.ReceiveBuf (Buf, uzun);
// değişiklikleri şeklimize uygula
Shape.Height: = Buf;
Shape.Width: = Buf;
Buf> 0 ise Shape.Shape: = stCircle (daire)
başka Shape.Shape: = stRectangle; (dikdörtgen)
// doğruluk tablosuna göre renk seçimi
Vaka Buf'u
0: Shape.Brush.Color: = clRed;
1: Shape.Brush.Color: = clGreen;
2: Shape.Brush.Color: = clBlue;
son;
// alanlardaki verileri değiştir
ShapeCBox.ItemIndex: = Buf;
ColorCBox.ItemIndex: = Buf;
Value1Edit.Text: = IntToStr (Takviye);
Value2Edit.Text: = IntToStr (Takviye);


son;

İstemcinin mesajı sunucudan okuma prosedürünü değiştirmek aynı şekilde kalır ( OnRead):

prosedür TForm1.ClientSocketRead (Gönderen: TObject;
Soket: TCustomWinSocket);
var
uzunluk: Bayt;
başlamak
// sunucudan ChatMemo'ya bir mesaj ekleyin
// ChatMemo.Lines.Add (Socket.ReceiveText());
// boyutu bilinmeyen bir arabelleği kabul et
len: = Socket.ReceiveLength;
Socket.ReceiveBuf (Buf, uzun);
// değişiklikleri şeklimize uygula
Shape.Height: = Buf;
Shape.Width: = Buf;
Buf> 0 ise Shape.Shape: = stCircle (daire)
başka Shape.Shape: = stRectangle; (dikdörtgen)
// doğruluk tablosuna göre renk seçimi
Vaka Buf'u
0: Shape.Brush.Color: = clRed;
1: Shape.Brush.Color: = clGreen;
2: Shape.Brush.Color: = clBlue;
son;
// alanlardaki verileri değiştir
ShapeCBox.ItemIndex: = Buf;
ColorCBox.ItemIndex: = Buf;
Value1Edit.Text: = IntToStr (Takviye);
Value2Edit.Text: = IntToStr (Takviye);
// verilerin ChatMemo'ya gelişiyle ilgili bir mesaj ekleyin
ChatMemo.Lines.Add ("[" + TimeToStr (Zaman) + "] Alınan veriler.");
son;

Hepsi bu kadar. Lütfen mesaj kabulünü devre dışı bırakmazsanız ( Socket.ReceiveText ()) ve hem mesajı hem de arabelleği aynı anda almaya çalışın, bu, işlevlerden biri için veri kaybına yol açacaktır. Mesajı aşağıdaki gibi bir arabellek biçimine çevirerek bu sorunları çözebilirsiniz:

i için: = 1 ila Uzunluk (TextEdit.Text) yapın
Buf: = Kopyala (TextEdit.Text, i, 1);

Açıkçası, dizi bir hücre daha büyüyecek ve türünü karakter veya dize olarak değiştirecektir. Bu durumda, Buf, gelen arabelleğin bir mesaj mı yoksa veri mi olduğu konusunda bir etiket görevi görecektir. Mesaj alma prosedürlerinde, bunun gibi bir koşul oluşturmanız gerekir:

len: = Socket.ReceiveLength;
Socket.ReceiveBuf (Buf, uzun);
Buf = "t" ise
Başlamak
... bir dizi birleştirme işlemi yapın (bir döngü aracılığıyla)
son;
Buf = "c" ise
Başlamak
... Shape parametrelerini değiştirmek için bir işlem yapın
son;

Tanıtım

Bu makale, Borland Delphi'de soketlere ("soketler" - yuvalar). Soketler konusundaki önceki makaleden farklı olarak, burada sunucu uygulamalarının oluşturulmasını ele alacağız.

Hemen belirtmek gerekir ki, ayrı istemci ve sunucu uygulamalarının bir arada var olması için birden fazla bilgisayara gerek yoktur. Hem sunucuyu hem de istemciyi aynı anda çalıştırdığınız yalnızca bir tane olması yeterlidir. Bu durumda, bağlanmak istediğiniz bilgisayarın adı olarak ana bilgisayar adını kullanmanız gerekir. yerel ana bilgisayar veya IP adresi - 127.0.0.1 .

Öyleyse teoriyle başlayalım. Eğer kararlı bir uygulayıcıysanız (ve gözünüzde herhangi bir algoritma göremiyorsanız), bu bölümü atlamanız gerekir.

Soket Sunucu Algoritması

Peki bir soket sunucusu ne yapılmasına izin verir?.. Nasıl çalışır?.. Soket protokolüne dayalı bir sunucu, aynı anda birçok istemciye hizmet verilmesine izin verir. Ayrıca, sayı sınırlamasını kendiniz belirleyebilirsiniz (veya varsayılan olarak yapıldığı gibi bu sınırlamayı tamamen kaldırabilirsiniz). Her bağlı istemci için sunucu, istemciyle veri alışverişi yapabileceğiniz ayrı bir soket açar. Ayrıca, her bağlantı için ayrı bir işlem (Thread) oluşturmak harika bir çözümdür.

Şemayı daha ayrıntılı olarak analiz edelim:

  • sv-in Port ve ServerType tanımı - istemcilerin normal olarak sunucuya bağlanabilmesi için, sunucu tarafından kullanılan bağlantı noktasının istemci tarafından kullanılan bağlantı noktasıyla tam olarak eşleşmesi gerekir (ve tersi). ServerType özelliği, bağlantı türünü belirler (ayrıntılar için aşağıya bakın);
  • Soket açma - bir soket ve belirtilen bağlantı noktasının açılması. İstemcilerin bağlanmasını beklemeye otomatik olarak başlar ( Dinlemek);
  • Müşteri bağlantısı ve onunla veri alışverişi - burada müşteri bağlanır ve onunla veri alışverişi yapılır. Bu aşamayla ilgili daha fazla ayrıntı, bu makalenin altında ve soketler (istemci tarafı) ile ilgili makalede bulunabilir;
  • İstemci bağlantısını kes - Burada istemcinin bağlantısı kesilir ve sunucuyla olan soket bağlantısı kapatılır;
  • Sunucuyu ve soketi kapatma - Yöneticinin emriyle sunucu işini bitirir, tüm açık soket kanallarını kapatır ve istemci bağlantılarını beklemeyi durdurur.

3-4. noktaların birçok kez tekrarlandığına dikkat edilmelidir, yani. bu adımlar her yeni istemci bağlantısı için gerçekleştirilir.

Not : Şu anda Delphi'de soketler hakkında çok az belge var, bu yüzden bu konuyu olabildiğince derinlemesine incelemek istiyorsanız, o zaman Unix / Linux sistemlerindeki literatüre ve elektronik belgelere bakmanızı tavsiye ederim - orada çok soketlerle çalışma teorisi iyi tanımlanmıştır. Ayrıca bu işletim sistemleri için pek çok soket uygulaması örneği bulunmaktadır (çoğunlukla C/C++ ve Perl'de de olsa).

TServerSocket bileşeninin kısa açıklaması

Burada tanışacağız ana bileşenin özellikleri, yöntemleri ve olayları TServerSocket.

Özellikler yöntemler Gelişmeler
Priz - Açık soket kanallarına erişiminiz olan TServerWinSocket sınıfı. Daha sonra, bu özelliği daha ayrıntılı olarak ele alacağız, çünkü aslında, ana olanlardan biridir. Bir çeşit: TServerWinSocket ;
Sunucu tipi - sunucu tipi. İki değerden birini alabilir: stNonBlocking- istemci soketleri ile senkronize çalışma. Bu tür bir sunucuyla, olaylar aracılığıyla istemcilerle çalışabilirsiniz. OnClientRead ve OnClientWrite. stThreadBlocking- asenkron tip. Her istemci soket kanalı için ayrı bir iş parçacığı oluşturulur. Bir çeşit: TServerType ;
ThreadCacheSize - sunucu tarafından önbelleğe alınacak istemci işlemlerinin (İş parçacığı) sayısı. Burada sunucunuzun iş yüküne göre ortalama değeri seçmeniz gerekiyor. Önbelleğe alma, her seferinde ayrı bir işlem oluşturmamak ve kapalı bir soketi öldürmemek, daha sonra kullanmak üzere bırakmak için gerçekleşir. Bir çeşit: tamsayı ;
Aktif - sunucunun şu anda aktif olup olmadığının bir göstergesi. Yani aslında değer NS sunucunun çalışır durumda olduğunu ve istemcileri almaya hazır olduğunu gösterir ve YANLIŞ- sunucu kapalı. Sunucuyu başlatmak için bu özelliği bir değere ayarlamanız yeterlidir. NS. Bir çeşit: Boole ;
Liman - istemcilerle bağlantı kurmak için bağlantı noktası numarası. Sunucu ve istemciler için bağlantı noktası aynı olmalıdır. 1025 ile 65535 arasındaki değerler önerilir, çünkü 1'den 1024'e kadar - sistem tarafından işgal edilebilir. Bir çeşit: tamsayı ;
Hizmet - hizmeti tanımlayan bir dize ( ftp, http, pop, vb.) kimin portu kullanılacaktır. Port numaralarının çeşitli standart protokollere uygunluğu için bir tür referanstır. Bir çeşit: sicim ;
Açık - Sunucuyu başlatır. Esasen, bu komut bir değer atamakla aynıdır. NS Emlak Aktif;
Kapat - Sunucuyu durdurur. Esasen, bu komut bir değer atamakla aynıdır. YANLIŞ Emlak Aktif.
OnClientConnect - istemci bir soket bağlantısı kurduğunda ve bir sunucu yanıtı beklediğinde oluşur ( Kabul Edildiğinde);
OnClientBağlantıyı Kes - İstemcinin soket kanalıyla bağlantısı kesildiğinde ortaya çıkar;
OnClientError - mevcut işlem başarısız olduğunda oluşur, yani. Bir hata oluştu;
OnClientRead - istemci herhangi bir veriyi sunucuya aktardığında oluşur. Bu verilere düzenlenebilir bir parametre aracılığıyla erişilebilir Soket: TCustomWinSocket;
OnClientWrite - sunucu bir soket aracılığıyla istemciye veri gönderebildiğinde oluşur;
OnGetSocket - bu olayın işleyicisinde parametreyi düzenleyebilirsiniz İstemciSoketi;
OnGetThread - bu olayın işleyicisinde, parametreye atayarak her bir müşteri kanalı için benzersiz bir süreç (İş parçacığı) tanımlayabilirsiniz. SocketThread gerekli alt görev TServerClientThread;
OnThreadStart , OnThreadEnd - sırasıyla bir alt görev (işlem, İş parçacığı) başladığında veya durduğunda oluşur;
Kabul Edildiğinde - sunucu bir istemciyi kabul ettiğinde veya ona bağlanmayı reddettiğinde oluşur;
Dinle - sunucu, istemci bağlantıları için bekleme moduna geçtiğinde oluşur.

TServerSocket.Socket (TServerWinSocket)

Peki sunucu istemciye nasıl veri gönderebilir? Ve veri al? Temel olarak, olaylar üzerinde çalışırsanız OnClientRead ve OnClientWrite, ardından ClientSocket (TCustomWinSocket) parametresi aracılığıyla istemciyle iletişim kurabilirsiniz. İstemci soketleri hakkındaki makalede bu sınıfla çalışma hakkında bilgi edinebilirsiniz. bu sınıf üzerinden veri gönderme/gönderme benzer - yöntemler (Gönder/Al) (Metin, Tampon, Akış). Ayrıca TServerSocket.Socket ile çalışırken. Ancak, o zamandan beri burada bir sunucu düşünüyoruz, o zaman bazı yararlı özellikler ve yöntemler vurgulanmalıdır:

  • Aktif Bağlantılar (tamsayı) - bağlı istemcilerin sayısı;
  • Aktif Konular (tamsayı) - çalışan işlemlerin sayısı; Bağlantılar (dizi) - bağlı her istemci için ayrı TClientWinSocket sınıflarından oluşan bir dizi. Örneğin, şöyle bir komut:
    ServerSocket1.Socket.Connections.SendText ("Merhaba!");
    bağlanacak ilk istemciye bir "Merhaba!" mesajı gönderir. Bu dizinin öğeleriyle çalışmak için komutlar - ayrıca (Gönder / Al) (Metin, Tampon, Akış);
  • IdleThreads (tamsayı) serbest işlemlerin sayısıdır. Bu tür işlemler sunucu tarafından önbelleğe alınır (bkz. ThreadCacheSize);
  • Yerel adres, YerelAna Bilgisayar, YerelLiman- sırasıyla - yerel IP adresi, ana bilgisayar adı, bağlantı noktası;
  • UzakAdres, Uzak Ana Bilgisayar, Uzak Bağlantı Noktası- sırasıyla - uzak IP adresi, ana bilgisayar adı, bağlantı noktası;
  • yöntemler Kilit ve Kilidini aç- sırasıyla, soketi bloke etme ve blokajını kaldırma.

Uygulama ve örnekler

Şimdi özel bir örnekle yukarıdakilere bakalım. Hazır kaynakları tıklayarak indirebilirsiniz.

Öyleyse, TServerSocket ile çalışmanın çok iyi bir örneğine bakalım (bu örnek, bu bileşeni öğrenmek için en görsel yardımcıdır). Aşağıdaki kaynaklar, tüm önemli sunucu olaylarının günlüğe kaydedilmesini ve ayrıca kısa mesaj alma ve gönderme özelliğini gösterir:

Örnek 1. Sunucunun çalışmasını günlüğe kaydetme ve inceleme, soketler aracılığıyla mesaj gönderme / alma.

(... TForm1 formunun dosya başlığı ve tanımının ve Form1 örneğinin gittiği yer burasıdır) (Tam kaynağa bakın) prosedür TForm1.Button1Click (Gönderen: TObject); başlamak (Portu belirleyin ve sunucuyu başlatın) ServerSocket1.Port: = 1025; (Ekle yöntemi, belirtilen konumda diziye bir dize ekler) Memo2.Lines.Insert (0, "Sunucu başlatılıyor"); ServerSocket1.Open; son; prosedür TForm1.Button2Click (Gönderen: TObject); başlamak (Sunucuyu durdurun) ServerSocket1.Active: = Yanlış; Memo2.Lines.Insert (0, "Sunucu durdu"); son; prosedür TForm1.ServerSocket1Listen (Gönderen: TObject; Soket: TCustomWinSocket); başlamak (Burada sunucu, istemciler için soketi "dinler") Memo2.Lines.Insert (0, "Portta dinleme" + IntToStr (ServerSocket1.Port)); son; prosedür TForm1.ServerSocket1Accept (Gönderen: TObject; Soket: TCustomWinSocket); başlamak (Sunucu burada müşteri kabul eder) Memo2.Lines.Insert (0, "İstemci bağlantısı kabul edildi"); son; prosedür TForm1.ServerSocket1ClientConnect (Gönderen: TObject; Soket: TCustomWinSocket); başlamak (Bu, istemcinin bağlandığı yerdir) Memo2.Lines.Insert (0, "İstemci bağlandı"); son; prosedür TForm1.ServerSocket1ClientDisconnect (Gönderen: TObject; Soket: TCustomWinSocket); başlamak (Bu, istemcinin bağlantısının kesildiği yerdir) Memo2.Lines.Insert (0, "İstemci bağlantısı kesildi"); son; prosedür TForm1.ServerSocket1ClientError (Gönderen: TObject; Soket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer); başlamak (Bir hata oluştu - kodunu gösteriyoruz) Memo2.Lines.Insert (0, "İstemci hatası. Kod =" + IntToStr (HataKodu)); son; prosedür TForm1.ServerSocket1ClientRead (Gönderen: TObject; Soket: TCustomWinSocket); başlamak (Müşteriden bir mesaj aldık - bunu Not1'de gösteriyoruz) Memo2.Lines.Insert (0, "İstemciden mesaj alındı"); Memo1.Lines.Insert (0, ">" + Socket.ReceiveText); son; prosedür TForm1.ServerSocket1ClientWrite (Gönderen: TObject; Soket: TCustomWinSocket); başlamak (Artık sokete veri gönderebilirsiniz) Memo2.Lines.Insert (0, "Artık sokete yazabilir"); son; prosedür TForm1.ServerSocket1GetSocket (Gönderen: TObject; Socket: Integer; var ClientSocket: TServerClientWinSocket); Memo2.Lines.Insert'i başlat (0, "Soket al"); son; prosedür TForm1.ServerSocket1GetThread (Gönderen: TObject; ClientSocket: TServerClientWinSocket; var SocketThread: TServerClientThread); Memo2.Lines.Insert'e başlayın (0, "Konu Al"); son; prosedür TForm1.ServerSocket1ThreadEnd (Gönderen: TObject; Konu: TServerClientThread); Memo2.Lines.Insert'i başlat (0, "İş parçacığı sonu"); son; prosedür TForm1.ServerSocket1ThreadStart (Gönderen: TObject; Konu: TServerClientThread); Memo2.Lines.Insert'i başlat (0, "İş parçacığı başlangıcı"); son; prosedür TForm1.Button3Click (Gönderen: TObject); var i: Tamsayı; başlamak (TÜM istemcilere Edit1'den bir mesaj gönderin) i için: = 0 - ServerSocket1.Socket.ActiveConnections-1'e ServerSocket1.Socket.Connections [i] .SendText (Edit1.Text); son; Memo1.Lines.Insert (0, "< "+Edit1.Text); end;

TServerSocket ile (ve sadece soketlerle) çalışma teknikleri

Her müşteri için benzersiz verilerin saklanması.

Elbette, sunucunuz çok sayıda istemciye hizmet verecekse, her istemci için bazı bilgileri (isim vb.) ve bu bilgileri bu istemcinin soketine bağlamanız gerekecektir. Bazı durumlarda, tüm bunları manuel olarak yapmak (bir soket tutamacına, istemci dizilerine vb. bağlama) çok uygun değildir. Bu nedenle, her soket için özel bir özellik vardır - Veri... Aslında, Data sadece bir işaretçidir. Bu nedenle, istemci verilerini bu özelliğe yazarken dikkatli olun ve işaretçilerle çalışma kurallarına (bellek ayırma, tür tanımlama vb.) uyun!

Bir soket üzerinden dosya gönderme.

Burada bir soket üzerinden dosya göndermeye bakacağız (JINX'in isteği üzerine) :-). Peki bir soket üzerinden dosya nasıl gönderilir? Çok basit! Bu dosyayı bir dosya akışı (TFileStream) olarak açmanız ve bir soket (SendStream) aracılığıyla göndermeniz yeterlidir! Bunu bir örnekle görelim:

Unutulmamalıdır ki yöntem Gönderme akışı yalnızca sunucu tarafından değil, istemci tarafından da kullanılır ( ClientSocket1.Socket.SendStream (srcfile))

İletim sırasında neden birkaç blok tek bir blokta birleştirilebilir?

Bu aynı zamanda JINX'in isteği üzerinedir :-). Bunun için ona çok teşekkürler! Bu nedenle, ilk olarak, bir soket aracılığıyla gönderilen verilerin yalnızca bir blokta birleştirilemeyeceğine, aynı zamanda birkaç blokta da bağlantısının kesilebileceğine dikkat edilmelidir. Gerçek şu ki, bir soket normal bir akıştır, ancak örneğin bir dosya akışının (TFileStream) aksine, verileri daha yavaş aktarır (kendiniz anlıyorsunuz - bir ağ, sınırlı trafik, vb.). Bu nedenle iki komut şunlardır:
ServerSocket1.Socket.Connections.SendText ("Merhaba,");
ServerSocket1.Socket.Connections.SendText ("dünya!");
bir komutla tamamen aynıdır:
ServerSocket1.Socket.Connections.SendText ("Merhaba dünya!");

Bu nedenle, örneğin 100 Kb'lik bir soket üzerinden bir dosya gönderirseniz, bu bloğu gönderdiğiniz kişi, trafiğe ve hat tıkanıklığına bağlı olarak birkaç blok alacaktır. Ayrıca, boyutlar mutlaka aynı olmayacaktır. Bir dosyayı veya başka herhangi bir büyük veriyi almak için veri blokları almanız ve ardından bunları bir bütün halinde birleştirmeniz (ve örneğin bir dosyaya kaydetmeniz) gerekir. Bu soruna mükemmel bir çözüm, aynı dosya akışıdır - TFileStream (veya bellekteki bir akış - TMemoryStream). Genel yöntemi kullanarak OnRead (OnClientRead) olayı aracılığıyla bir soketten veri parçacıklarını alabilirsiniz. AlmaBuf... Yöntemi kullanarak ortaya çıkan bloğun boyutunu belirleyebilirsiniz. Alma Uzunluğu... Bir soket akışı da kullanabilirsiniz (TClientSocket makalesine bakın). Ve işte küçük bir örnek (yaklaşık):

Bir soket nasıl izlenir

Bu konu karmaşıktır ve uzun bir değerlendirme gerektirir. Şimdilik, programınız tarafından oluşturulan soketi her zaman izleyebileceğinizi not edeceğim :-). Yuvaların (Windows'taki çoğu nesne gibi) Handle özelliğinde yazılmış kendi tanıtıcıları vardır. Böylece, bu tanımlayıcıyı öğrendikten sonra, herhangi bir soketi (başka birinin programı tarafından oluşturulmuş olsa bile) özgürce kontrol edebilirsiniz! Ancak, büyük olasılıkla, başka birinin soketini izlemek için yalnızca WinAPI Sockets işlevlerini kullanmanız gerekecektir.

sonsöz

Bu makale, Delphi'deki TServerSocket bileşeniyle çalışmak için temel teknikleri ve soketler üzerinden veri alışverişi için bazı genel teknikleri gösterir. Herhangi bir sorunuz varsa - bana e-posta ile gönderin: [e-posta korumalı] mailru.com veya daha iyisi - bu sitenin konferanslarına yazın (Delphi. Genel sorular) böylece diğer kullanıcılar sorunuzu görebilir ve cevaplamaya çalışabilir!

Karikh Nikolay ( nitro). Moskova bölgesi, Zhukovski

Uygulama en basiti olduğu için MS Jet 4.0 veritabanını (yani MS Access veritabanını) kullanmaya karar verdim. Bu karar, Jet'in (lütfen MS Access ile karıştırmayın) ücretsiz bir ürün olması ve MS Windows ile birlikte gelmesinden kaynaklanmaktadır (yani programımızın çalışması için istemcinin bilgisayarına Access'in kendisini yüklemek gereksizdir). ). Ve veritabanı düzenleyicisi çok iyidir ve çekirdek, veri depolamanın en sapkın isteklerini karşılamak için bir dizi alan türünü destekler.

O halde yeni bir veritabanı oluşturalım, adını Test edelim ve C:\ClientServer\Server\Data klasörüne kaydedelim (bariz nedenlerden dolayı, Access'te yeni bir veritabanı oluşturma işlemini atlıyorum ve sadece yapısını vereceğim. veritabanımızda bulunan tablolar).

1. Birinci masa, buna Önce diyelim (pekala, ben yazar değilim!)

2. Tablo iki, buna zor diyelim - İkinci

Eh, olduğu gibi, üs ile ve bu kadar.

2. Program
2.1. Sunucu uygulaması.

Yeni bir uygulama oluşturalım ve C:\ClientServer\Server klasöründe Server adı altına kaydedelim. Uzak Veri Modülünü deponun Multitier sekmesinden uygulamaya ekleyin (Şekil 1).

RDM eklerken, ekleme sihirbazı bu modülün parametrelerini soracaktır - oraya sunucumuzun adını "Test" gireceğiz.

Gerisini değiştirmeden bırakacağız. "Tamam" butonuna tıkladıktan sonra, projede Test adlı olağan tarih modülüne benzer bir form görünecektir. isimle kaydedelim RDMFrm.pas.

Üzerine ADOConnection bileşenlerini (tek parça), ADOTable ve DataSetProvider'ı (her biri iki parça) koyalım. ADOTable ve DataSetProvider bileşenlerini sırasıyla adotFirst, adotSecond, dspFirst ve dspSecond olarak adlandıralım. ADOConnection bileşenine çift tıklamak, Bağlantı Dizesi sihirbazını getirecektir. "Bağlantı Dizesini Kullan" öğesini seçin ve Oluştur düğmesini tıklayın. Açılan "Veri bağlantısı özellikleri" penceresinde "Microsoft Jet 4.0 OLE DB Sağlayıcı" maddesini seçin ve "İleri" düğmesine basın. "Bağlantı" sekmesinde, veritabanına giden yolu girin, "Bağlantıyı kontrol et" düğmesine basın ve bağlantı kontrolünün tamamlandığını belirten bir mesaj alın. Ardından Tamam düğmesine tıklayarak sihirbazı kapatın. ADOConnection bileşeninin ayrıca False ve Connected to True olarak ayarladığımız bir LoginPrompt özelliği vardır. ADOTable bileşenleri için, açılır listeden seçim yaparak Bağlantı özelliğini ADOConnection olarak ayarlayın. TableName özelliğini sırasıyla First ve Second olarak ayarlayın. CursorType özelliği ctDynamic, TableDirect özelliği ise True. FieldsEditor'u arayın ve tüm alanları buraya ekleyin.

DataSetProvider bileşenleri:

Bu, ilkel bir MIDAS sunucusu oluşturma sürecinin tamamlanmış olarak kabul edilebileceği yerdir. Sunucuyu DCOM alt sistemine kaydettirmek için uygulamayı / regserver - Server.exe / regserver parametresi ile çalıştırmanız gerekir.
Ve son dokunuş, Delphi klasöründe bulunan Borland'dan SocketServer uygulaması mı? /Bin/scktsvr.exe. İstemcinin sunucuyu görebilmesi için scktsvr.exe'yi çalıştırmanız gerekir (eğer Win NT / w2k / XP kuruluysa, bu uygulamayı bir hizmet olarak kaydedebilirsiniz, bunun için scktsvr ile başlatmanız gerekir. exe / kurulum parametresi)

2.2. İstemci uygulaması

Yeni bir uygulama oluşturalım ve Client adı altında C:\ClientServer\Client klasörüne kaydedelim. Ana forma iki ClientDataSet bileşeni yerleştirelim (bunlara cdsFirst, cdsSecond diyelim), DataSource (bunlara dsFirst, dsSecond diyelim), DBGrid (dbgFirst, dbgSecond diyelim) bir SocetConnection bileşeni yerleştirelim.

SocetConnection

Her şeyi doğru yaptıysanız, Connected özelliğini True olarak ayarladığınızda, sunucu uygulaması başlamalıdır.

Müşteri Veri Kümesi

Alan Düzenleyicisini başlatın (bileşene çift tıklayın) ve tüm alanları buraya ekleyin. Bileşenler için Müşteri Veri Kümesi bir işleyici yazalım sdsAfterPost

Ve olay işleme için değiştirin Gönderi Sonrası her iki ClientDataSet.

Veri kaynağı

Mülk Anlam
Veri Kümesisırasıyla cdsFirst ve cdsSecond

DBGrid

Mülk Anlam
Veri kaynağısırasıyla dsFirst ve dsSecond

Sütun Düzenleyiciyi başlatın (bileşene çift tıklayın) ve tüm alanları buraya ekleyin.
Grid'in yanındaki formun üzerine bir buton koyalım ve onu onClick işleyicisine yazalım.

O halde yeni bir veritabanı oluşturalım, adını Test edelim ve C:\ClientServer\Server\Data klasörüne kaydedelim (bariz nedenlerden dolayı, Access'te yeni bir veritabanı oluşturma işlemini atlıyorum ve sadece yapısını vereceğim. veritabanımızda bulunan tablolar).

1. Tablo bir, buna İlk diyelim

2. Tablo iki, buna zor diyelim - İkinci

Eh, olduğu gibi, üs ile ve bu kadar.

programı

2.1. Sunucu uygulaması.

Yeni bir uygulama oluşturalım ve C:\ClientServer\Server klasöründe Server adı altına kaydedelim. Uzak Veri Modülünü deponun Multitier sekmesinden uygulamaya ekleyin (Şekil 1).

Pirinç. 1 Özel Uzak Veri Modülüne sahip Depo.

RDM eklerken, ekleme sihirbazı bu modülün parametrelerini soracaktır - oraya sunucumuzun adını "Test" gireceğiz.


Gerisini değiştirmeden bırakacağız. "Tamam" butonuna tıkladıktan sonra, projede Test adlı olağan tarih modülüne benzer bir form görünecektir. isimle kaydedelim RDMFrm.pas.

Üzerine ADOConnection bileşenlerini (tek parça), ADOTable ve DataSetProvider'ı (her biri iki parça) koyalım. ADOTable ve DataSetProvider bileşenlerini sırasıyla adotFirst, adotSecond, dspFirst ve dspSecond olarak adlandıralım. ADOConnection bileşenine çift tıklamak, Bağlantı Dizesi sihirbazını getirecektir. "Bağlantı Dizesini Kullan" öğesini seçin ve Oluştur düğmesini tıklayın. Açılan "Veri bağlantısı özellikleri" penceresinde "Microsoft Jet 4.0 OLE DB Sağlayıcı" maddesini seçin ve "İleri" düğmesine basın. "Bağlantı" sekmesinde, veritabanına giden yolu girin, "Bağlantıyı kontrol et" düğmesine basın ve bağlantı kontrolünün tamamlandığını belirten bir mesaj alın. Ardından Tamam düğmesine tıklayarak sihirbazı kapatın. ADOConnection bileşeninin ayrıca False ve Connected to True olarak ayarladığımız bir LoginPrompt özelliği vardır. ADOTable bileşenleri için, açılır listeden seçim yaparak Bağlantı özelliğini ADOConnection olarak ayarlayın. TableName özelliğini sırasıyla First ve Second olarak ayarlayın. CursorType özelliği ctDynamic, TableDirect özelliği ise True. FieldsEditor'u arayın ve tüm alanları buraya ekleyin.

DataSetProvider bileşenleri:

Bu, ilkel bir MIDAS sunucusu oluşturma sürecinin tamamlanmış olarak kabul edilebileceği yerdir. Sunucuyu DCOM alt sistemine kaydettirmek için uygulamayı / regserver - Server.exe / regserver parametresi ile çalıştırmanız gerekir.
Ve son dokunuş, Delphi klasöründe bulunan Borland'dan SocketServer uygulaması mı? /Bin/scktsvr.exe. İstemcinin sunucuyu görebilmesi için scktsvr.exe'yi çalıştırmanız gerekir (eğer Win NT / w2k / XP kuruluysa, bu uygulamayı bir hizmet olarak kaydedebilirsiniz, bunun için scktsvr ile başlatmanız gerekir. exe / kurulum parametresi)

2.2. İstemci uygulaması

Yeni bir uygulama oluşturalım ve Client adı altında C:\ClientServer\Client klasörüne kaydedelim. Ana forma iki ClientDataSet bileşeni yerleştirelim (bunlara cdsFirst, cdsSecond diyelim), DataSource (bunlara dsFirst, dsSecond diyelim), DBGrid (dbgFirst, dbgSecond diyelim) bir SocetConnection bileşeni yerleştirelim.

SocetConnection

Her şeyi doğru yaptıysanız, Connected özelliğini True olarak ayarladığınızda, sunucu uygulaması başlamalıdır.

Müşteri Veri Kümesi

Alan Düzenleyicisini başlatın (bileşene çift tıklayın) ve tüm alanları buraya ekleyin. Bileşenler için Müşteri Veri Kümesi bir işleyici yazalım sdsAfterPost

Prosedür TMainForm.cdsAfterPost (DataSet: TDataSet);
başlamak
(TClientDataSet olarak DataSet) ile başlar
eğer o zaman devlet
denemek
Güncellemeleri Uygula (0);
Yenile;
hariç
EDatabaseError.Create ("Hatadan çıkıldı");
son;
son;
son;

Ve olay işleme için değiştirin Gönderi Sonrası her iki ClientDataSet.

Veri kaynağı

Mülk Anlam
Veri Kümesi sırasıyla cdsFirst ve cdsSecond

DBGrid

Mülk Anlam
Veri kaynağı sırasıyla dsFirst ve dsSecond

Sütun Düzenleyiciyi başlatın (bileşene çift tıklayın) ve tüm alanları buraya ekleyin.
Forma düğmeyi Grid'in yanına koyun ve onClick işleyicisine yazın:

  • dbgFirst için - cdsFirst.Post
  • dbgSecond - cdsSecond.Post

Her şey. Delphi'yi kapatıyoruz (deneyin saflığı için). Ve istemci uygulamasını başlatıyoruz. Her şeyi doğru yaptıysanız, bunun gibi bir şey görmelisiniz.


Makale inceleme alırsa ve okuyucuların ilgisini hak ediyorsa, devamı uzun sürmeyecektir.