PDA

Tam Sürümünü Görmek İçin : ağ üzerinde server - client ile ms access vt ye erişmek


DotNetKid
17/05/2006, 09:13
http://www.yazgelistir.com/Makaleler/MakaleDetay.aspx?MakaleId=1000000547

yukarıdaki makalede yapıldıgı gibi bir server - client uygulaması yaptım. verileri byte olarak server exe ye gönderebiliyorum. daha sonraki aşamam, Makine A daki veriyi Makine B deki mdb veritabanına kayıt etmek idi. Makine A daki Client.exe de yazılan veriyi Makine B deki Server.exe ile access veritabanına kayıtı da yaptım.

sıra geldi, client tan mdb deki verileri cekmeye. bunun için aklıma bi kaç mantık geliyor ama daha iyi bir yol olabilir. bi kaç kriterim var verileri alırken;

- veriler herhangi bir anda güncellenebilir,
- bu yuzden Client.exe, verileri belli aralılarda (30 sn.de bir) güncellemeli,
- sanırım bunun için de, server.exe 30 sn.de bir güncellenmeli, sonucta verilere asıl ulaşan o.
- gelen veri, bikaç tablunun ilişkilendirilmiş hali olan bir tablo. bu verileri, server.exe de bir cok boyutlu diziye mi aktarmalıyım.
Öyle ise; bir dizi ile gelen verileri byte byte Client.exe ye gönderebilir miyiz. aslında ben sorularımı uzatmayım. konu da uzamasın. bildiğiniz bir mantık varsa, yardım bekliyorum.

(bir de son olarak, Server.exe Client.exe den cvp beklediği için, malumunuz, TcpListen ile işlem görüyor. yani Dinleyici durumunda.. Peki; Server.exe sorgulamayı yapıp verileri Client.exe ye geri göndereceği için, Client.exeye de bir Dinleme Fonksiyonu yazılmalı değil mi? Yoksa bu Server-Client uygulamaları baska bir mantıkla mı icra görüyor...)

Tşk.ler, kolay gelsin...


cemaliozan
17/05/2006, 21:52
Aslında Client-Server mimariye dayalı uygulama geliştirme düzeni biçim değiştirdi. Yinede hala kendine özgü protokol sistemi kullanarak bu işi yapmaya çalışan birilerini görmek güzel. Eğer bunu eğitim amaçlı yapacaksan devam et. Ama profesyonel bir çalışma ise uğraştığın şey bence ADO .NET FRAME WORK gibi daha gelişkin ve basit yöntemlerle çalışmayı dene.

Gerçek client - server mimari üzerinde veri alış verişi her zaman delta diye adlandırılan bir tampon bölgede tutlur. Client server mimaride en büyük sorun güncelleme çakışmalarını yönetirken ortaya çıkar. Yani iki kullanıcı aynı kayıt satırı üzerinde güncelleme yapmaya kalktığında sorun çıkar. Biz bu tür problemleri eski programlama dillerinde kayıda kilit atarak, daha sonra kayda kilit atmayı deneyen kullanıcıyıda haberdar ederek çözüyorduk. Mümkün olduğunca üzerinde çalışılacak kayıt dizisini sınırlandırıyor, yetki çerçeveleri içinde işlemler yaptırıyorduk.

Senin sorundan anladığım kadarıyla sen aynı veya farklı networklerde çalışan makinalar arasında veri-alış verişi yaptırmak istiyorsun. Bunun içinde TCP/IP protokolleri ile birlikte kendi özgün protokollerini kullanmak istiyorsun. Eğer durum böyleyse tam olarak bir client-server durumundan söz edilebileceğini sanmıyorum. Bu durumda kullandığın dile bağlı olarak yapman gereken kendine özgü istemci ve sunucu için protokoller geliştirmek olacaktır.

Bu protokollerde daha çok şunları ön plana çıkaracaksın ;

Talepçi - istemci
Talep edilen - komut seti
Talep edilen sunucu
Talebin karşılığı- veri
Talebin karşılığının geri gönderileceği istemci
Aslında kodları paylaşabilirsen farklı açılımlarlada konuyu inceleyebiliriz.
Delphi ile buna benzer bir çalışmayı inceleyebilirsin.
http://forum.ceviz.net/showthread.php?t=27309

