C
cb1997
Unregistered / Unconfirmed
GUEST, unregistred user!
//服务器端
unit uServer;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, IdTCPConnection, IdTCPClient, IdBaseComponent,
IdComponent, IdTCPServer, ComCtrls;
type
TDataState = (dstNone, dstReceiving);
//Data对象用来保存一个连接的状态以及一些变量
TThreadData = class
private
FState: TDataState;
FFileSize: Integer;
FStream: TFileStream;
procedure SetState(const Value: TDataState);
procedure SetFileSize(const Value: Integer);
procedure SetStream(const Value: TFileStream);
public
constructor Create;
destructor Destroy; override;
property State : TDataState read FState write SetState;
property FileSize : Integer read FFileSize write SetFileSize;
property Stream : TFileStream read FStream write SetStream;
end;
TfmServer = class(TForm)
IdTCPServer1: TIdTCPServer;
SaveDialog1: TSaveDialog;
ProgressBar1: TProgressBar;
procedure IdTCPServer1Execute(AThread: TIdPeerThread);
procedure IdTCPServer1Connect(AThread: TIdPeerThread);
procedure IdTCPServer1Disconnect(AThread: TIdPeerThread);
private
public
{ Public declarations }
end;
var
fmServer: TfmServer;
implementation
{$R *.dfm}
procedure TfmServer.IdTCPServer1Execute(AThread: TIdPeerThread);
var
aFileSize : Integer;
aFileName : String;
Buff : array[0..1023] of Byte;
ReadCount : Integer;
begin
with AThread.Data as TThreadData do
begin
if State = dstNone then
begin
if not AThread.Terminated and AThread.Connection.Connected then
begin
//读取文件名
[red]aFileName := AThread.Connection.ReadLn(#13#10, 100);[/red]
if aFileName = '' then
Exit;
SaveDialog1.FileName := aFileName;
if SaveDialog1.Execute then
begin
//返回确认文件传输标志
AThread.Connection.WriteLn;
//开始读取文件长度,创建文件
AThread.Connection.ReadBuffer(aFileSize, 4);
FileSize := aFileSize;
ProgressBar1.Max := FileSize;
Stream := TFileStream.Create(SaveDialog1.FileName, fmCreate);
State := dstReceiving;
end
else
AThread.Connection.Disconnect
end;
end else begin
if not AThread.Terminated and AThread.Connection.Connected then
begin
//读取文件流
repeat
if FileSize - Stream.Size > SizeOf(Buff) then
ReadCount := SizeOf(Buff)
else
ReadCount := FileSize - Stream.Size;
AThread.Connection.ReadBuffer(Buff, ReadCount);
Stream.WriteBuffer(Buff, ReadCount);
ProgressBar1.Position := Stream.Size;
Caption := IntToStr(Stream.Size) + '/' + IntToStr(FileSize);
Application.ProcessMessages;
until Stream.Size >= FileSize;
AThread.Connection.WriteLn('OK');
Stream.Free;
Stream := nil;
State := dstNone;
end;
end;
end;
end;
{ TThreadData }
[red][black]constructor TThreadData.Create;
begin
inherited;
Stream := nil;
end;[/black][/red][black][/black]
[red]destructor TThreadData.Destroy;
begin
if Assigned(Stream) then
Stream.Free;
inherited;
end;
procedure TThreadData.SetFileSize(const Value: Integer);
begin
FFileSize := Value;
end;
procedure TThreadData.SetState(const Value: TDataState);
begin
FState := Value;
end;[/red]
procedure TfmServer.IdTCPServer1Connect(AThread: TIdPeerThread);
begin
AThread.Data := TThreadData.Create;
with AThread.Data as TThreadData do
begin
State := dstNone;
end;
end;
procedure TfmServer.IdTCPServer1Disconnect(AThread: TIdPeerThread);
begin
//(AThread.Data as TThreadData).Free;
end;
procedure TThreadData.SetStream(const Value: TFileStream);
begin
FStream := Value;
end;
end.
//客户端
unit uClient;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, IdTCPConnection, IdTCPClient, IdBaseComponent,
IdComponent, IdTCPServer, ComCtrls, IdAntiFreezeBase, IdAntiFreeze;
type
TfmClient = class;
TfmClient = class(TForm)
IdTCPClient1: TIdTCPClient;
Button1: TButton;
OpenDialog1: TOpenDialog;
ProgressBar1: TProgressBar;
IdAntiFreeze1: TIdAntiFreeze;
Label1: TLabel;
Edit1: TEdit;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
public
{ Public declarations }
end;
var
fmClient: TfmClient;
implementation
{$R *.dfm}
{ TThreadData }
procedure TfmClient.Button1Click(Sender: TObject);
var
Buf : array[0..1023] of Byte;
ReadCount : Integer;
aStream : TFileStream;
aSize : Integer;
aFileName : String;
begin
if OpenDialog1.Execute then
begin
IdTCPClient1.Connect;
aStream := TFileStream.Create(OpenDialog1.FileName, fmOpenRead or fmShareDenyWrite);
try
//发送文件名
aFileName := ExtractFileName(OpenDialog1.FileName);
IdTCPClient1.WriteLn(aFileName);
//等待接受确认
IdTCPClient1.ReadLn(#13#10, 1000);
//写文件长度和文件流
aSize := aStream.Size;
ProgressBar1.Max := aSize;
[red]IdTCPClient1.WriteBuffer(aSize, 4);[/red] //IdTCPClient1.WriteStream(aStream);[black][/black]
[red][black]while aStream.Position < aStream.Size do
begin
[red] [black] if aStream.Size - aStream.Position >= SizeOf(Buf) then
ReadCount := sizeOf(Buf)
else
ReadCount := aStream.Size - aStream.Position;
aStream.ReadBuffer(Buf, ReadCount);
IdTCPClient1.WriteBuffer(Buf, ReadCount);
ProgressBar1.Position := aStream.Position;[/black][/red][/black][/red]
Application.ProcessMessages;
end;
Caption := IdTCPClient1.ReadLn;
IdTCPClient1.Disconnect;
finally
aStream.Free;
showmessage('传输完毕');
end;
end;
end;
{ TMyThread }
procedure TfmClient.Button2Click(Sender: TObject);
begin
IdTCPClient1.Host := edit1.Text;
IdTCPClient1.Connect(5000);
end;
end.
unit uServer;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, IdTCPConnection, IdTCPClient, IdBaseComponent,
IdComponent, IdTCPServer, ComCtrls;
type
TDataState = (dstNone, dstReceiving);
//Data对象用来保存一个连接的状态以及一些变量
TThreadData = class
private
FState: TDataState;
FFileSize: Integer;
FStream: TFileStream;
procedure SetState(const Value: TDataState);
procedure SetFileSize(const Value: Integer);
procedure SetStream(const Value: TFileStream);
public
constructor Create;
destructor Destroy; override;
property State : TDataState read FState write SetState;
property FileSize : Integer read FFileSize write SetFileSize;
property Stream : TFileStream read FStream write SetStream;
end;
TfmServer = class(TForm)
IdTCPServer1: TIdTCPServer;
SaveDialog1: TSaveDialog;
ProgressBar1: TProgressBar;
procedure IdTCPServer1Execute(AThread: TIdPeerThread);
procedure IdTCPServer1Connect(AThread: TIdPeerThread);
procedure IdTCPServer1Disconnect(AThread: TIdPeerThread);
private
public
{ Public declarations }
end;
var
fmServer: TfmServer;
implementation
{$R *.dfm}
procedure TfmServer.IdTCPServer1Execute(AThread: TIdPeerThread);
var
aFileSize : Integer;
aFileName : String;
Buff : array[0..1023] of Byte;
ReadCount : Integer;
begin
with AThread.Data as TThreadData do
begin
if State = dstNone then
begin
if not AThread.Terminated and AThread.Connection.Connected then
begin
//读取文件名
[red]aFileName := AThread.Connection.ReadLn(#13#10, 100);[/red]
if aFileName = '' then
Exit;
SaveDialog1.FileName := aFileName;
if SaveDialog1.Execute then
begin
//返回确认文件传输标志
AThread.Connection.WriteLn;
//开始读取文件长度,创建文件
AThread.Connection.ReadBuffer(aFileSize, 4);
FileSize := aFileSize;
ProgressBar1.Max := FileSize;
Stream := TFileStream.Create(SaveDialog1.FileName, fmCreate);
State := dstReceiving;
end
else
AThread.Connection.Disconnect
end;
end else begin
if not AThread.Terminated and AThread.Connection.Connected then
begin
//读取文件流
repeat
if FileSize - Stream.Size > SizeOf(Buff) then
ReadCount := SizeOf(Buff)
else
ReadCount := FileSize - Stream.Size;
AThread.Connection.ReadBuffer(Buff, ReadCount);
Stream.WriteBuffer(Buff, ReadCount);
ProgressBar1.Position := Stream.Size;
Caption := IntToStr(Stream.Size) + '/' + IntToStr(FileSize);
Application.ProcessMessages;
until Stream.Size >= FileSize;
AThread.Connection.WriteLn('OK');
Stream.Free;
Stream := nil;
State := dstNone;
end;
end;
end;
end;
{ TThreadData }
[red][black]constructor TThreadData.Create;
begin
inherited;
Stream := nil;
end;[/black][/red][black][/black]
[red]destructor TThreadData.Destroy;
begin
if Assigned(Stream) then
Stream.Free;
inherited;
end;
procedure TThreadData.SetFileSize(const Value: Integer);
begin
FFileSize := Value;
end;
procedure TThreadData.SetState(const Value: TDataState);
begin
FState := Value;
end;[/red]
procedure TfmServer.IdTCPServer1Connect(AThread: TIdPeerThread);
begin
AThread.Data := TThreadData.Create;
with AThread.Data as TThreadData do
begin
State := dstNone;
end;
end;
procedure TfmServer.IdTCPServer1Disconnect(AThread: TIdPeerThread);
begin
//(AThread.Data as TThreadData).Free;
end;
procedure TThreadData.SetStream(const Value: TFileStream);
begin
FStream := Value;
end;
end.
//客户端
unit uClient;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, IdTCPConnection, IdTCPClient, IdBaseComponent,
IdComponent, IdTCPServer, ComCtrls, IdAntiFreezeBase, IdAntiFreeze;
type
TfmClient = class;
TfmClient = class(TForm)
IdTCPClient1: TIdTCPClient;
Button1: TButton;
OpenDialog1: TOpenDialog;
ProgressBar1: TProgressBar;
IdAntiFreeze1: TIdAntiFreeze;
Label1: TLabel;
Edit1: TEdit;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
public
{ Public declarations }
end;
var
fmClient: TfmClient;
implementation
{$R *.dfm}
{ TThreadData }
procedure TfmClient.Button1Click(Sender: TObject);
var
Buf : array[0..1023] of Byte;
ReadCount : Integer;
aStream : TFileStream;
aSize : Integer;
aFileName : String;
begin
if OpenDialog1.Execute then
begin
IdTCPClient1.Connect;
aStream := TFileStream.Create(OpenDialog1.FileName, fmOpenRead or fmShareDenyWrite);
try
//发送文件名
aFileName := ExtractFileName(OpenDialog1.FileName);
IdTCPClient1.WriteLn(aFileName);
//等待接受确认
IdTCPClient1.ReadLn(#13#10, 1000);
//写文件长度和文件流
aSize := aStream.Size;
ProgressBar1.Max := aSize;
[red]IdTCPClient1.WriteBuffer(aSize, 4);[/red] //IdTCPClient1.WriteStream(aStream);[black][/black]
[red][black]while aStream.Position < aStream.Size do
begin
[red] [black] if aStream.Size - aStream.Position >= SizeOf(Buf) then
ReadCount := sizeOf(Buf)
else
ReadCount := aStream.Size - aStream.Position;
aStream.ReadBuffer(Buf, ReadCount);
IdTCPClient1.WriteBuffer(Buf, ReadCount);
ProgressBar1.Position := aStream.Position;[/black][/red][/black][/red]
Application.ProcessMessages;
end;
Caption := IdTCPClient1.ReadLn;
IdTCPClient1.Disconnect;
finally
aStream.Free;
showmessage('传输完毕');
end;
end;
end;
{ TMyThread }
procedure TfmClient.Button2Click(Sender: TObject);
begin
IdTCPClient1.Host := edit1.Text;
IdTCPClient1.Connect(5000);
end;
end.