Strumienie i wysyalnie pliku

0

Witam :) za programowanie zabralem sie niedawno

Mam taki problem, che wysylac plik,zalozmy ze to jest jakas bitmapka,uzywajac Tstream (do odczytu) i TServerSocket, TserverClient

Staralem sie przeslac plik bit po bicie uzywajc BlockWrite BlockREad,ale program sie wysypywal:|

Napisal sam cos takiego,ale to nie jest nadal to czego potrzebuje.Owszem wszystlo ladnie pieknie,ale ostatni pakiet jest pusty! lub niepelny!

var
  plik : Tfilestream;
  Buffer : array [1..1024] of char;  
  petle:real;
  petle2:integer;
begin
plik :=TFileStream.Create('1.bmp',fmOpenRead);
rozmiar:=plik.size;

Petle:=plik.Size div 1024;
petle2:=round(petle);

for petle2:=1 to petle2 do begin
plik.readBuffer(buffer,sizeof(buffer));
serwer.Socket.Connections[0].SendBuf(buffer,sizeof(buffeR));
end;
plik.Free;

Pliczek leci ladnie,client zapisuje, ostatni pakiet niepelny zostal przeslany i zawsze wiadac CZARNĄ LINIE.

Jak mam inaczej napisac ten serwer? jakis przykladzik ? pomoc?

// zamiast Petle:=plik.Size div 1024; daj Petle:=(plik.Size-1) div 1024 + 1; poza tym nie używaj sizeof przy sendbuf, bo w ten sposób zawsze wyślesz wielokrotność 1024 bajtów - Ł

0

nie bardzo działa,niedopracowane i czesto wysypuje to błedy :|

0

Być może to Ci pomoże:

http://vegat.idohost.com/module.php?name=nvread&f=3&id=33

żródło: http://vegat.idohost.com/module.php?name=nvread&f=3

Sam jestem ciekaw. Jak ci wyjdzie to napisz ;)

0

Właściwie to nie ma się co dziwić że nie chce przesyłać całego, bo za mało pętli jest robionych. Jeśli masz plik o rozmiarze np. 1000 kb i chcesz wysyłać go w 101 kb częściach to jeśli napiszesz Petle:=1000 div 101 to wyśle tylko 9 części czyli 909 kb. Czyli 91 kb jest nie wysłanych. Następna twoja linia nie jest w ogóle potrzebna (petle2:=round(petle)) bo div zaokrągla. Ja na twoim miejscu napisałbym sobie prostą funkcję liczącą ile pętli trzeba zrobić np.

function ilepetli(rozmiar:int64):integer;
var
temp:int64;
begin
 temp:=rozmiar div 101; //zamiast 101 piszesz oczywiście rozmiar na jaki chcesz dzielić plik
 if temp * 101 < rozmiar then  //tutaj tak samo
 inc(temp);
 result:=temp;
end;

A później tylko instrukcją warunkową sprawdzałbym czy nie jest wykonywana ostatnia pętla i zmienił bym tylko wielkość wysyłanej części pliku na tą która została.

0
Petle:=plik.Size div 1024;
petle2:=round(petle);
for petle2:=1 to petle2 do 

te dwa fragmenty sa glupie (wybacz szczerosc)

  1. jezeli dzielisz uzywajac div to wynik jest typu integer a nie real wiec nie ma powodu pozniej go zaokraglac

  2. rozumiem ze miales na mysli

for petle:=1 to petle2

ale w tym wypadku po co petle i petle2 przyjmuja ta sama wartosc</delphi>

Sugeruje Ci odczytywac z pliku uzywajac petli while np:

while plik.Position<plik.Size do
begin
   Application.ProcessMessages;
   petle:=FSt.Read(Buf,SizeOf(Buf));
   sleep(10);
   ServerSocket1.Socket.Connections[x].SendBuf(Buf,petle);
end;

to powinno dzialac</delphi>

1 użytkowników online, w tym zalogowanych: 0, gości: 1