acemi
17/05/2006, 22:27
Yerel agda calisacak gercek bir uygulamamı bu? Eger oyleyse, cok daha basit yollar var.

DotNetKid
18/05/2006, 09:05
@cemaliozan: cok tşk ederim. emek vermişsin. yazdılarında haklısın. ben düşündüğün gibi bir sistem yazmayı düşünüyordum. dün buna mecburdum. cünkü senin ve @acemi nin bahsettiği daha basit yöntemlerden haberim yoktu. fakat buraya msj yazdıktan sonra daha farklı yontemler oldugunu ogrendim ama sadece bu kadar.

frameWork altında bu işi goren class lar varmış. baska bir bilgim yok. bu bir proje olacak ama geniş çaplı değil. @acemi: yerel ağda çalışacak gerçek bir uygulamadan kastettiğin şeyi anlayamadım. evet yerel agda çalışacak. ve ben fazla zamanım ve bilgim olmadıgı için frameWork ün kendi class larını kullanmak istiyorum. projeyi kısaca çizeyim:

- bir kaç makine A makinesinde bulunan bir ms access vt ye erişecek:
- işlemler: yeni kayıtlar girme, kayıt silme, güncelleme ve görüntüleme işlemleri var.
- B ve C makineleri ise girilen kayıtları listeleyecek. ama her 30 sn de bir ( veya bir kaç dk. ) form yenilenecek. (A daki verilerin güncellenme ihtimaline karşın)

bir arkadaş da client-server da veri iletişimini xml ile de yapabilirsin dedi. veya pointerlarla. bir de dediğim gibi frameWork un kendi hazır sınıfları ile. sizce ne yapmalıyım..

- en profesyonel yaklaşım ?
- en hızlı ve güvenli yaklaşım ?
- en kolay yaklaşım ?

ilgileriniz için tşk ederim arkadaşlar...

cemaliozan
18/05/2006, 09:22
önce acemi usta cevap versin, hem üstattan isitfade edelim hem ben biraz düşüneyim. :)

DotNetKid
18/05/2006, 10:10
... :p ..

acemi
18/05/2006, 12:27
Kodları, .mdb dosya, programın çalıştığı makinedeymiş gibi yazacaksın. Yani, ağ kısmını hiç düşüneyeceksin, herşey tek bir makinede bitiyor gibi...

Sunucu makineye, asıl .mdb dosyayı koyacaksın. Diğer makinelere, aslında içinde veri olmayan, sadece ana makinedeki .mdb dosyanın tablolarına linkler olan bir .mdb koyacaksın.

server-client iliskisini MS Access halledecek, sen o konuyla ilgili hicbir şey yapmayacaksın.

cemaliozan
18/05/2006, 13:39
İşte ustayla aramızdaki fark bu. Ben yıllardır ağ uygulamaları yazarım, daha access'in marifetlerinden bilem haberim yok. İşin yoksa uğraş dur ADO'ydu cidoydu. Sen acemi ustanın tarifini yap, bizede öğret olmazsa ben başka bir CORBA tarifi vereyim. :)

Kolay gelsin.

DotNetKid
18/05/2006, 13:44
" mdb dosyanın tablolarına linkler olan bir .mdb "

bu ne demek.. link ten kastın C# da vt yolunu belirttiğim kodlar mı

yani " C:\\.. " değil de, @"\\SERVER\C\.. " gibi mi. eğer oyle ise, mdb nin bulundugu klasöre paylaşım vermeden bağlantıyı sağlamıyor..

cemaliozan
18/05/2006, 13:58
hemen ustaya bende bir soru sorayım ;

Güncelleme çakışmalarınıda Access otomatik hallediyor mu?

acemi
18/05/2006, 14:08
bu ne demek.. link ten kastın C# da vt yolunu belirttiğim kodlar mı

Olayın o kısmının C# ile ilgisi yok, Access icinde biten bir olay.

* İstemci makinede bos bir Access dosyası oluştur.
* MS Access ile bu dosyayı aç
* tablolar kısmında bos alana mouse sag tuş ile tıkla
* açılan menude bagla/link (veya benzeri... tam kelimeyi hatırlamıyorum. Al degil ama...) gibi bir seçenek olacak, onu sec
* Baglanacak tablolari nerede bulacağını soran birşey çıkacak. Ağ üzerinden, sunucudaki .mdb dosyayı bul ve butun tablolarini sec


