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_