Mega Code Archive

 
Categories / Delphi / Forum
 

Neoturk - client+socket dosya gönderme örneği

herkese merhaba, Dikkat ettip gönderilen kodları inceledim ama Adam Akıllı Socketler üzerinden Dosya Gönderme kodunu göremedim, bir kaç örnek varsa da bunlar da copy/paste yapıldığı için pek bir açıklama getirilmemiş, ve acemi birisi için de anlaşılmaz bir kod bütünlüğü olduğunu düşündüm... Bu nedenle bunu en basit şekilde anlatacağım sizlere, siz de öğrenin...! Öncelikle Dosya Gönderebileceğiniz Yöntemleri kabaca sayayım sizlere ( kabaca ! ) - tcp socketleri üzerinden dosya gönderimi yapılabilir - nmstrm componentleri üzerinden dosya gönderimi yapılabilir - udp protokolü üzerinden dosya gönderimi yapılabilir Burada sizlere ben tcp socketlerinden çok kısaca bahsedeceğim, önce diğerlerinden bahsedeyim, nmstrm komponentleri bildiğiniz üzere D7'de ve xp ortamında yemiyor.. deneyenler görmüşlerdir. Bu nedenden ötürü de geriye adam akıllı 2 yöntem kalıyor, ya udp ya da tcp ! 1. ya tcp kullanacaksınız 2. ya da udp kullanacksınız başka aklıma birşey gelmiyor.. ( uçuk düşünmeye de gerek yok.. yok ftp yok web vs vs...! ) udp konusu pass geçiyorum! çünkü bu konuda birkaç kod parçacığı gördüm ve gerçekten sinirlendim, çünkü anlatılanla uygulama arasında dağlar kadar fark var.. ve her zaman da yemez! yiyeceği yerler vardır, yemeyeceği yerler vardır.. öyle ulu ortalıkta Remote olarak udp yemez.. biz buna teknik olarak yiyen formasyonlarına "R3x" diyoruz... afedersiniz bazı "öküzler"de bunu windows açığı olarak görüp ileri geri konuşurlar.. bunlara da ne yorum yaparsınız onu da bilemem.... gelelim tcp konusuna, tcp socket üzerinden dosya göndermek en yeterli ve başarılı bir koşuldur! Burada dikkat edilecek husus, gönderilen veri paketlerinin Size'ı(büyüklüğü) ve verinin Yığınlaşıp yığınlaşmadığı! konusudur.. (Hızlıca anlatacam kusuruma bakmayın) verinin yığınlaşması derken şunu anlayın, dosyayı açıp içindeki verileri "paketler" halinde peş-peşe motor gibi teorik gönderebilirsiniz, ama pratikde, cache bellek dolacağı için ( winsock cache bellekden bahsediyorum ) tüm paketler karşı pc ye ulaşmayacaktır. Bunu önlemek için de, ping-pong yöntemini kullanabilirsiniz! ( veriyi aldım-sonraki veriyi gönder ) hızlıca çok basit ve tipik bir server kodunu yazıyorum: {programmed by neoturk} const bufsize=512; //paket büyüklüğü, 256/512/1024/2048.... var Form1: TForm1; fSrc,fDst,len: Integer; size: Longint; buffer: packed array [0..bufsize-1] of byte; implementation {$R *.dfm} procedure TForm1.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket); var dta:string; begin len:=socket.ReceiveBuf(buffer,bufsize); FileWrite(fDst,buffer,len); memo1.lines.add('bufBYTE='+inttostr(len)); //pong iste, sonraki veri için socket.SendText('pong1'+#13#10); end; procedure TForm1.FormCreate(Sender: TObject); begin //dosyayı oluştur fDst := FileCreate('c:\deneme.txt'); end; procedure TForm1.Button1Click(Sender: TObject); begin //programı kapat FileClose(fDst); close; end; end. çok sade ve temiz bir kod, kendim yazdım, bu kodu yazana kadar da göbeğim çatladı desem inanmazsınız.... Burada şunu açıklayayım hemen, formun create kısmında c:\deneme.txt dosyasını oluşturuyorum. Gelen paketler bu dosyaya yazdırılacak! bitti............ gelelim client formuna: const crlf=#13#10; bufsize=512; var Form1: TForm1; sendfilegate1:boolean; kapat:boolean; buffer: packed array [0..bufsize-1] of Byte; stopped:boolean; stepped:integer; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var x:string; size,fsize,bytesent:longint; fsrc,len:integer; begin stepped:=0; if filelistbox1.ItemIndex=-1 then begin memo1.lines.add('dosya seç'); exit; end; x:=directorylistbox1.Directory+'\'+filelistbox1.items[filelistbox1.itemindex]; memo1.lines.add(x); if clientsocket1.Socket.Connected=false then begin memo1.lines.add('bağlantı yok?'); exit; end; fSrc := FileOpen(x,fmOpenRead); fsize := FileSeek(fSrc,0,2); FileSeek(fSrc,0,0);//başa konumlan gauge1.MaxValue:=fsize; memo1.lines.add(inttostr(fsize)+' byte...'); memo1.lines.add('dosya göndeirliyor...'); sendfilegate1:=true; bytesent:=0; size:=fsize; stopped:=false; while size>0 do begin if kapat then break; application.ProcessMessages; if (sendfilegate1) and (stopped=false) then//ping-pong begin len := FileRead(fSrc,buffer,sizeof(buffer)); memo1.lines.add(inttostr(len)); clientsocket1.Socket.SendBuf(buffer,len); gauge1.Progress:=bytesent; bytesent:=bytesent+len; size:=size-len; sendfilegate1:=false;//pong iste end; end; fileclose(fsrc); memo1.lines.add('upload ok'); gauge1.Progress:=0; end; procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket); var dta:string; begin dta:=trim(socket.receivetext); inc(stepped); form1.Caption:=dta+'/'+inttostr(length(dta))+'='+inttostr(stepped); if dta='pong1' then sendfilegate1:=true; end; end. kodu inceleyin... gerekli nesneleri formlara dizayn edin... Anlatılacak daha epey bir şey var, ama bunu burada yapmanın gereği yok.. olayı teorik olarak inceleyin ve neyin nasıl olduğunu kavrayın.. bunu ben daha da geliştirdim ve şu anda da RealLife olarak kullanıyorum ve xp ortamı olsun w9x olsun, adsl olsun, modem olsun ne olursa olsun paşa paşa çalışıyor... Çalışmıyo diyemezsiniz, deneyiminiz varsa epey birşey kapıyor olmalısınız.. çalışmalarınızda başarılar, saygılarımla_ xxnt03@lycos.co.uk neoturk_