Guncelleme çakışmalarını, kayıt kilitlemelerini filan Access halledecek. (bana usta deyip durma, yazdıklarımdan sonra +1 filan yazma)

cemaliozan
18/05/2006, 14:42
(bana usta deyip durma, yazdıklarımdan sonra +1 filan yazma)
*usta = üstat

DotNetKid
18/05/2006, 16:06
hehe ona da kızar, @acemi biraz terstir..

DotNetKid
18/05/2006, 16:07
yahu arkadaşlar. tşk ederim ilgi için. ama bunu ben yine de client-server ile yapsam. @cemaliozan hani seni su bahsettigin kolay yontemlerle filan. ms access @aceminin dediği şeyi yapıyor, ama ben pek güvenemedim. ne dersiniz..

DotNetKid
18/05/2006, 16:08
bir de; accessten diğer makinede ki access dosyasına link ile eriştik ama sanırım diğer makinedeki access dosyası paylaşımı acık olmayan bir dizinde olursa çalışmaz (?!)

cemaliozan
18/05/2006, 16:16
ms access @aceminin dediği şeyi yapıyor, ama ben pek güvenemedim. ne dersiniz..

valla ben bunada kızar diye yorum yapamıyorum artıkın. Bende bizim bankanın veri tabanı tasarımı için yardım istediydim yine kızdığındanmıdır yoksa iş yoğunluğundanmı henüz cevap alamadım, bekliyorum.

cemaliozan
18/05/2006, 16:56
@Dotnetkid : Çok özür dilerim ama verdiğin bu bağlantıyı daha yeni farkediyorum
http://www.yazgelistir.com/Makaleler...eId=1000000547 (http://www.yazgelistir.com/Makaleler/MakaleDetay.aspx?MakaleId=1000000547) :)

TCP/IP ve soket programlama konusu derin bir konu. Kısaca soket programcılığı ile bahsettiğin biçimde projeyi gerçekleştirmenin maliyeti yazılımsal olarak oldukça yüksek olacaktır. Öncelikle bu yüksek maliyeti (ekonomik anlamda değil) göz önüne alıp soketler üzerinden veri alış verişi yapmakta kararlıysan önce C# ile soket programcılığı konularını bu makalede anlatılandan daha fazla araştırmanı tavsiye ederim.

C# ile soket programcılığında sana yapabileceğim kodsal katkımdan çok, mantıksal yaklaşım konusunda olabilir. Çünki her ne kadar askerliğimizi birlikte yapsakta C#'a o kadar aşina değilim.

Soket programcılığında en temel konuyu zaten yapmışsın anladığım kadarıyla. Bir client-server uygulama arasında özgün bir protkol tanımı yaptın mı? Örneğin delphicesini göstereyim :

Aşağıda istemci tarafının durumu ve talep karşılıklarıyla ilgili bir tanımlama var. Bu tanımlamalar gerek yerel gerekse uzak bilgisayar arasında yapılan işleri özetlemek için kullanılıyor.

{ TCliStatus = csIdle : Dinlemede
csCONN : Bağlantı Kuruldu
csDRVL : Sürücü Listesi
csFOLD : Klasör Listesi
csList : Dosya Listesi
csCDRV : Sürücü Değiştirildi
csCDIR : Klasör Değiştirildi
csEmpt : Klasörde dosya yok
csBitmap : Bitmap Resim
csDesk : Masa üstü görünütüsü
csFCPY : Dosya kopyalama
csSCFN : Dosya Gönderme
csSize : Dosya/klasör boyu
csText : Text dosyası
csSTATU : Statü Mesajları...
csPath : Sunucu üzerinde geçerli path
csCOMM : Masa üstünde tıklama olayları
csTest : Test Ediliyor
csEnum : Açık uygulamalrın listesi, Text olarak gönderiliyor.
csChat : Chat
csError : Hata Mesajı;}

TCliStatus = (csIdle, csCONN,csDRVL,csFOLD,csList, csCDRV, csCDIR,csEmpt,
csBitmap, csDesk,csFCPY,csSCFN,csSize, csStatu,csPath, csText,csCommand ,
csEnum,csChat,csTest,csError);



