![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
передать файлы через сеть
проходивший мимо © (2007-03-29 21:35:00)интересует с помощью чего и как лучше передавать большие файлы через сеть?
пробовал ServerSocket&ClientSocket, но при передачи фильма или музыки конечный файл оказывался совершенно не читаемым.
делал так:
на сервере:
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
ms: TMemoryStream;
begin
if Socket.ReceiveText = 'send' then//если пришла команда на отправку, то
begin
ms:= TMemoryStream.Create;
try
ms.LoadFromFile(in_file);//загружаем файл в память
ms.Position:= 0;
Socket.SendText(IntToStr(ms.Size) + #0); //пеердаём размер файла и отделяем его символом #0
Socket.SendStream(ms); //отправляем
except
ms.Free; //очищаем
end;
end;
end;
на клиенте:
procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var
s, sl,ss: string;
begin
s:= Socket.ReceiveText;
//если не в режиме приёма
if not Reciving then
begin
SetLength(sl, StrLen(PChar(s))+1); //получаем длину файла
StrLCopy(@sl[1], PChar(s), Length(sl)-1);
DataSize:= StrToInt(sl);
Data:= TMemoryStream.Create;
Delete(s, 1, Length(sl));//удаляем размер файла
Reciving:= true;
//это чтоб знать сколько данный поступило
(* ss:=IntToStr(Data.Position)+' / '+IntToStr(DataSize)+' .';
Label3.Caption:=ss;
Gauge1.MaxValue:=DataSize;*)
end;
Application.ProcessMessages;
//сохраняем данные в файл, пока не получим всё
try
//это чтоб знать сколько данный поступило
(* ss:=IntToStr(Data.Position)+' / '+IntToStr(DataSize)+' .';
Label3.Caption:=ss;
Gauge1.Progress:=Data.Position;*)
Data.Write(s[1], length(s));
if Data.Size = DataSize then
begin
Data.Position:= 0;
Data.SaveToFile(out_file);//сохраняем в указанный файл
Data.Free;
Reciving:= false;
Socket.Close;
end;
except
Data.Free;
end;
end;
может что-то не так делаю... или может лучше передавать с помощью чего-то другого?
проходивший мимо (2007-03-31 16:14:00) [1]абалдеть. ещё раз спасибо. скорость раз в 50 увеличилась!
проходивший мимо (2007-03-31 15:02:00) [2]Сергей М., спасибо большое.
вроде работает, щас проверять на передачу фильмлв буду
Ketmar (2007-03-30 13:21:00) [3]c помощью 3" floppy.
Сергей М. (2007-03-30 12:35:00) [4]сервер:
var
fs: TFileStream;
fsize: Int64;
..
fs:= TFileStream.Create(in_file, fmRead);
try
fsize := fs.Size;
Socket.SendBuf(fsize, SizeOf(fsize));
Socket.SendStream(fs);
except
fs.Free;
raise;
end;
клиент:
type
TRcvState = (rsRcvFileSize, rsRcvFileData);
var
BytesNeed: Int64 = SizeOf(TInt64);
RcvState: TRcvState = rsRcvFileSize;
buf: array[0..4095] of Byte;
fs: TFileStream;
..
procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
BytesRead: Integer;
begin
case RcvState of
rsRcvFileSize:
begin
BytesRead := Socket.ReceiveBuf(buf[BytesNeed - SizeOf(Int64)], BytesNeed);
if BytesRead = 0 then Exit;
Dec(BytesNeed, BytesRead);
if BytesNeed > 0 then Exit;
BytesNeed := PInt64(@buf)^;
RcvState := rsRcvFileData;
end;
rsRcvFileData:
begin
BytesRead := Socket.ReceiveBuf(buf, Min(BytesNeed, SizeOf(Buf));
if BytesRead = 0 then Exit;
Dec(BytesNeed, BytesRead);
if not Assigned(fs) then
fs:= TFileStream.Create(out_file, fmCreate);
try
fs.WriteBuffer(buf, BytesRead);
except
FreeAndNil(fs);
raise;
end;
if BytesNeed > 0 then Exit;
FreeAndNil(fs);
BytesNeed := SizeOf(Int64);
RcvState := rsRcvFileSize;
end;
end;
end;
проходивший мимо (2007-03-30 11:14:00) [5]не получется.
тогда вот это условие никогда верным не бывает (я кучу раз проверил, никогда переданный файл не сохранялся.)
if Data.Size = DataSize then
begin
...
end.
Сергей М. (2007-03-30 08:19:00) [6]Delete(s, 1, Length(sl) + 1);//удаляем размер файла