Передача файлов по сети

Shouldercannon

Well-Known Member
25.05.2010
128
0
29
Пенза
#1
Доброго времени суток!
Сделал передачу файлов через Socket и столкнулся с проблемами.
Код:
unit frm_ReceivingFile;
procedure TFormReceivingFile.FormCreate(Sender: TObject);
begin
ProcReceivingFile('Test', 'test.txt', ExtractFilePath(Application.ExeName) + 'Downloads'); //!//
ClientSocket1.Open; // Открываем сокет
BReceive := False; // Режим клиента - приём команд
end;
procedure TFormReceivingFile.ProcReceivingFile(Nick, sFile, sFolder: String);
begin
LUser.Caption := Nick;
LFile.Caption := ExtractFileName(sFile);
ReceptionFolder := sFolder;
end;
procedure TFormReceivingFile.ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
begin
LStatus.Caption := 'Приём...';
end;
procedure TFormReceivingFile.ClientSocket1Disconnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
LStatus.Caption := 'Нет соединения';
end;
procedure TFormReceivingFile.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var
s: AnsiString; // Принятый текст
begin
s := Socket.ReceiveText;
// Если клиент в режиме приёма файла, то...
if BReceive then Writing(s) // Записываем данные в буфер
else // Если клиент не в режиме приёма файла, то...
if Copy(s, 1, Pos('<||>', String(s)) - 1) = '10' then // Если это команда принятия файла "10", то...
begin
MS := TMemoryStream.Create; // Создаём буфер для файла
// Определяем имя файла
Delete(s, 1, Pos('<||>', String(s)) + 3);
sName := String(Copy(s, 1, Pos('<||>', String(s)) - 1));
// Определяем размер файла
Delete(s, 1, Pos('<||>', String(s)) + 3);
Size := StrToInt(String(Copy(s, 1, Pos('<||>', String(s)) - 1))); // Определяем размер файла
Delete(s, 1, Pos('<||>', String(s)) + 3); // Удаляем последний разделитель
BReceive := True; // Переводим сервер в режим приёма файла
Writing(s); // Записываем данные в буфер
end;
end;
procedure TFormReceivingFile.Writing(s: AnsiString);
begin
// Если принято байт меньше размера файла, то...
if MS.Size < Size then MS.Write(s[1], Length(s)); // Записываем в буфер
// Выводим прогресс закачки файла
ProgressBar1.Position := MS.Size * 100 div Size;
LReceived.Caption := Format('%s / %s', [GetNormalSize(MS.Size), GetNormalSize(Size)]);
// Если файл принят, то...
if MS.Size = Size then
begin
BReceive := False; // Переводим клиента в нормальный режим
MS.Position := 0; // Переводим каретку в начало буфера
MS.SaveToFile(Format('%s\%s', [ReceptionFolder, ExtractFileName(sName)])); // Сохраняем файл
ClientSocket1.Socket.SendText('11'); // Посылаем команду "11", то есть файл принят
FreeAndNil(MS); // Убиваем буфер
LStatus.Caption := 'Файл принят';
end;
end;
ProgressBar работает нормально, а в LStatus количество переданных байт выводится только после получения файла
Код:
unit frm_FileTransfer;
procedure TFormFileTransfer.FormCreate(Sender: TObject);
begin
ServerSocket1.Open; // Открываем сокет
end;
procedure TFormFileTransfer.FormDestroy(Sender: TObject);
begin
ServerSocket1.Close; // Закрываем сокет
end;
procedure TFormFileTransfer.ProcFileTransfer(Nick, sFile: String);
var
Size: Integer;
P: ^Byte;
begin
LUser.Caption := Nick;
LFile.Caption := ExtractFileName(sFile);
Self.Show;
MS := TMemoryStream.Create; // Создаём буфер для файла
MS.LoadFromFile(sFile); // Загружаем файл в буфер
ServerSocket1.Socket.Connections[0].SendText(AnsiString('10<||>' + sFile + '<||>' + IntToStr(MS.Size) + '<||>')); // Посылаем информацию о файле (файл и размер)
MS.Position := 0; // Переводим каретку в начало файла
P := MS.Memory; // Загружаем в переменную "P" файл
Size := ServerSocket1.Socket.Connections[0].SendBuf(P^, MS.Size); // Посылаем файл
// Выводим прогресс
ProgressBar1.Position := Size * 100 div MS.Size;
LReceived.Caption := Format('%s / %s', [GetNormalSize(Size), GetNormalSize(MS.Size)]);
end;
procedure TFormFileTransfer.ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
LStatus.Caption := 'Передача...';
end;
procedure TFormFileTransfer.ServerSocket1ClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
LStatus.Caption := 'Нет соединения';
end;
procedure TFormFileTransfer.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
begin
// Если клиент принял файл, то...
if Socket.ReceiveText = '11' then
begin
LStatus.Caption := 'Файл отправлен';
FreeAndNil(MS); // Убиваем буфер
end;
end;
PrograssBar стоит на месте, а в LStatus количество переданных байт сразу на максимуме (10 Кб / 10 Кб)