小弟入门不久,想学习FTP,哪位老哥有FTP客户端源码,请提供,多谢!如果没有请告诉我显示文件列表用哪个控件,并告诉我一些简单的使用方法,急需,多谢!
解决方案 »
- delphi里的pagecontrol控件每个页面必须激活过一次里面的控件才能用于多线程?为什么?
- 代码看不懂请求助!
- 高手请入,关于格式化输出到电视屏幕问题
- 如何调用重载函数(DELPHI中的InputBox有四种形式)
- 为什么我的数据导出Excel功能在XP系统下导出都是乱码?????
- 请问,如何用程序封掉端口
- 程序启动窗体出现的问题,导致系统主窗体最小化时不能到任务栏,只能到桌面左下角的问题,帮忙看一下代码!!
- 怎样把real型的转换为string数据类型的啊?
- 如何调用access中存储的图片字段,解决就结贴(100分只给最好的)
- 请教!listview?请分析我的代码错在哪儿?
- 怎样将blob字段里的文件保存到本地?急
- 关于SQL查询出的数据的输出的问题
{***************************************************************
*
* 单 元 名 : unt_Main
* 编写目的 : 进行文件上传
* 作 者 : 黄仁光
* 编写日期 :2002年09月25日
*
****************************************************************}unit unt_Main;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Psock, NMFtp, StdCtrls, ComCtrls, inifiles, Menus, ScktComp,
Gauges, FileCtrl, ExtCtrls;type
TUploadThread = class(TThread)
private
{私有定义}
protected
procedure Execute;override;
procedure InitialBreakPoint(BytesHaveSent:int64);
end;type
TfrmMain = class(TForm)
ftpUpload: TNMFTP;
sbrInformation: TStatusBar;
mmnMain: TMainMenu;
N1: TMenuItem;
N2: TMenuItem;
cskUpload: TClientSocket;
ggHaveSend: TGauge;
memInformation: TMemo;
GroupBox1: TGroupBox;
lsbFailFile: TListBox;
palProxyServer: TPanel;
grbProxyServer: TGroupBox;
lblProxyServer: TLabel;
lblProxyPort: TLabel;
ckbUseProxyServer: TCheckBox;
grbServerOption: TGroupBox;
lblUserName: TLabel;
lblPassword: TLabel;
lblServerAddress: TLabel;
edtUserName: TEdit;
edtPassword: TEdit;
edtServerAddr: TEdit;
palOperate: TPanel;
btnUpload: TButton;
btnDisconnect: TButton;
btnCancelUpload: TButton;
btnRequestUpload: TButton;
edtProxyServer: TEdit;
edtProxyPort: TEdit;
procedure btnDisconnectClick(Sender: TObject);
procedure btnUploadClick(Sender: TObject);
procedure ftpUploadPacketSent(Sender: TObject);
procedure ftpUploadSuccess(Trans_Type: TCmdType);
procedure FormShow(Sender: TObject);
procedure N2Click(Sender: TObject);
procedure ftpDisconnect(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure lsbFailFileClick(Sender: TObject);
procedure btnCancelUploadClick(Sender: TObject);
procedure ftpUploadFailure(var Handled: Boolean; Trans_Type: TCmdType); //(var ByetesSent : longint ; var BytesTotal : longint);
procedure DisplayMemo(FileSize: integer; bComplete: Boolean);
procedure ftpUploadConnect(Sender: TObject);
procedure ftpUploadConnectionFailed(Sender: TObject);
procedure btnRequestUploadClick(Sender: TObject);
procedure ckbUseProxyServerClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
//请求上传文件
function Command(CommandSend:String):Boolean;
//连接服务器
function FTPConnect():Boolean;
//获取服务器上对应文件的大小(已上传部分)
function GetServerFileSize(SendFileName:String):int64;
//初始化断点
//procedure IniBreakPoint(BytesHaveSent:Int64);//用线程的方法代替了
//文件是否接受完毕
function FileCompleteReceive(SendFileName:String;FileSize:int64):boolean;
end; SegInfo = packed record //信息
RequstSendCommand:array[0..500] of char;//要求发送文件
FileName : array[0..500] of Char;//续传文件名
FileSize : int64;//已传输部分的该文件的大小
FileSendComplete:array[0..500] of char;//发送完毕命令
end;//const BUFFERSIZE = 1024*250;//缓冲区大小
const BUFFERSIZE = 256000;//缓冲区大小
var
frmMain: TfrmMain;
ClientCfg: TIniFile;
bComplete: Boolean;//是否是一个全新的传送
BytesSent: int64;//已传送字节数(实时的)
bSending:Boolean;//是否正处于发送状态
objSegInfo : SegInfo;
implementation
uses unt_Method, Unit_Option;
{$R *.DFM}{***************************************************************
* 方 法 名 : TUploadThread.Execute
* 编写目的 : 执行上载文件
* 作 者 : 黄仁光
* 参 数 : None
* 结 果 : None
* 编写日期 :2002年10月09日
****************************************************************}
procedure TUploadThread.Execute;
var
BytesHaveSent:Int64;
BytesTotal:Int64;
ConfigIniFile:TIniFile;
begin
FreeOnTerminate := true;
with frmMain do
begin
if Terminated then
exit;
memInformation.Clear;
if FileToSendName = '' then
begin
Application.MessageBox('请在列表框中选择要传输的文件!', '错误', MB_OK);
exit;
end;
btnUpload.Enabled := false;
btnCancelUpload.Enabled:= false;
N1.Enabled := false;
memInformation.Clear;
try
ClientCfg := TIniFile.Create(ExtractFileDir(Application.ExeName) + '\FileConfig.ini');
try
if bComplete = true then
begin
if FTPConnect then
begin
IniCfgFile(FileToSendName);
DisplayMemo(ClientCfg.ReadInteger('Job' + IntToStr(ClientCfg.ReadInteger('Job', 'Count', 0)), 'BytesTotal', 0), bComplete);
lsbFailFile.Items.Add(FileToSendName);
ftpUpload.Mode(MODE_BYTE);
memInformation.Lines.Add('正在传送文件......');
btnDisconnect.Enabled := true;
bSending := true;
ftpUpload.Upload(FileToSendName, ExtractFileName(FileToSendName));
end;
end
else //续传
begin
DisplayMemo(ClientCfg.ReadInteger('Job' + IntToStr(ClientCfg.ReadInteger('Job', 'Count', 0)), 'BytesTotal', 0), bComplete);
BytesHaveSent := GetServerFileSize(FileToSendName);
if BytesHaveSent <> 0 then
begin
//进度条
ConfigIniFile := TIniFile.Create(ExtractFileDir(Application.ExeName) + '\FileConfig.ini');
BytesTotal := ConfigIniFile.ReadInteger('Job' + IntToStr(lsbFailFile.ItemIndex+1), 'BytesTotal', 0);
ggHaveSend.Progress := (100*BytesHaveSent) div BytesTotal;
//IniBreakPoint(BytesHaveSent);
//Synchronize(InitialBreakPoint);
bSending := true;
InitialBreakPoint(BytesHaveSent);//如果出现意想不到的异常,则需要定义
BytesSent := BytesHaveSent; //一个全局变量,使用Synchronize方法
end
else
begin
ftpUpload.Disconnect;
memInformation.Lines.Add('要求续传该文件失败!');
bSending := false;
exit;
end; if FTPConnect then
begin
ftpUpload.Mode(MODE_BYTE);
memInformation.Lines.Add('正在传送文件......');
bSending := true;
btnDisconnect.Enabled := true;
ftpUpload.UploadAppend(TempFilePath + '\TempFile' + ExtractFileName(FileTOSendName), ExtractFileName(FileToSendName));
end;
end;
except
memInformation.Lines.Add('与服务器断开连接!');
ftpUpload.Disconnect;
btnDisconnect.Enabled := false;
bSending := false;
exit;
end;
finally
ClientCfg.Free;//使用了全局变量不好
N1.Enabled:= true;
end;
end;
end;
var
IniFile: TIniFile;
hFile: THandle;//上传的文件句柄
hTempFile: THandle;//临时文件句柄
strTemp:String;//可能不需要
JobNo:Integer;
begin
with frmMain do
begin
JobNo := ClientCfg.ReadInteger('Job', 'Count', 0);
DisplayMemo(ClientCfg.ReadInteger('Job' + IntToStr(JobNo), 'BytesTotal', 0), bComplete);
memInformation.Lines.Add('正在初始化断点,可能花费的时间较长,请耐心等待!');
try
IniFile := TIniFile.Create(ExtractFileDir(Application.ExeName) + '\FileConfig.ini'); //hrg add
FileToSendName := IniFile.ReadString('Job' + IntToStr(JobNo), 'FileName', FileToSendName); //hrg change
IniFile.WriteInteger('Job' + IntToStr(JobNo),'BytesSent',BytesHaveSent);
finally
FreeAndNil(IniFile);
end;
if FileExists(TempFilePath + '\TempFile' + ExtractFileName(FileToSendName)) then
begin
DeleteFile(TempFilePath + '\TempFile' + ExtractFileName(FileToSendName));
end;
hFile := FileOpen(FileToSendName, fmOpenRead);
strTemp := TempFilePath + '\TempFile' + ExtractFileName(FileToSendName);//可能不需要
hTempFile := FileCreate(TempFilePath + '\TempFile' + ExtractFileName(FileToSendName));
FileClose(hFile);
FileClose(hTempFile);
FileCopy(FileToSendName,strTemp,BytesHaveSent);
memInformation.Lines.Add('断点初始化完毕!');
end;
end;function TfrmMain.FTPConnect():Boolean;
begin
result := false;
try
if ftpUpload.Connected then//有待商榷,是否断开后再去连接
ftpUpload.Disconnect;
if ftpUpload.Connected = false then
begin
ftpUpload.UserID := edtUserName.Text;
ftpUpload.Password := edtPassword.Text;
ftpUpload.Host := edtServerAddr.Text;
if ckbUseProxyServer.Checked then
begin
ftpUpload.Proxy := edtProxyServer.Text;
try
ftpUpload.Port := StrToInt(edtProxyPort.Text);
except
Application.MessageBox('端口必须是整数','端口填写错误',MB_OK)
end;
end;
ftpUpload.Connect;
result := ftpUpload.Connected;
end;
except
//result可能不需要
memInformation.Lines.Add('连接服务器失败!');
btnDisconnect.Enabled := false;
bSending := false;
exit;
end;
end;function TfrmMain.FileCompleteReceive(SendFileName:String;FileSize:int64):boolean;
var
SktStream : TWinSocketStream;
begin
result := false;
FillChar(objSegInfo,sizeof(objSegInfo),0);
StrPCopy(objSegInfo.FileName,SendFileName);
objSegInfo.FileSize := FileSize;
try
cskUpload.Address := edtServerAddr.Text;
try
if cskUpload.Active = true then
cskUpload.Close;
except
memInformation.Lines.Add('断开连接错误');
end;
cskUpload.Open;
except
memInformation.Lines.Add('连接服务器失败,请检测地址、密码、用户是否填写正确。');
Application.MessageBox('连接失败','提示',MB_OK);
exit;
end;
SktStream:= TWinSocketStream.Create(cskUpload.Socket,8000);//下面这段代码存在Bug
try
if cskUpload.Active = true then
SktStream.WriteBuffer(objSegInfo,sizeof(objSegInfo));
if (cskUpload.Active = true) and (SktStream.WaitForData(8000)) then
SktStream.ReadBuffer(objSegInfo,sizeof(objSegInfo));
except
//Application.MessageBox('请确认FTP站点是否将此文件已上传的部分删除掉了','提示',MB_OK);
FreeAndNil(SktStream);
exit;
end;
if StrPas(objSegInfo.FileSendComplete) = '文件接收完毕' then
result:= true;
cskUpload.Close;
FreeAndNil(SktStream);
end;function TfrmMain.GetServerFileSize(SendFileName:String):int64;
var
SktStream : TWinSocketStream;
begin
FillChar(objSegInfo,sizeof(objSegInfo),0);
StrPCopy(objSegInfo.FileName,SendFileName);
try
cskUpload.Address := edtServerAddr.Text;
try
if cskUpload.Active = true then
cskUpload.Close;
except
memInformation.Lines.Add('断开连接错误');
end;
cskUpload.Open;
except
memInformation.Lines.Add('连接服务器失败,请检测地址、密码、用户是否填写正确。');
Application.MessageBox('连接失败','提示',MB_OK);
result := 0;
exit;
end;
SktStream:= TWinSocketStream.Create(cskUpload.Socket,8000);//下面这段代码存在Bug
try
if cskUpload.Active = true then
begin
SktStream.WriteBuffer(objSegInfo,sizeof(objSegInfo));
end;
if (cskUpload.Active = true) and (SktStream.WaitForData(8000)) then
SktStream.ReadBuffer(objSegInfo,sizeof(objSegInfo));
except
//Application.MessageBox('请确认FTP站点是否将此文件已上传的部分删除掉了','提示',MB_OK);
FreeAndNil(SktStream);
result := 0;
exit;
end;
result:= objSegInfo.FileSize;
cskUpload.Close;
FreeAndNil(SktStream);
end;procedure TfrmMain.DisplayMemo(FileSize: integer; bComplete: Boolean);
begin
memInformation.Clear;
memInformation.Lines.Add('*************************************************************');
memInformation.Lines.Add('[文件信息]');
memInformation.Lines.Add('文件名:' + FileToSendName);
memInformation.Lines.Add('文件大小:' + IntToStr(FileSize) + '字节');
if bComplete = true then
memInformation.Lines.Add('传送类型: 全新传送')
else
memInformation.Lines.Add('传送类型: 断点续传');
memInformation.Lines.Add('*************************************************************');
end;//中断连接并停止传输
procedure TfrmMain.btnDisconnectClick(Sender: TObject);
begin
if Application.MessageBox('确实要中断当前传输?', '提示', MB_OKCANCEL) = IDOK then
begin
try
if ftpUpload.Connected then
ftpUpload.Abort;
//ftpUpload.Disconnect;
bSending := false;
bComplete := false;
btnDisconnect.Enabled := false;
except
FileToSendName := '';
bSending := false;
Application.MessageBox('断开错误','提示',MB_OK);
end;
end;
FileToSendName := '';
end;
var
BTotal: int64;
BSent: int64;
begin
BSent := BytesSent + ftpUpload.BytesSent;
ClientCfg.WriteInteger('Job' + IntToStr(ClientCfg.ReadInteger('Job', 'Count', 0)), 'BytesSent', BSent);
BTotal := ClientCfg.ReadInteger('Job' + IntToStr(ClientCfg.ReadInteger('Job', 'Count', 0)), 'BytesTotal', 0);
ggHaveSend.Progress:= (100*BSent) div BTotal;
sbrInformation.Panels[0].Text:= '已传送 : '+IntToStr(BSent)+'字节';
sbrInformation.Panels[1].Text:= '文件大小 : '+IntToStr(BTotal)+'字节';
end;procedure TfrmMain.ftpUploadSuccess(Trans_Type: TCmdType);
var
FileConfigIni: TIniFile;
iLoop: Byte;
FailFileCount: Byte;
begin
if ((Trans_Type = cmdUpload) or (Trans_Type = cmdAppend)) then
begin
if FileCompleteReceive(FileToSendName,GetSendFileSize(FileToSendName)) then
begin
FileConfigIni := TIniFile.Create(ExtractFileDir(Application.ExeName) + '\FileConfig.ini');
FailFileCount := FileConfigIni.ReadInteger('Job', 'Count', 0);
for iLoop := 1 to FailFileCount do
begin
if FileConfigIni.ReadString('Job' + IntToStr(FailFileCount), 'FileName', '') = FileToSendName then
begin
FileConfigIni.EraseSection('Job' + IntToStr(FailFileCount));
FileConfigIni.WriteInteger('Job', 'Count', FailFileCount - 1);
end;
end;
for iLoop := 0 to lsbFailFile.Items.Count - 1 do
begin
if lsbFailFile.Items.Strings[iLoop] = FileToSendName then
begin
lsbFailFile.Items.Delete(iLoop);
end;
end;
memInformation.Lines.Add('文件传送完毕!');
DeleteFile(TempFilePath + '\TempFile' + ExtractFileName(FileToSendName));
btnDisconnect.Enabled := false;
btnUpload.Enabled := false;
bSending := false;
BytesSent := 0;
ggHaveSend.Progress:= 0;
sbrInformation.Panels[0].Text:= '';
sbrInformation.Panels[1].Text:= '';
bComplete:= true;
FileToSendName := '';
end
else//接收方没有接收到文件的最后部分才造成接收方认为没有完全接收文件
begin //这种情况出现的概率应当说是非常的小
Application.MessageBox('文件还没有完全传输成功请在文件列表中选择该文件继续上传','提示',MB_OK);
ggHaveSend.Progress:= 0;
sbrInformation.Panels[0].Text:= '';
sbrInformation.Panels[1].Text:= '';
end;
end;
end;procedure TfrmMain.ftpDisconnect(Sender: TObject);
begin
btnDisconnect.Enabled := false;
btnUpload.Enabled := false;
end;procedure TfrmMain.FormCreate(Sender: TObject);
var
IniFile: TIniFile;
hFile: THandle;
temp:String;
begin
BytesSent:= 0;
bSending := false;
if not FileExists(ExtractFileDir(Application.ExeName) + '\FileConfig.ini') then
begin
Application.MessageBox('配置文件丢失,无法保存上次断点续传信息。如有文件未完成,请重新上传。','错误',MB_OK);
hFile := FileCreate(ExtractFileDir(Application.ExeName) + '\FileConfig.ini');
FileClose(hFile);
FileSetAttr('.\FileConfig', faArChive);
end;
temp := ExtractFileDir(Application.ExeName) + '\FileConfig.ini';
IniFile := TIniFile.Create(ExtractFileDir(Application.ExeName) + '\FileConfig.ini');
if (IniFile.ReadString('FileConfig', 'TempFilePath','') = '') or (not DirectoryExists('.\Temp')) then
begin
CreateDir('.\Temp');
IniFile.WriteString('FileConfig', 'TempFilePath', GetCurrentDir + '\Temp');
end;
if IniFile.ReadInteger('Job', 'Count', 0) = 0 then
IniFile.WriteInteger('Job', 'Count', 0);
IniFile.Free;
exit;
end;procedure TfrmMain.lsbFailFileClick(Sender: TObject);
begin
//lsbFailFile.Selected[lsbFailFile.ItemIndex]:= false;//:= not lsbFailFile.Selected[lsbFailFile.ItemIndex];
//if lsbFailFile.Selected[lsbFailFile.ItemIndex] = true then
if not bSending then
begin
FileToSendName := lsbFailFile.Items.Strings[lsbFailFile.ItemIndex];
bComplete := false;
btnUpload.Enabled := lsbFailFile.Selected[lsbFailFile.ItemIndex];
btnCancelUpload.Enabled:= true;
end;
end;
procedure TfrmMain.btnCancelUploadClick(Sender: TObject);
begin
{try
if ftp.Connected = false then
begin
ftp.UserID := EditUser.Text;
ftp.Password := EditPwd.Text;
ftp.Host := EditServerAddr.Text;
ftp.Connect;
end;
except
Application.MessageBox('与服务器连接出现错误!', '错误', MB_OK);
exit;
end;
try
ftp.Delete(ExtractFileName(lsbFailFile.Items.Strings[lsbFailFile.ItemIndex]));
except
Application.MessageBox('无法删除文件,请检查文件分段是否存在,或服务器是否允许此项操作。', '错误', MB_OK);
exit;
end;}
if Application.MessageBox('此操作将导致已发送文件段的遗失,无法进行此文件的续传。是否继续?','提示',MB_OKCANCEL) = IDOK then
begin
DeleteFile(ExtractFileDir(Application.ExeName) + '\FileConfig.ini');
DeleteFile(TempFilePath + '\TempFile' + ExtractFileName(lsbFailFile.Items.Strings[lsbFailFile.ItemIndex]));
lsbFailFile.Items.Delete(lsbFailFile.ItemIndex);
ggHaveSend.Progress:= 0;
memInformation.Clear;
sbrInformation.Panels[0].Text:= '';
sbrInformation.Panels[1].Text:= '';
bComplete:= true;
btnUpload.Enabled := false;
btnCancelUpload.Enabled := false;
exit;
end;
end;procedure TfrmMain.ftpUploadFailure(var Handled: Boolean; Trans_Type: TCmdType);
begin
//if Trans_Type = cmdDelete then
// Application.MessageBox('无法删除文件,请检查文件分段是否存在,或服务器是否允许此项操作。', '错误', MB_OK);
case Trans_Type of
cmdChangeDir: memInformation.Lines.Add('改变目录失败');
cmdMakeDir: memInformation.Lines.Add('创建目录失败');
cmdDelete: memInformation.Lines.Add('删除文件失败');
cmdRemoveDir: memInformation.Lines.Add('删除目录失败');
cmdList: memInformation.Lines.Add('列出列表失败');
cmdRename: memInformation.Lines.Add('改文件名失败');
cmdUpRestore: memInformation.Lines.Add('重新上传失败');
cmdDownRestore: memInformation.Lines.Add('重新下载失败');
cmdDownload: memInformation.Lines.Add('下载失败');
cmdUpload: memInformation.Lines.Add('上传失败');
cmdAppend: memInformation.Lines.Add('追加上传失败');
cmdReInit: memInformation.Lines.Add('重新初始化失败');
cmdAllocate: memInformation.Lines.Add('分配失败');
cmdNList: memInformation.Lines.Add('列举文件名和目录失败');
cmdDoCommand: memInformation.Lines.Add('发送命令失败');
cmdCurrentDir: memInformation.Lines.Add('访问当前目录失败');
end;
end;procedure TfrmMain.ftpUploadConnect(Sender: TObject);
begin
memInformation.Lines.Add('FTP连接成功');
end;procedure TfrmMain.ftpUploadConnectionFailed(Sender: TObject);
begin
memInformation.Lines.Add('FTP连接失败');
end;procedure TfrmMain.ckbUseProxyServerClick(Sender: TObject);
begin
if ckbUseProxyServer.Checked then
begin
edtProxyServer.Enabled := true;
edtProxyPort.Enabled := true;
end
else
begin
edtProxyServer.Enabled := false;
edtProxyPort.Enabled := false;
end;
end;
{***************************************************************
*
* 单 元 名 : unt_Server
* 编写目的 : 提供服务信息
* 作 者 : 黄仁光
* 编写日期 :2002年10月08日
*
****************************************************************}unit unt_Server;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ScktComp, StdCtrls, Psock, NMMSG, NMFtp, ComCtrls,inifiles,registry;type
TfrmServer = class(TForm)
btnStartup: TButton;
btnStop: TButton;
sbrInformation: TStatusBar;
sskProvideServer: TServerSocket;
memInformation: TMemo;
procedure sskProvideServerGetThread(Sender: TObject;
ClientSocket: TServerClientWinSocket;
var SocketThread: TServerClientThread);
procedure btnStartupClick(Sender: TObject);
procedure btnStopClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end; TMultiThread = class(TServerClientThread)
constructor Create(CreateSuspended: Boolean; ASocket: TServerClientWinSocket);
procedure ClientExecute;override;
//destructor Destroy;override;
end; SegInfo = packed record //信息
RequstSendCommand:array[0..500] of char;//要求发送文件
FileName : array[0..500] of Char;//文件名
FileSize : int64;//文件大小
FileSendComplete:array[0..500] of char;//发送完毕命令
end;var
frmServer: TfrmServer;
hTempFile : THandle;
CSocket : TServerClientWinSocket;
objSegInfo : SegInfo;
UserHost:String;
implementation
uses unt_Method;{$R *.DFM}{***************************************************************
* 方 法 名 : TfrmServer.sskProvideServerGetThread
* 编写目的 :
* 作 者 : 黄仁光
* 参 数 : Sender
ClientSocket
SocketThread
* 结 果 : None
* 编写日期 :2002年11月11日
****************************************************************}
procedure TfrmServer.sskProvideServerGetThread(Sender: TObject;
ClientSocket: TServerClientWinSocket;
var SocketThread: TServerClientThread);
begin
CSocket:= ClientSocket;
SocketThread:= TMultiThread.Create(false,ClientSocket);
end;{***************************************************************
* 方 法 名 : ClientExecute
* 编写目的 : 处理与客户端的信息交流
* 作 者 : 黄仁光
* 参 数 : None
* 结 果 : None
* 编写日期 :2002年10月08日
****************************************************************}
procedure TMultiThread.ClientExecute;
var
SktStream : TWinSocketStream;
f: file of Byte;
FileToSendName:String;
CommandSend:String;//反馈消息
SendFileSize:int64;//发送端实际发送的文件大小
begin
UserHost := CSocket.RemoteHost;
FillChar(objSegInfo,sizeof(objSegInfo),0);
SktStream:= TWinSocketStream.Create(CSocket,5000);
if SktStream.WaitForData(8000) then
begin
SktStream.ReadBuffer(objSegInfo,sizeof(objSegInfo));
//响上传应请求
if StrPas(objSegInfo.RequstSendCommand) = '要求上传文件' then
begin
if Application.MessageBox(PChar('客户'+UserHost+'请求上传文件,同意吗?'),'客户请求',MB_OKCANCEL) = IDOK then
begin
CommandSend := '允许发送文件';
StrPCopy(objSegInfo.RequstSendCommand,CommandSend);
end
else
begin
CommandSend := '不允许发送文件';
StrPCopy(objSegInfo.RequstSendCommand,CommandSend);
end
end;
//获取上传来的文件名
if Trim(StrPas(objSegInfo.FileName)) <> '' then
begin
FileToSendName := StrPas(objSegInfo.FileName);
frmServer.sbrInformation.Panels.Items[1].Text := ExtractFileName(StrPas(objSegInfo.FileName));
AssignFile(f, GetFTPRoot+'\'+ExtractFileName(FileToSendName));
try
Reset(f);
except
Application.MessageBox('文件打开错误', '提示', MB_OK);
SktStream.Free;
exit;
end;
//判断是否接收完毕
SendFileSize := objSegInfo.FileSize;//发送方所发送的文件大小,当发送方认为发送完毕时传送过来
objSegInfo.FileSize:= FileSize(f);//FileSize(f)实际接收到的文件大小,续传和完毕时要用到
if FileSize(f) = SendFileSize then
begin
StrPCopy(objSegInfo.FileSendComplete,'文件接收完毕');
//objSegInfo.FileSendComplete := '文件接收完毕';
frmServer.memInformation.Lines.Add('接收来自'+UserHost+'的文件完毕');
frmServer.memInformation.Lines.Add('文件名为:'+ExtractFileName(FileToSendName));
frmServer.memInformation.Lines.Add('文件大小为:'+IntToStr(SendFileSize));
end
else
begin
frmServer.memInformation.Lines.Add(UserHost+'准备续传文件');
frmServer.memInformation.Lines.Add('续传的文件名为:'+ExtractFileName(FileToSendName));
end;
CloseFile(f);
end;
SktStream.WriteBuffer(objSegInfo,sizeof(objSegInfo));
SktStream.Free;
end;
end;constructor TMultiThread.Create(CreateSuspended: Boolean; ASocket: TServerClientWinSocket);
begin
inherited;
FreeOnTerminate:= true;
end;procedure TfrmServer.btnStartupClick(Sender: TObject);
begin
sskProvideServer.Open;
btnStartup.Enabled := false;
btnStop.Enabled := true;
sbrInformation.Panels.Items[0].Text := '服务已经启动';
end;procedure TfrmServer.btnStopClick(Sender: TObject);
begin
sskProvideServer.Close;
btnStartup.Enabled := true;
btnStop.Enabled := false;
sbrInformation.Panels.Items[0].Text := '服务已经停止';
end;procedure TfrmServer.FormDestroy(Sender: TObject);
begin
sskProvideServer.Free;
end;procedure TfrmServer.FormCreate(Sender: TObject);
begin
memInformation.Lines.Add('FTP的根目录是'+GetFTPRoot);
//SetFTPOption;//设置FTP的属性
end;end.