ftp服务器详解+源代码
- 格式:doc
- 大小:209.50 KB
- 文档页数:38
FTP命令使用详解FTP(File Transfer Protocol,文件传输协议)是一种用于在网络上进行文件传输的协议。
它使用客户端-服务器模型来传输文件,客户端通过FTP命令与服务器建立连接并发送命令来进行文件操作。
FTP命令可以分为两类:原始FTP命令和扩展FTP命令。
原始FTP命令是FTP协议定义的基本命令,如USER、PASS、LIST、RETR和STOR等;扩展FTP命令是在原始FTP命令的基础上添加的一些功能性命令,如MKD、RMD、RNFR、RNTO和SIZE等。
下面是一些常用的FTP命令及其使用详解:1. USER:用于指定登录FTP服务器的用户名。
语法:USER username示例:USER alice说明:发送用户名给服务器进行验证。
2. PASS:用于指定登录FTP服务器的密码。
语法:PASS password说明:发送密码给服务器进行验证。
3. LIST:用于列出当前目录下的文件和子目录。
语法:LIST [dirname]示例:LIST /pub说明:如果指定了dirname参数,则列出该目录下的文件和子目录;如果未指定,则列出当前目录下的文件和子目录。
示例:RETR myfile.txt5. STOR:用于将本地计算机上的文件上传到远程服务器。
语法:STOR filename示例:STOR myfile.txt说明:将本地计算机上的名为myfile.txt的文件上传到服务器。
6. MKD:用于在远程服务器上创建新目录。
语法:MKD dirname示例:MKD newdir说明:在服务器上创建一个名为newdir的新目录。
7. RMD:用于在远程服务器上删除指定目录。
语法:RMD dirname示例:RMD olddir说明:在服务器上删除名为olddir的目录。
8. RNFR和RNTO:用于重命名远程服务器上的文件或目录。
语法:RNFR oldname; RNTO newname示例:RNFR oldfile.txt; RNTO newfile.txt说明:将服务器上的名为oldfile.txt的文件重命名为newfile.txt。
FTP服务器一、下载 /二、安装[root@localhost windows]# cp vsftpd-2.0.7.tar.gz /usr/src[root@localhost windows]# cd /usr/src[root@localhost src]# tar -zxvf vsftpd-2.0.7.tar.gz[root@localhost src]# cd vsftpd-2.0.7[root@localhost vsftpd-2.0.7]# cat -n INSTALL |less 查看帮助文件。
[root@localhost vsftpd-2.0.7]# make[root@localhost vsftpd-2.0.7]# make install[root@localhost vsftpd-2.0.7]# which vsftpd三、配置服务器[root@localhost vsftpd-2.0.7]# cp vsftpd.conf /etc 将配置示例文件copy到/etc目录下。
[root@localhost vsftpd-2.0.7]# cp RedHat/vsftpd.pam /etc/pam.d/ftp pam是一个身份验证模块,可对用户身份进行验证。
[root@localhost vsftpd-2.0.7]# vi /etc/vsftpd.conflisten=YES 最后一行加入此代码,需要服务器独立运行,所以自己监听端口。
[root@localhost vsftpd-2.0.7]# /usr/local/sbin/vsftpd & 启动服务并在后台运行。
[1] 15040 --->监听编号。
[root@localhost vsftpd-2.0.7]# ps -aux|grep vsftpd 查看到PID。
[root@localhost vsftpd-2.0.7]# netstat -tnl 查看一下有没有开放21的端口。
rem setlocal批处理中所作的环境更改只影响本批处理。
前面加@的作用,不显示此行命令本身@setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSIONrem 显示命令本身关@echo offrem 填ftp服务器地址或域名set ftpsvr=localhostrem 填用户名set user=lijrem 填密码set pass=jierem 填保存备份的文件夹set archdir=D:\abcrem 填WinRAR安装文件夹,如:C:\Program Files\WinRAR ----------- compress已经注释,无需此功能rem set rardir=C:\Program Files\WinRARrem 把要使用的临时文件夹的路径设为环境变量mytempset mytemp=%temp%\ftp.xrem 防止可能的同名文件夹或文件存在影响工作,全删一遍。
>nul不显示回显2>nul不显示错误信息rd /s /q "%mytemp%">nul 2>nuldel /a /f "%mytemp%">nul 2>nulmd "%mytemp%"rem 把一个斜杠写到%mytemp%\rdl里面。
斜杠表示远程的根文件夹。
rdl用作保存远程文件夹列表。
echo />"%mytemp%\rdl"rem 已下载文件的远程文件夹计数set dcount=0rem 标号cycle:cyclerem 获取远程文件夹内的文件和子文件夹列表。
rem 因为下面那个for要被执行多次,非第一次执行要跳过已处理的行,所以要写skip=n。
rem 但是,第一次执行时,写个skip=0出错。
所以第一次执行时不写ship= 。
if %dcount%==0 set oo=if not %dcount%==0 set oo=^ skip=%dcount%rem 跳过指定的行数,每次从rdl文件中取一行赋给%%I。
//连接FTPvari:integer;tr : Tstrings;IdFTP1.Quit;tr := TStringlist.Create;IdFTP1.Host := hostTxt.Text; //FTP服务器地址 172.20.16.76IdFTP1.Port := StrToInt(PortTxt.Text); //FTP服务器端口号9500ername := UserTxt.Text; //FTP服务器用户名IdFTP1.Password := pwdTxt.Text; //FTP服务器密码IdFTP1.Connect(); //连接到ftpIdFTP1.ChangeDir('JMPZ');IdFTP1.List(tr); //得到目录下所有文件列表FFTxt.Items.Assign(tr);tr.Free;//ftp当前路径,从登陆用户的起始目录起始IdFTP1.RetrieveCurrentDir//ftp目录变换,DirName只能是上一目录,或者下一目录,无需加"/"IdFTP1.ChangeDir(DirName);idftp_Client.Connected// 判断是否连接//要使用IdFTP1.DirectoryListing属性,必须uses IdAllFTPListParsers;否则会有no idftplistparse classes have been registered的错误//===========================================================UseMLIS为目录解析器相关的参数,不同的Ftp服务器,会有不同的格式//使用idftp1.list命令获取的目录列表时,显示列表为drw-rw-rw- 1 user group0 Jun 2619:30 JMPZdrw-rw-rw- 1 user group0 Jun 2619:31加密配置若进入二级目录,则多显示两行drw-rw-rw- 1 user group0 Jun 2619:30 .drw-rw-rw- 1 user group0 Jun 2619:30 ..drw-rw-rw- 1 user group0 Apr 509:420旧订单drw-rw-rw- 1 user group0 Apr 509:2911rrrrrrrr但是当参数eMLIS:= true;时,显示列表为Type=dir;Modify=20170626113034;Win32.ea=0x00000010; JMPZType=dir;Modify=20170626113101;Win32.ea=0x00000010; 加密配置若进入二级目录,则多显示行Type=cdir;Modify=20170626113034;Win32.ea=0x00000010; /JMPZType=dir;Modify=20170405014212;Win32.ea=0x00000010; 0旧订单Type=dir;Modify=20170405012904;Win32.ea=0x00000010; 11rrrrrrrrType=dir;Modify=20170608010420;Win32.ea=0x00000010; 4501036094或者(不同的Ftp服务器,会有不同的格式)11-16-1604:59PM <DIR> aspnet_client06-28-1709:06AM <DIR> H_I11-15-1608:43AM <DIR> H_P09-30-1508:43AM <DIR> JMPZ09-22-1503:52PM <DIR> USB_Driver_Windows//=================================================================//上传文件,要保证FTP路径正确,文件夹存在,默认会覆盖uses IdFTPCommon;//ftBinaryIdFTP1.Put('本地文件及路径', AnsiToUtf8('FTP文件夹相对路径'));IdFTP1.TransferType := ftBinary;IdFTP1.Put('1.txt', AnsiToUtf8('4501036094\Main.txt'));//================================================================//创建文件夹,调试模式下,会报错tryIdFTP1.ChangeDir('000');exceptIdFTP1.MakeDir('000');IdFTP1.ChangeDir('000');end;//===================================================================== =//判断文件是否存在if idftp1.Size('ip.bin')=-1thenbeginNoteFlag('下载失败',clred);Exit;end;//==================================================================== //下载文件夹内的所有文件及文件夹procedure TForm1.DownloadDirectory(var idFTP: TIdFtp;LocalDir, RemoteDir: string);vari,DirCount: Integer;strName: string;beginif Copy(LocalDir,Length(LocalDir),1)<>'\'thenLocalDir:=LocalDir+'\';if not DirectoryExists(LocalDir + RemoteDir) thenbeginCreateDirectory(PChar(LocalDir + RemoteDir),nil); //创建一个全路径的文件夹LogTxt.Lines.Add('建立目录:' + LocalDir + RemoteDir);end;idFTP.ChangeDir(AnsiToUtf8(RemoteDir));idFTP.TransferType := ftASCII;idFTP.List(nil);DirCount := idFTP.DirectoryListing.Count;for i := 0to DirCount - 1dobeginstrName := Utf8ToAnsi(idFTP.DirectoryListing.Items[i].FileName);LogTxt.Lines.Add('解析文件:' + strName);if idFTP.DirectoryListing.Items[i].ItemType = ditDirectory thenif (strName = '.') or (strName = '..') thenContinueelsebeginDownloadDirectory(idFTP,LocalDir + RemoteDir + '\', strName);idFTP.ChangeDir('..');idFTP.List(nil);endelsebeginif (ExtractFileExt(strName) = '.txt') or (ExtractFileExt(strName) = '.html') or (ExtractFileExt(strName) = '.htm') thenidFTP.TransferType := ftASCII //文本模式elseidFTP.TransferType := ftBinary; //二进制模式idFTP.Get(AnsiToUtf8(strName), LocalDir + RemoteDir + '\' + strName, True);LogTxt.Lines.Add('下载文件:' + strName);end;Application.ProcessMessages;end;end;//调用DownloadDirectory(idftp1,ExtractFilePath(Application.ExeName),'H_C');//ExtractFilePath(Application.ExeName):下载到本地文件夹//H_C:FTP的文件夹。
FileZilla客户端源码解析FileZilla客户端源码解析 FTP是TCP/IP协议组的协议,有指令通路和数据通路两条通道。
⼀般来说,FTP标准命令TCP端⼝号是21,Port⽅式数据传输端⼝是20。
FileZilla作为populate open source project,⾃然也有指令通路和数据通路。
然⽽,FileZilla源码极少有注释,⽹上参考资料也寥寥⽆⼏。
FileZilla⽤的到类库多且复杂(客户端wxWeidgets、GnuTLS、sqlite3、GNU IDN Library - Libidn,服务端boost、zlib),模式也不易理解(proxy模式、改编CAsynSocket的CAsynSocketEx、layer等)。
想要完全搞懂FileZilla的细节似乎是件很困难的事情。
好在我只需了解⾥⾯核⼼代码的⼯作原理,能封装为⼰所⽤即可。
FileZilla官⽅论坛回答提问时指出,engine⼯程重点是ControlSocket.h和transfersocket.h,显然,⼀个对应ftp控制,另⼀个对应数据传输。
interface⼯程重点是Mainfrm.h、state.h、commandqueue.h(出于效率考虑,很复杂)。
engine⼯程其他重点类有 CServer, CServerPath, CDirectoryListing, COptionsBase,客户端interface⼯程其他重点类有 COptions。
此外,客户端interface定义了资源⽂件dialog.xrc和menu.xrc(这两个⽤wxWidgets资源编辑器打开。
⽤⽂本打开也可以,内容是xml格式)。
该论坛链接地址为https:///viewtopic.php?f=3&t=8443。
截图如下1 command指令相关1.1 CCommand指令类,头⽂件:commands.h,⼯程:engine,性质:抽象类、虚基类 CCommand及其基类定义了ftp指令实体,是CCommandQueue操作的基本单元。
FTP 的主要功能如下:∙提供文件的共享(计算机程序 / 数据);∙支持间接使用远程计算机;∙使用户不因各类主机文件存储器系统的差异而受影响;∙可靠且有效的传输数据。
FTP ,尽管可以直接被终端用户使用,但其应用主要还是通过程序实现。
FTP 控制帧即指 TELNET 交换信息,包含 TELNET 命令和选项。
然而,大多数 FTP 控制帧是简单的 ASCII 文本,可以分为 FTP 命令或 FTP 消息。
FTP 消息是对 FTP 命令的响应,它由带有解释文本的应答代码构成。
命令描述ABOR 中断数据连接程序ACCT <account> 系统特权帐号ALLO <bytes> 为服务器上的文件存储器分配字节APPE <filename> 添加文件到服务器同名文件CDUP <dir path> 改变服务器上的父目录CWD <dir path> 改变服务器上的工作目录DELE <filename> 删除服务器上的指定文件HELP <command> 返回指定命令信息LIST <name> 如果是文件名列出文件信息,如果是目录则列出文件列表MODE <mode> 传输模式(S=流模式,B=块模式,C=压缩模式)MKD <directory> 在服务器上建立指定目录NLST <directory> 列出指定目录内容NOOP 无动作,除了来自服务器上的承认PASS <password> 系统登录密码PASV 请求服务器等待数据连接PORT <address> IP 地址和两字节的端口 IDPWD 显示当前工作目录QUIT 从 FTP 服务器上退出登录REIN 重新初始化登录状态连接REST <offset> 由特定偏移量重启文件传递RETR <filename> 从服务器上找回(复制)文件RMD <directory> 在服务器上删除指定目录RNFR <old path> 对旧路径重命名RNTO <new path> 对新路径重命名SITE <params> 由服务器提供的站点特殊参数SMNT <pathname> 挂载指定文件结构STAT <directory> 在当前程序或目录上返回信息STOR <filename> 储存(复制)文件到服务器上STOU <filename> 储存文件到服务器名称上STRU <type> 数据结构(F=文件,R=记录,P=页面)SYST 返回服务器使用的操作系统TYPE <data type> 数据类型(A=ASCII,E=EBCDIC,I=binary)USER <username>> 系统登录的用户名标准 FTP 信息如下:响应代码解释说明110 新文件指示器上的重启标记120 服务器准备就绪的时间(分钟数)125 打开数据连接,开始传输150 打开连接200 成功202 命令没有执行211 系统状态回复212 目录状态回复213 文件状态回复214 帮助信息回复215 系统类型回复220 服务就绪221 退出网络225 打开数据连接226 结束数据连接227 进入被动模式(IP 地址、ID 端口)230 登录因特网250 文件行为完成257 路径名建立331 要求密码332 要求帐号350 文件行为暂停421 服务关闭425 无法打开数据连接426 结束连接450 文件不可用451 遇到本地错误452 磁盘空间不足500 无效命令501 错误参数502 命令没有执行503 错误指令序列504 无效命令参数530 未登录网络532 存储文件需要帐号550 文件不可用551 不知道的页类型552 超过存储分配553 文件名不允许。
最近一段时间,因为公司项目的需要,对HTTP协议以及FTP 协议都有所了解,并且在基于网络开放源代码基础上,能够完成项目的要求。
今天给大家分享下,怎样建立属于我们自己的FTP服务器以及FPT客户端,同时非常非常感谢这些开源软件及其作者为IT行业做出的贡献,最大程度上至少解放了我们这些IT码农。
且看正文。
本文主要内容:1、FTP服务端部署---- 基于Android中SwiFTP开源软件介绍;2、FTP客户端部署--- 基于ftp4j开源jar包的客户端开发;3、使用步骤--- 如何测试我们搭建的FTP可操作性。
本文所涉及到的知识、文档、源代码照旧会在文章末尾列出。
欢迎大家一起学习。
一、 FTP服务端部署SwiFTP开源软件是为Android系统开发,也就是说我们可以将其源代码嵌入到我们的项目中。
当然,对其进行一定改造还是必不可少的。
这儿只是从感官上对SwiFTP的运行效果图进行一下说面,以便帮助大家有初步认识:SwiFTP 资料信息:Google Download 介绍:/p/swiftp/downloads/listGitHub 介绍:https:///ppareit/swiftpAndroid版本SwiFTP截图界面其实很简单,但是从设计角度分析,SwiFTP框架系统还是值得我们研究的,当然如果你想改造成属于自己的FTP服务器(一般就是改改用户名、密码、PWD(起始工作目录))等,那更得花时间去钻研了。
二、 FTP客户端部署接下来,重点介绍我们的主角ftp4j开源jar包,该jar包就是开发我们FTP客户端核心了。
ftp4j官网地址:http://www.sauronsoftware.it/projects/ftp4j/。
对比与AndroidSDK而言,也就是ftp4jSDK了,一切的一切(文档、源代码、示例)都可以在官网查询。
想要了解的同学,至少得保证把首页给整明白吧。
1、ftp4j概要官网描述如下:The ftp4j libraryimplementsa Java full-features FTP client. With ftp4j embedded in yourapplication you can : FTP site (directory listing included), cre ate, delete, transfer files(upload and download) , browse the remoteFTP site (directory listing included), create, delete,rename and move remote directories and files.关于FTP连接主要有如下几种方式:The ftp4j library can connect the remote FTP server:·Througha direct TCP/IPconnection. 一般就是直接连接了。
QT程序FTP服务器12级电子新能源本2班20120553049张恒一、 QT简介QT是一个跨平台的C++图形化用户界面的应用程序开发框架。
它既可以开发GUI程序,也用于开发非GUI程序,比如控制台工具和服务器。
在QT Creator 3.1.0正式发布后,QT实现了对IOS、Android、WP 的全面支持。
二、 FTP服务器FTP是文件传输协议的英文简称,用于Internet上的控制文件的双向传输。
同多数Internet服务器一样,FTP也是分为两部分,即客户端程序与服务器系统。
本次所做出的图形化界面程序为FTP的客户端程序。
三、程序介绍1.UI介绍FTP客户端程序的UI界面是图所示,在UI中主要由连接、上传、下载、退出、返回、FTP地址、用户名、密码等组成,并且在下方留出大窗口用于显示FTP服务器中的文件。
2.程序源代码介绍3.#include "ftp.h"4.#include "ui_ftp.h"5.6.Ftp::Ftp(QWidget *parent)7.: QWidget(parent), ui(new Ui::Ftp), ftpobj(0)8.{9.ui->setupUi(this);10.//ui->lineEdit->setText("");11.//ui->comboBox->addItem("192.168.1.253");12.ui->lineEdit_3->setEchoMode(QLineEdit::Password);13.//ui->treeWidget->setAcceptDrops(true);14.this->setAcceptDrops(true);15.//model = new QDirModel;16.//ui->treeView->setModel(model);17.//ui->treeView->setAcceptDrops(true);18.19.ui->label_2->setText(tr("Please enter the name of an FTP server."));20.ui->lineEdit_2->setText("");21.ui->lineEdit_3->setText("");22.23.ui->treeWidget->setEnabled(false);24.ui->treeWidget->setRootIsDecorated(false);25.//ui->treeWidget->setHeaderLabels(QStringList() <<tr("Name") <<tr("Size")<<tr("Owner") <<tr("Group") <<tr("Time"));26.ui->treeWidget->header()->setStretchLastSection(false);27.28.ui->pushButton_2->setDefault(true);29.ui->pushButton->setEnabled(false);30.ui->radioButton_2->setChecked(true);31.ui->pushButton_3->setEnabled(false);32.progressDialog = new QProgressDialog(this);33.34.connect(ui->checkBox, SIGNAL(clicked()), this, SLOT(enableCheckBox()));35.connect(ui->treeWidget, SIGNAL(itemActivated(QTreeWidgetItem *, int)),36.this, SLOT(processItem(QTreeWidgetItem *, int)));37.connect(ui->treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *)),38.this, SLOT(enableDownloadButton()));39.connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelDownload()));40.connect(ui->pushButton_2, SIGNAL(clicked()), this, SLOT(connectOrDisconnect()));41.connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(cdToParent()));42.connect(ui->pushButton_3, SIGNAL(clicked()), this, SLOT(downloadFile()));43.connect(ui->pushButton_4, SIGNAL(clicked()), this, SLOT(close()));44.connect(ui->pushButton_5, SIGNAL(clicked()), this, SLOT(uploadFile()));45.//红色代码用于设置信号槽,定义了PushButton、PushButton_2、PushButton_3等按钮的使用46.setWindowTitle(tr("FTP"));47.}48.49.Ftp::~Ftp()50.{51.delete ui;52.}53.54.55.QSize Ftp::sizeHint() const56.{57.return QSize(500, 300);58.}59.60.//![0]61.void Ftp::connectOrDisconnect()62.{63.if(!ui->checkBox->isChecked()){64.if(ui->lineEdit_2->text().isEmpty()||ui->lineEdit_3->text().isEmpty())65.{66.QMessageBox::information(this, tr("FTP"),tr("请检查ftp账号信息,用户名和密码都不允许为空。
一个简单的FTP服务器实例目标FTP是网络上共享资源的常用方法,在本章中我们将实现一个简单的FTP服务器。
本章知识点:FTP协议Socket类和TcpListener类名称空间实例功能本实例实现一个简单的FTP服务器,该服务器是一个控制台程序,编译后的可执行文件为,在控制台中键入ftpd后就可启动服务器,若要改变ftp服务器的工作目录,可以键入ftpd –r 后接绝对路径。
服务器的ftp服务端口采用默认的21。
服务器启动后,用户就可从其他任何一台联网计算机进行访问。
下面是应用的一个例子:(服务器所在机器的ip为)用户在自己计算机的控制台中输入ftp 回车后可以看到服务器传过来的欢迎信息,并要求输入登陆账号(图5-1)。
图5-1 登陆ftp输入用户名和密码后(为简化起见我们在程序中省去了验证过程,任何人都可以登陆),用户的控制台如图5-2所示,在服务器上,也出现了该用户的登陆情况(图5-3)。
图5-2 成功登陆图5-3 服务端接下来用户可以使用各种命令进行各种ftp操作,比如列出目录下所有文件和文件夹(ls),下载指定的文件(get),上载文件(put)等等。
下面是客户端(图5-4)和服务端(图5-5)某时刻的运行状态。
图5-4 客户端运行情况图5-5 服务端运行情况编程思路要实现FTP服务器,我们必须对FTP协议有一定的了解,使用符合协议的指令集和网络传输方式,我们将在下一节详细介绍关于FTP协议的基础知识。
另外,我们还采用了TcpListener 和Socket编程技术实现数据传输,所以这也是我们需要掌握的内容。
最后,为了同时给多个用户提供服务,FTP服务器还必须支持多线程。
FTP服务器程序的大框架是这样的:程序运行后,在服务器的某个端口有一个TcpListener 一直在监听用户的请求,当有用户请求服务时,服务器立刻创建一个新的线程处理这个请求,我们称开始了一个新的会话。
在会话中,服务器通过Socket接收用户命令,对命令进行分析后采取相应的操作,并将结果返回。
一直到用户退出这个会话,服务器才销毁这个线程。
服务器和客户端的会话方式有两种,一是被动方式(passive),即服务器在某个特定端口有一个TcpListener在不断监听用户命令;二是主动方式,这种情况下,服务器在该客户端有服务请求时,创建一个套接字和它进行数据传输。
关键技术FTP协议1)概述FTP的目标是提高文件的共享性,提供非直接使用远程计算机,使存储介质对用户透明和可靠高效地传送数据。
图5-6是FTP服务示意图,为了让大家更好的理解,我们先解释一下相关的概念。
(1)字节大小,在FTP中字节大小有两个:逻辑字节大小和用于传输的字节大小。
后者通常是8位,而前者可不一定是多少了。
传输字节不必等于逻辑字节大小,也不必对数据结构进行解释。
(2)控制连接是建立在USER-PIT和SERVER-PI之间用于交换命令与应答的通信链路。
(3)数据连接是传输数据的全双工连接。
传输数据可以发生在服务器DTP和用户DTP 之间也可以发生在两个服务器DTP之间。
(4)DTP:数据传输过程,DTP建立和管理数据连接,可以是主动的也可以是被动的。
(5)EOR代表记录尾。
(6)NTV代表网络虚拟终端。
(7)NVFS代表网络虚拟文件系统。
(8)FTP可以传输非连续的文件,这些文件的一部分称为页。
(9)PI代表协议解释器。
(10)服务器DTP代表一种传输过程,它通常处于“主动”状态,它和侦听端口建立数据连接,它还可以为传输和存储设置参数,并根据PI的指令传输数据。
当然,DTP也可以转入“被动”状态。
(11)服务器FTP进程,它是和用户FTP进程一起工作的,它由PI和DTP组成。
至于用户FTP进程则是由PI,DTP和用户接口组成的。
图5-6 FTP 服务示意图注意:数据连接是双向的,它不用整个时间都存在。
上图中用户PI开始控制连接,控制连接与Telnet协议很象。
在开始阶段,标准FTP命令由用户PI产生并通过控制连接传送到服务器进程。
服务器PI向用户PI返回标准应答。
FTP命令指定数据连接参数和文件系统操作。
用户DTP在特定数据端口侦听,服务器开始数据连接并以指定的参数开始数据传输。
数据端口不必在开始FTP命令的机器上,但用户或用户FTP进程必须确定它在指定的数据端口上侦听。
这个数据连接是全双工的。
在另外一种情况下,用户或许希望在两个主机间传送文件,不是两个本地主机。
用户在两台主机间建立控制连接,然后规划数据连接。
用这种方式,控制信息由用户PI获得,但是数据在服务器DTP之间传送。
图5-7就是一个例子:图5-7协议要求数据传输在处理时打开控制连接。
在完成FTP服务后由用户中止控制连接,而服务器具体操作。
如果在未接收命令时关闭了控制连接,服务器也会关闭数据传输。
数据传输功能数据连接只传输数据,控制连接传送命令和响应。
几个命令是关于在主机间传输数据的,数据传输基本上独立于物理结构的,但是如果在压缩传输模式下流式传输与文件结构有关,文件的属性与表示类型有关。
数据表示与保存数据是在主机间的存储设置间传送的。
因为两个系统的数据存储方式不同,因此需要对它进行转换,在传送文本时会有对ASCII表示的问题,在进行二进制传送的时候,会有不同系统对字节长度规定不同的问题,有的系统是7位,有的系统可能是32位,这也需要进行转换。
需要提供数据表示与传输模型函数,但是FTP提供这方面的功能不多,超过FTP提供功能的那一部分要用户自己实现。
数据表示是由用户指定的表示类型,它可以是隐含的,也可以是用户指定的。
请一定注意:逻辑字节长度与物理字节长度是不同的。
ASCII类型:这是所有FTP必须实现的默认类型,用于传送文本文件,当在主机间使用EBCDIC传送时更方便,则不使用ASCII类型。
发送方将内部表示转换为NVT-ASCII格式,接收方则进行相反的过程接收数据。
根据NVT标准,要在行结束处使用<CRLF>序列。
NVT-ASCII是8位的。
ASCII 和EBCDIC的格式参数在下面讨论。
EBCDIC类型:它是作为ASCII的另一种方法在主机间传送数据的数据类型。
EBCDIC和ASCII很象,仅在类型的功能描述上有一些差别。
行结束符使用很少。
图象类型:在此类型下传送的数据被看作连续的位,发送方将数据打包到8位传输字节中传送。
因为结构的需要要对传送数据进行填充,填充字节全部为0,填充必须在文件结构时使用,而且要标记出以便接收方过滤掉。
它用于传送二进制数据和有效地传送和存储文件,因此所有FTP也必须实现。
本地类型:也可以以十进制指定逻辑字节大小。
如果物理字节大小和逻辑字节大小不同,直接将物理数据打包为逻辑字节,不用什么填充。
接收方根据逻辑字节大小进行和本机的存储特点进行转换。
传输必须是可重复的,也就是说,相同的文件相同的参数,那内容必须是一样的。
数据结构除了有不同的数据类型外,FTP还允许有不同的文件结构,下面是三种文件结构:文件式结构:文件中没有内部结构,文件被看作是二进制流;记录结构:文件是由一系列记录组成的;页结构:文件是由不同的索引页组成的。
如果未使用STRU命令,文件结构是默认值。
文件的结构会影响传输模型,存储和数据表示。
文件本来的属性和保存它的主机有关,不同的机器会以自己的方式保存文件。
在不同主机间传送文件时必须使主机能够识别相互的表示。
有些主机上的文件是面向字节的,有些是面向记录的,在传送时就会出现问题。
那就要在接收方进行内部转换。
在进行转换的时候,需要区别记录的边界,在ASCII中使用<CRLF>,在EBCDIC中使用<NL>作为分隔符。
采用这种实现方法的必须保证转换是可逆的。
文件结构:如果未使用STRU命令,文件结构是默认值。
文件结构中没有默认值,文件被看作是连续的字节串。
记录结构:对于文本文件,记录结构必须是所有FTP实现必须有的。
记录结构文件是由连续的记录构成的。
页结构:文件是非连续时使用页结构。
这种文件称为随机访问文件。
这些文件中有时会的和文件整体或部分相关的信息出现。
在FTP中,文件的一个部分称为页。
建立数据连接传送数据机制包括建立连接选择数据参数。
用户和服务器DTP有默认数据端口。
用户进程默认数据端口和控制连接端口相同。
服务器进程默认数据端口和控制连接端口相邻。
传输字节大小是8位字节。
此字节是实际传输字节,但不代表主机内的数据表示。
被动数据传输进程在数据端口接收数据,FTP请求命令决定数据传输的方向。
服务器在接收到请求以后,将初始化端口的数据连接。
当连接建立后,传输在DTP之间传送,服务器PI对用户PI返回应答。
FTP实现运行一个默认数据端口,用户PI才能改变默认端口。
通过PORT命令可能改变端口,用户可能希望数据在第三方主机上进行其它操作,用户PI需要在两个服务器PI上建立连接。
一个服务器被告知侦听另一服务器的请求。
用户PI通过PORT命令通知另一服务器的数据端口。
最后双方发送相应的传送命令。
通常,服务器负责支持数据连接,初始化并关闭它,除非用户DTP在传输模式下要求关闭连接。
服务器在下面情况下关闭数据连接:服务器结束发送数据,通过EOF要求中止传送;用户发送ABORT命令;用户改变端口;控制连接关闭;发生不可恢复错误。
数据连接管理默认数据连接端口:所有FTP必须支持默认数据连接,只有用户PI能够初始化非默认端口的使用。
确定非默认数据端口:用户PI可以使用PORT命令指定非默认端口,它要求服务器方以PASV确定非默认数据端口。
连接是由双方地址确定的,因此改变一方地址就改变了连接。
数据连接的重用:在使用流式数据传输模型时,文件结束通过关闭连接指示。
如果要传送多个文件时就会出麻烦,解决的方法有两个,一个是确定非默认端口,另一个是使用另一种传输模式。
就传输模式而言,流传输模式是不安全的,因此无法确定连接是暂时还是永久关闭。
其它传输模式不通过关闭连接表示文件结构,它们可以通过FTP命令决定传送结构。
因此使用这些传输模式可以在保持连接的情况下传送多个文件。
传输模式有三种传输模式:一种将数据格式化并考虑重新开始过程;一种压缩数据;一种是不经过处理(少量处理)传送。
所有数据传输必须以一个EOF结束,它可以显式给出,也可以通过关闭连接隐式给出。
对于记录文件,所有EOR是显式的,包括最后一个记录。
对于以页结构传送的文件,使用“最后一页”表示结束。
从这里开始,下文中我们提到的字节指的是“传输字节”。
为了进行标准化传送,传送主机必须把行结束或记录结束的内部表示转化为传输模式和文件结构指定的形式传送,接收方则进行相反的工作。
IBM大型机的记录计数域可能不能为其它主机识别,所以记录结束标记在流模式下以双字节控制码传送,在块或压缩模式下以标记位传送。