İstemci sunucu tarafına bir talep gönderdiğinde örneğin ;

//Klösörü değiştirdik, geçerli klasör bilgilerini istiyoruz
procedure TForm1.ListBox1DblClick(Sender: TObject);
Var S:String;
i:Integer;
begin
S:=ListBox1.Items[ListBox1.ItemIndex];
FCurDir := S;
ClientSocket1.Socket.SendText('CDIR!'+S);
AddMemoMsg('Klasör değişikliği gönderildi.',0);
end;

istemcinin soket nesnesi talebi alıp uygun cevabı geri döndürüyor.


procedure TForm1.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
D,strIn,strCommand, strFile, strFeedback: string;
B : Boolean;
CompList,FeedBackList : TStringList;
FStream : TFileStream;
X,Y,i,nReceived : Integer;
begin
try
FeedBackList := TStringList.Create;
try
// read from the client
strCommand := Socket.ReceiveText;
lbLog.Items.Add ('Client: ' + Socket.RemoteAddress + ': ' +
strCommand);
// extract the file name (tüm komutlar 5 karakterden oluşuyor)
strFile := Copy (strCommand, 6, Length (strCommand) - 5);

//Klasörü Değiştir
if Pos('CDIR!',strCommand) = 1 then
Begin
D:=Copy(strCommand,6,Length(strCommand));
if DirectoryExists(D) Then
DirectoryListBox1.Directory := D
else
if DirectoryListBox1.ItemIndex>0 Then
DirectoryListBox1.ItemIndex := DirectoryListBox1.ItemIndex -1 ;

DirectoryListBox1.OpenCurrent;
Socket.SendText('FOLD!');
Socket.SendText(DirectoryListBox1.Items.Text);
Exit;
End;
end;

Şekilde gördüğün gibi istemci ve kullanıcı arasındaki komut trafiği benim tanımladığım 5 karakterlik komut seti ifadelerle belirtiliyor.

İstemci talep gönderiyor (CDIR)
Sunucu talebi read ile dinlerken alıyor ve gerekeni yapıyor - Socket.SendText(DirectoryListBox1.Items.Text);Bunu veri tabanına uyarlamak içinde aynı mekanizmayı kullanacaksın. İstemci ve sunucu soketlerin Read ve Send yöntemlerini kullanacaksın.

Yapacağın iş için bence bu kadar karışık bir işe gerek yok. C#'a hakimsen bunu win32 platformu veya .NET veya web tabanlı çok daha kolay yapabilirsin. Kullanacağın bağlantı ve veri bilinçli bileşenler zaten yerleşik kütüphanelerde tanımlı. Senin yapacağın bir kaç basit ayar.

Kolay gelsin.

Revne
18/05/2006, 23:40
evet asıl access (mdb) dosyan server olarak kulladigin bilgisayarda paylasıma acık olmalı...

DotNetKid
19/05/2006, 13:51
bahsettiğim proje zate suan web tabanlı calışıyor. asp ile. ama IIS üzerine calışmak istemedigim icin bunu kullanmak istemiyorum. IIS arasıra sorun cıkarabiliyor. hem ayrıca madem programcı isek, neden gercel bir yazılım geliştirmeyelim değil mi. şimdilik cok tşk ederim. kolay gelsin ugrayacağım ;)

cemaliozan
19/05/2006, 14:55
Hocam bir yanlış anlaşılma var sanırım. Web tabanlı (betik dili önemli değil) yapılmasından yanayım demedim. Soket programcılığı kasar, şart oğlu şart değilde ADO vb. tabanlı bir yapıyla uygulama yazmanızı önerdim.

Kasıp kasmamak size kalmış. Kolay gelsin.

DotNetKid
21/05/2006, 17:13
bir arkadaş; byte byte veri okutmak hatalara neden olabilir. hem de cok kasmış olursun, c# ta ve diğer bir çok platform da bu iş için özel sınıflar var demişti. winND mi ne tam olarak hatırlamıyorum.

işin garip tarafı client-server uygulama ile ilgili netteki makalelere baktıgımda hep bu vb. yontemler kullanılmış. (byte byte şeklinde..) eğer bildiğiniz yerler varsa alabilirim.

codeproject vs.. gibi yerlere az cok baktım..