《visualc网络编程案例实战之ftp客户端.pptx》由会员分享,可在线阅读,更多相关《visualc网络编程案例实战之ftp客户端.pptx(51页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第4章 FTP客户端客户端本章将带领大家编写一个简单的FTP客户端程序,实现简单的功能:登录FTP服务器,处理服务器上的文件,如上传、下载,最后安全退出服务器。先弄清楚原理,然后我们再考虑怎样去实现。4.1 FTP工作原理FTP的工作原理跟TCP一样,客户端需要先与服务器连接,等待服务器的应答,最后再建立数据通道。所以,FTP浏览器在和服务器建立连接时也需要经过“三次握手”的过程。这表示客户端与服务器之间的连接是可靠、安全的,这也为数据传输提供了可靠的保证。FTP的工作原理如图4.1所示。图 4.1 FTP工作原理图4.1.1 FTP数据结构进行FTP编程之前,用户首先需要知道FTP有哪些数据
2、结构。由于在某些主机上保存的文件是面向字节的,某些是面向记录的。所以在FTP中,除了有不同的数据类型以外,还有几种不同的文件结构类型。这样做的目的是为了在不同的主机之间传送文件时能够相互识别。二进制结构:文件中没有内部结构,一般被看作二进制流。文件式结构:由许多记录组成的文件。页面结构:由不同的索引页组成文件。注意:一般情况下,如果没有使用FTP命令去设置文件的结构,则默认的结构是文件式结构。4.1.2 FTP数据传输模式在FTP的数据传输中,传输模式将决定文件数据会以什么方式被发送出去。一般情况下,网络传输模式有3种:将数据格式化后传送、压缩后传送、不做任何处理进行传送。当然不论用什么模式进
3、行传送,在数据的结尾处都是以EOF结束。在FTP中定义的传输模式有以下几种。1二进制模式二进制模式就是将发送数据的内容转换为二进制表示后再进行传送。这种传输模式下没有数据结构类型的限制。在二进制结构中,发送方发送完数据后,会在关闭连接时标记EOF。如果是文件结构,EOF被表示为双字节。其中第一个字节为0,而控制信息包含在后一个字节内。本书中如无特别说明,均采用该模式进行传输数据。2文件模式文件模式就是以文件结构的形式进行数据传输。文件结构是指用一些特定标记来描述文件的属性以及内容。一般情况下,文件结构都有自己的信息头,其中包括计数信息和描述信息。信息头大多以结构体的形式出现。计数信息:计数指明
4、了文件结构中的字节总数。描述信息:描述信息是负责对文件结构中的一些数据进行描述。例如,其中的数据校验标记是为了在不同主机间交换特定的数据时,不论本地文件是否发生错误都进行发送。但在发送时发送方需要给出校验码,以确定数据发送到接收方时的完整性、准确性。在文件结构中,既可以用记录结构,也可以用相对应的数据表示。文件的信息头结构如表4.1所示。表4.1 文件的信息头结构描述信息是由字节中的位特定标记值来说明。列举几个特定标记值及其意义,如表4.2所示。文件信息文件信息头计数信息大小数信息大小文件信息文件信息头描述信息大小描述信息大小计数信息占数信息占16位字位字节描述信息占描述信息占8位字位字节表4
5、.2 特定标记值及意义由表4.2可知,描述信息中可能存在多个标记值,所以必须将需要用到的标记都进行设置。标 记 值意意 义64表示文件的表示文件的结束符束符标记EOF32表示文件中有可疑表示文件中有可疑错误16表示具有重表示具有重发标记的文件的文件3压缩模式在这种模式下,需要传送的信息包括一般数据、压缩数据和控制命令。一般数据:以字节的形式进行传送。压缩数据:包括数据副本和数据过滤器。控制命令:用两个转义字符进行传送。注意:此种传输模式请参考其他相关书籍,本书不再进行深入讲解。在FTP数据传输时,发送方必须把数据转换为文件结构指定的形式再传送出去,而接收方则相反。因为进行这样的转换很慢,所以一
6、般在相同的系统中传送文本文件时都采用二进制流表示比较合适。4.1.3 与服务器进行连接FTP客户端需要与服务器连接成功后,才能进行文件数据的传输。当连接时,客户端需要用户指定端口、连接模式等操作。1连接所使用的端口在连接端口的使用上,FTP与HTTP不同。因为FTP在与服务器连接时需要用到两个端口:其中一个端口(FTP的默认端口是21)作为控制连接端口,它主要用于发送命令给服务器以及等待服务器的响应;另一个端口是数据传输端口,端口号为20或者任意有效端口号,用来建立数据传送通道。2连接模式FTP客户端连接服务器的模式有两种:PORT模式和PASV模式。PORT模式:PORT是主动模式。当客户端
7、选择这种模式与服务器进行连接的时候,它需要向服务器提供一个IP地址和一个端口号。PASV模式:PASV是被动模式。当选择这种模式连接时,服务器需要提供给客户端一个IP地址和一个端口号。用户平时从网上一个指定的FTP地址和端口下载文件就是这种模式的一种实际应用,相反则为PORT模式。注意:在本章中如无特别说明,所选用的连接模式均是被动模式。4.1.4 登录验证 在连接FTP服务器成功之后,用户需要发送相关命令或者是数据流到服务器进行身份验证或其他操作。在本章的小节中,给出了一些常用的FTP命令。1登录方式在登录FTP时,登录方式有匿名登录、代理登录或者是通过用户名登录等。各种登录方式的不同在于访
8、问文件的权限(只读、只写或者读写),这也是FTP的一个重要特点。注意:在本章中涉及到的登录方式主要是以用户名登录为主。2验证客户端将用户名和密码以命令的方式发送到服务器进行验证,例如,用户名为“lymlrl”,密码为“123456”的用户在进行验证时,将其转换成命令流:“USER”+lymlrl+“PASS”+123456;这个命令将作为字符串被发送到服务器,这个工作是通过CArchive等类中的函数实现的(具体内容将在4.3节中讲解)。服务器在验证之后会返回结果给客户端。如果返回值的第一个数字为1、2或者是3,则表示返回值正确,否则发生错误。然后提取当前位置的下一条命令值,如果为EROR表示
9、出现用户名或密码错误;为SUSS则表示验证成功。4.1.5 关闭数据连接通常情况下,服务器只负责进行数据连接,并对它进行初始化和关闭。除非客户端在命令控制中主动要求关闭连接时,服务器才会关闭连接。当然服务器也会在以下情况下关闭数据连接。当服务器发送数据结束时,会通过EOF终止传送;客户端发送ABORT命令;客户端改变了端口号;控制连接通道被关闭;传输过程中发生严重错误。但是,在一般情况下客户端与服务器之间的连接都是在数据正常处理完成以后关闭的。4.1.6 FTP常用命令在实际编程中,有些复杂的操作,只是需要客户端发送相关的指令到服务器执行即可。所以,对于用户来说掌握常用的FTP命令是非常重要的
10、。下面列举了一些常用的FTP命令,如表4.3所示。表4.3 常用FTP命令及意义在表4.3中,已经列举了部分常用的FTP命令。通常情况下,客户端通过CArchive类的成员函数WriteString()可以将这些命令以字符串的形式发送到服务器执行。然后,客户端使用CArchive类的成员函数ReadString()来获取服务器返回的数据。关于这两个函数的一些用法将在下一节实例中进行讲解。FTP命令命令意意 义LIST发送当前工作目送当前工作目录下的文件名列表到客下的文件名列表到客户端端PWD显示服示服务器的当前工作目器的当前工作目录名名RETR从服从服务器下器下载一个文件一个文件STOR上上传
11、文本文件到服文本文件到服务器,如果文件存在会被覆盖器,如果文件存在会被覆盖STOU上上传文本文件到服文本文件到服务器,但不会覆盖已器,但不会覆盖已经存在的文件存在的文件STRU设置文件的置文件的结构构MODE指定数据的指定数据的传输模式模式ABORT通知服通知服务器关器关闭连接接4.1.7 数据校验与重发控制FTP是属于TCP/IP簇中的一种具体应用,所以FTP也具有数据重发机制。但在FTP中,数据重发仅用于文件和压缩模式。一般情况下,重发机制都要求发送者在发送数据时加入特定标记来描述数据的重要信息。并且该标记只针对发送者有意义,其内容大多是用来校验数据的完整性。特定标记可以表示任何可以标记的
12、属性或其他信息。如果接收方也支持重发机制,那么接收方系统中将会保存这一特定标记。当系统重新启动或者其他原因造成系统重启,用户均可以根据原来的标记继续传送数据。其实,用户经常用到的断点续传就是很好的一个例子。当接收方收到一段数据后,记下标记,如果传送过程中出现错误,那么发送方将会从这个标记点重新传送数据。4.2 FTP客户端实例接下来我将带领大家一步步完成FTP客户端的编写,毕竟这才是本章最主要部分。4.2.1 创建工程创建基于对话框的应用程序,命名为FTP_client。程序的界面设计及各个关键控件的ID如图4.2所示。图4.2 客户端程序界面及控件ID部分控件关联的变量如图4.3所示。图4.
13、3 部分控件ID及关联的变量为类CFTP_clientDlg定义两个公有的成员变量,如下:4.2.2 连接和登陆验证用户需要通过客户端来连接FTP服务器,然后登录。这样才能对FTP服务器上的文件进行操作。1.实现连接和登陆验证添加“连接服务器”按钮的消息响应函数OnConnect(),代码如下:用户使用该软件时首先应该填写主机、端口、用户名和密码信息,便于与指定的服务器连接,然后完成登陆验证。连接和登陆的验证过程如图4.4所示。图4.4 连接和登陆验证过程示意图响应函数OnConnect()用到了MFC中的类CSocket的对象sock_client,它的大部分功能继承自类CAsyncSock
14、et,实际上代码中sock_client对象调用的函数都继承自CAsyncSocket。功能实现过程:(1)调用成员函数Create()创建了socket,用于向服务器发送命令和接收来自FTP服务器的响应。(2)调用成员函数Connect()连接FTP服务器,需要向函数提供FTP服务器的IP和端口号。(3)调用我们自己将要封装的2个函数MySockSend()和MySockRecv(),发送用户名和密码,并接收来自FTP服务器的响应。(4)禁用相关的文本编辑框和按钮,防止用户再做修改困扰我们的程序。2.封装发送命令函数为类CFTP_clientDlg添加公有成员函数MySockSend(),用
15、于发送命令信息,代码如下:函数MySockSend()以发送的命令为参数,功能包括:调用类CSocket的成员函数Send()发送命令;添加命令到ListBox上,方便用户知道程序做了什么,这里用到了类CListBox的成员函数AddString()。3.封装接收响应函数为类CFTP_clientDlg添加公有成员函数MySockRecv(),用于接收来自FTP服务器的响应消息,代码如下:函数MySockRecv()没有参数,功能包括:调用类CSocket的成员函数Receive()接收来自FTP服务器的响应消息;添加响应消息到ListBox上,方便用户知道服务器的应答。程序连接FTP服务器的
16、运行效果如图4.5所示。图4.5 程序连接FTP服务器的运行效果4.2.3 更新文件列表客户端可以发送命令LIST到FTP服务器,服务器会告知客户端:用户的根目录下到底有哪些文件。文件的信息是通过客户端与服务器端建立的数据连接传送的,传完连接会被关闭。1.让服务器进入被动模式(PASV)在主动模式(PORT)下,FTP 的客户端只是告诉服务器自己的端口号,让服务器来连接客户端指定的端口。对于客户端的防火墙来说,这是从外部到内部的连接,可能会被阻塞。为了解决服务器发起到客户的连接问题,有了另一种 FTP 连接方式,即被动方式。命令连接和数据连接都由客户端发起,这样就解决了从服务器到客户端的数据端
17、口的连接被防火墙过滤的问题。下面我们要在类CFTP_clientDlg中添加公有的成员函数Pasv_mode(),用来实现这一功能,函数封装如下:虽然代码看起来有些多(至少我这么认为),但客户端和服务器端的交互还是很简单的,如图4.6所示。图4.6 客户端和服务器端的交互但函数Pasv_mode()实现的功能还是比较简单的:(1)发送命令让FTP服务器进入被动模式(PASV),服务器会新开一个端口号等待客户端的连接。(2)从服务器返回的响应中取出数据,然后计算端口号。(3)客户端创建一个临时的套接字sock_temp连接服务器新开的端口。2.更新列表添加“更新文件列表”按钮的消息响应函数OnU
18、pdate(),代码如下:响应函数OnUpdate()功能的实现过程:调用我们之前封装的函数Pasv_mode使服务器进入被动模式,再向服务器发送LIST命令,用新建立的连接接收文件信息数据(封装在了函数Parse_list()中),接收到的数据信息如图4.7所示。最后关闭数据连接。图4.7 由数据连接接收的文件信息在类CFTP_clientDlg中添加公有的成员函数Parse_list(),实现解析文件信息,获取文件列表的功能,代码如下:函数Parse_list()功能的实现过程:用临时的数据连接sock_temp接收数据(文件信息),从数据中筛选出文件名,添加到文件名列表中。文件信息的每一
19、行由“rn”结束,每行的各个信息由空格“”连接,文件名放在最后。我是依据以上特征遍历信息查找到文件名的。程序窗口“更新文件列表”按钮的运行效果如图4.8所示。图4.8 单击“更新文件列表”按钮的运行效果4.2.4 文件上传添加“文件上传”按钮的消息响应函数OnStorefile(),实现选择文件上传到服务器的功能,代码如下:用户单击“文件上传”按钮后,会首先弹出文件“打开”对话框,用户选择要上传的文件,单击确定,由客户端完成与服务器接下来的交互如图4.9所示(假定用户选择了know1.txt文件)。图4.9 客户端上传文件时与服务器的交互过程响应函数OnStorefile()的实现过程:(1)
20、弹出“打开”文件对话框,供用户从中选择需要上传的文件。(2)使FTP服务器进入被动模式,建立数据连接(在Pasv_mode()函数中完成),向服务器发送上传文件的命令(STOR 文件名).(3)客户端打开文件读取其内容,依靠数据连接传输内容,文件传输结束时关闭文件和连接,弹出“上传完毕”的提示信息对话框。单击程序“文件上传”按钮的运行效果如图4.10所示。图4.10 程序“文件上传”按钮的运行效果4.2.5 文件下载用户可以通过两种操作来实现“文件下载”的功能:双击服务器文件列表中的文件名;单击服务器文件列表中的文件名,再单击“文件下载”按钮。为文件名列表框添加鼠标双击事件的响应函数OnDbl
21、clkListfile(),实现相应文件下载的功能,代码如下:用户通过两种方式下载文件,都会弹出文件“另存为”对话框,选择好保存位置后,客户端开始下载FTP服务器上的相应文件,客户端与FTP服务器的交互如图4.11所示(假定要下载的文件是welcome.txt)。图4.11 客户端上传文件时与服务器的交互过程响应函数OnDblclkListfile()的实现过程:(1)使FTP服务器进入被动模式,建立数据连接(在Pasv_mode()函数中完成),获取用户选择下载的文件名,向服务器发送下载文件的命令(RETR 文件名)。(2)调用函数fileStore()弹出“另存为”文件对话框,供用户从中选
22、择文件存放的位置。(3)弹出“文件已保存”的提示信息对话框。选择要下载的文件名,单击程序“文件下载”按钮的运行效果如图4.12所示。图4.12 程序“文件下载”按钮的运行效果为类CFTP_clientDlg添加公有成员函数fileStore(),实现保存文件的功能,代码如下:函数fileStore()以要保存的文件名filename作为参数,功能的实现过程:弹出文件“另存为”对话框,选择好保存位置后,会在当前路径下创建该文件,最后关闭文件和数据连接。提示:读者也许已经发现,我们每次的数据传输都需要使用PASV获取新的端口号,建立新的连接,在接收完数据后需要关闭数据连接。这可以当做与FTP服务器
23、交互的一种“规则”。4.2.6 安全退出添加“关闭连接”按钮的消息响应函数OnQuit(),代码如下:客户端要与服务器端断开连接时,需要发送命令QUIT,FTP服务器会返回响应,交互如图4.13所示。图4.13 断开连接的交互过程关闭按钮的运行效果比较简单,为了完整,我还是将他的运行效果展示出来,如图4.14所示。图4.14 程序“关闭连接”按钮的运行效果综上所述,多次添加成员函数的类CFTP_clientDlg的定义如下:4.3 小 结本章首先带领大家了解了FTP的工作原理,然后据此设计实现了一个能与FTP服务器交互的客户端程序。读者要重点掌握FTP的工作原理,毕竟软件的设计与实现是建立在他之上的。相信了解了原理的读者肯定能设计和实现更好的程序。