计算机网络课程设1ftp_第1页
计算机网络课程设1ftp_第2页
计算机网络课程设1ftp_第3页
计算机网络课程设1ftp_第4页
计算机网络课程设1ftp_第5页
已阅读5页,还剩22页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、成绩 中国农业大学课程论文(2008-2009学年 春季 学期)课程名称:计算机网络课程设计 任课教师: 杨 璐 班级: 学号: 姓名: 计算机网络课程设计课程设计名称:ftp 客户端软件课程设计目的:1. 通过ftp客户端软件加深对网络传输的理解。2. 了解网络传输的实现方法3. 学习ftp协议4. 通过ftp程序的编写,了解协议在网络中不可替代的作用课程设计要求:客户端程序具有文件列表、下载文件、上传文件等常用功能。因为ftp协议比较复杂,为了简单起见,客户端只实现ftp客户端协议的一个子集。具有以下几个功能:l l连接到指定的ftp服务器;l l断开和主机的连接;l l进入子目录;l l

2、退出子目录;l l列出服务器当前目录下的所有文件l l从服务器下载指定的文件到本地(可以同时指定多个文件连续下载)l l从本地上传指定的文件到服务器用户界面应该能够为程序输入下面的信息:l l服务器主机名l l用户名、口令l l数据的传送类型l l要进入的服务器目录l l要下载的远程文件名 l l要上载的本地文件名和远程文件名 同时,界面也为用户输出以下的信息:l lftp服务器上的文件和目录列表l l从服务器返回的应答课程设计软件环境:操作系统:windows xp sp3使用语言:c+使用平台:vs2005使用库:lib-ws2_32,winsock.h,fstream,iostream,

3、errno.h,time.h,string,windows.h课程设计与调试的硬件环境:cpu:p core2 7200内存:2g硬盘空间:250g网卡:10/100m/1000m自适应网卡课程设计原理:1.简介ftp 文件传输协议,提供的是文件传输服务,c/s的方式进行网络访问,端口号一般为21。支持密名访问的ftp都包含一个anonymous用户,使用anonymous登陆后只需输入e-mail即可登录。用户登录后即可进行文件操作,本次课程设计我采用的是命令行方式的操作界面。对文件的操作需要使用指定命令(如列目录使用list)。根据命令性质的不同对两类命令进行分析1) 简单的无数据传输方式

4、:以cwd为例:client-setcommand(cwd ,direct);命令格式规范化,例如要进入根目录下的tools目录就可使命令规范化为”cwd/toolsrn”(其中代表一个空格)。请注意这里的字符串一个字符都不能差,更详细的说明参见rfc959文档,内有详细说明。client-sendcommand();sendcommand()即为发送规范化的命令。client-receivecommand();接收应答信息并分离应答码。2) 复杂的有数据传输方式:带有数据传输的文件需要建立数据套接字来传输,建立数据套接字的方式有两种,主动模式,被动模式。简单的介绍下这两种模式:a. 主动模式

5、:主动模式是客户端发送数据连接请求,并告知服务器端已开放的正在监听的端口,由服务器发送连接请求,建立连接。b. 被动模式:被动模式是发送被动连接模式命令,服务器由应答码返回可用的ip与端口信息,通过对应答码的分析找到端口号,用客户端连接正在监听的服务器端口。由于主动模式的局限性,即在有nat转换时无法将信息送至正确的位置,因为经过nat技术转换的端口号代表的是一台计算机的内网编号,而不是计算机网络端口的端口号,所以无法正确送达。也因此本程序采用被动模式。当数据链路建立完成后,数据链路需要进行初始化,数据链路有两种常用的模式,ascii方式和二进制方式,下面介绍下这两种传输方式:a. ascii

6、方式:ascii方式传输数据时,数据以一个字符一个字符为单位传输,这种方式一般使用在文本文件等一些使用ascii码来储存信息的文件传输中ascii方式同样用于文件目录列表的传输。使用ascii方式传输二进制文件,例如可执行文件,图片文件,动画文件,等等,会使文件损坏。b. 二进制方式:二进制文件传输数据时,数据以比特为单位传输,到达客户端后,由操作系统将其合并转换。使用2进制可以传输绝大多数的文件,但是二进制方式也有其不可避免的局限性,二进制传输文件要求服务器和客户端使用相同类型的操作系统,如果不同类型下载的文件无法使用,但可以使用二进制方式传输到另一台拥有相同操作系统的机器上,文件可以使用。

7、所以二进制方式传输同样不适用于网络传输。确定了传输类型后,就可以创建套接字,格式化命令,发送命令,并接受信息和应答码与两不同的socket上。char* filename = new char512;memset(filename,null,512);/*pasv方式传输*/client-setcommand(pasv);client-sendcommand();client-receivecommand();/*分析应答码取端口号*/client-getport();/*设置传输类型初始化数据套接字*/client-setcommand(type ,i);client-sendcommand

8、();client-receivecommand();client-interlizedatasocket();coutfilename;memset(temp,null,512);/*格式化路径信息direct*/memcpy(temp,direct,strlen(direct);memcpy(temp+strlen(direct),/,1);memcpy(temp+strlen(direct)+strlen(/),filename,strlen(filename);/*格式化命令retr*/client-setcommand(retr ,temp);client-sendcommand()

9、;client-receivecommand();/*接收数据信息和应答信息*/client-receivedata(filename);client-receivecommand();/*清理内存*/delete filename;其他命令只需对以上两种类型命令的模型稍加改动即可详情请参照以上注释阅览源程序。下面对我封装的这个ftp类进行剖析。2.封装类分析ftp客户端主要有一个类ftpclient来完成封装,具体的成员包括成员函数:private:ftpclient:getcode前提条件:cmdbuffer中尚存有pasv命令的应答信息用于获取cmdbuffer中的端口信息并进行转换ft

10、pclient:interlizedatasocket 初始化控制连接public:ftpclient:ftpclientftpclient的析构函数,包含释放缓冲区的任务。ftpclient:ftpclient ftpclient的构造函数,初始化缓冲区,调用interlizesocket()函数初始化控制连接。ftpclient:receivecommand 接收控制信息应答码ftpclient:receivedata接收数据链路信息ftpclient:receivelist接收列表信息ftpclient:sendcommand发送命令ftpclient:senddata发送数据用于上载f

11、tpclient:setcommand ftpclient:setcommandsetcommand分别对应单指令和双指令代码进行重载,将命令格式化并储存在cmdbuffer中。成员变量:ftpclient:buffer 数据缓冲ftpclient:cmdbuffer 应答信息缓冲ftpclient:command 命令字符串缓冲ftpclient:ipaddressip地址缓冲 ftpclient:listbuffer 列表信息缓冲ftpclient:port 控制端口信息ftpclient:portfordata数据端口信息ftpclient:serveraddr 用于建立控制套接字参数,

12、系统库参数ftpclient:serveraddrdata用于建立数据套接字参数,系统库参数ftpclient:socketcontrol 控制连接套接字ftpclient:socketdata数据连接套接字 ftpclient:wsd系统库参数,代表wsadata。3主程序流程图:start输入服务器ip,port连接服务器end输入用户名密码身份验证输入命令判断命令执行对应模块完成命令listcwddeleretrstormkdrmdquit从这次课设中我学到了什么:l 整体的学习ftp掌握ftp的工作原理,与协议工作时的详细步骤l 建立了以c+为基础的网络编程底层模型,学会了使用sock

13、et编程并发送信息l 深入的体会了一次字符串的编辑修改编程发现其实完全掌握字符串的操作,是很复杂的一件事l 采用了面向对象的思想来编程序,加强了对知识的理解。l 全程使用指针、数组、结构体等底层数据操纵方法,虽然错误层出不穷,但加深了对指针的理解,并且深感一句箴言的意义:“看你c用得好不好,就是看你指针用得好不好”。l 使用了标准的代码书写规范,变量命名采用骆驼命名法,书写规范采取标准c+书写规范l 学习编写注释,了解到注释的重要作用,可惜写的还不是很全:p。l 加强了代码重用性,此段程序我编过两次,第一次编写结束后发现许多代码重用性非常高,例如指令内容格式化,接收并显示应答信息返回应答码,数

14、据连接的建立,第二次编写时尽量提高了代码重用性,但做的还是不够好。l 对于返回值的处理趋向于使用int而不使用void,通过int返回1,0代表成功或不成功。l 防止内存泄漏的问题,程序中的num*无法删除,是我对内存泄漏的重要有了更深的理解。l 解决了当下载信息大于缓冲区时应当怎么做,l 查明了为何通过2下载的文件中的0a,变成了0d0a.在老师的帮助下:)。l 了解了不同操作系统在网络中传输互联的困难。l 学会了文件读写,并能区分文件读写时不同参数的不同意义l 最重要的事,是我学习如何去自学,鉴于老师给的资料并不完整,访遍baidu,google,csdn,兰森林,

15、等知名网站查找答案,解决问题,我觉得这是一次宝贵的机会。l 以上的问题,每解决一项,都要花费我好几个小时的时间,有的问题甚至3天都没能解决,有的问题可能我还没能发现,但我觉得其实快乐就在这里,每当解决一个困扰了好几天的问题的时候,那种兴奋正是给我坚持下来的动力。最后附上程序代码ftpclient.h#pragma comment(lib,ws2_32)#include#include#include#include#include#include#include#includeusing namespace std;class ftpclientprivate:wsadata wsd;stri

16、ng ipaddress;int port;char *buffer;char *cmdbuffer;char *listbuffer;char *command;int portfordata;socket socketdata;socket socketcontrol;sockaddr_in serveraddrdata;sockaddr_in serveraddr;/*返回cmdbuffer中有的应答码cmdbuffer必须有返回信息*/int getcode()int code = 100*(cmdbuffer0-0)+10*(cmdbuffer1-0)+(cmdbuffer2-0);

17、return code;/*初始化客户端,连接服务器,成功返回1失败返回0,打印欢迎信息,server返回信息,ip*/int interlizesocket()/建立与socket库绑定wsastartup(makeword(2,2),&wsd);/创建流式socketsocketcontrol = socket(af_inet,sock_stream,ipproto_tcp);/填充本地socket地址serveraddr.sin_family=af_inet;serveraddr.sin_port=htons(port);serveraddr.sin_addr.s_addr=inet_a

18、ddr(ipaddress.c_str();/向ftp服务器发送connect请求connect (socketcontrol, (sockaddr*)&serveraddr, sizeof(serveraddr);/从ftp服务器获得connect应答if (recv(socketcontrol,cmdbuffer,512,0)coutserver:buffer = new char4096;memset (buffer,null,4096);this-cmdbuffer = new char512;memset (cmdbuffer,null,512);this-listbuffer =

19、new char4096;memset (listbuffer,null,4096);this-command = new char512;memset (command,null,512);ipaddress = ip;port = p;coutip:ip:portendl;if(interlizesocket()=1)coutconnect server successful!endl;ftpclient()delete buffer;delete cmdbuffer;delete listbuffer;delete command;colsesocket(socketcontrol);/

20、*privatepart:固定部分如user pass 等userpart:用户输入部分如anonymous direct等标准格式一般为如:user anonymousrn或如pasvrn*/int setcommand(char* privatepart,char* userpart)memset (command,null,strlen(command);memcpy (command,privatepart,strlen(privatepart);memcpy (command+strlen(privatepart),userpart,strlen(userpart);memcpy (

21、command+strlen(privatepart)+strlen(userpart),rn,2);return 1;int setcommand(char* privatepart)memset(command,null,strlen(command);memcpy(command,privatepart,strlen(privatepart);memcpy (command+strlen(privatepart),rn,2);return 1;/*发送command中的命令command中必须有格式化好的命令*/int sendcommand()coutcommandendl;send(

22、socketcontrol,command,strlen(command),0);memset(command,null,strlen(command);return 1;/*从socketcontrol接收信息读入cmdbuffer成功返回代码,失败返回600.*/int receivecommand()memset(cmdbuffer,null,strlen(cmdbuffer);if(recv(socketcontrol,cmdbuffer,512,0)coutserver:cmdbuffer;int temp = getcode();return temp;return 600;/*s

23、ocketdata初始化,取pasv的返回信息,转化为int建立socket,socketdata信息储存在buffer或listbuffer中,用于数据的传输。条件:cmdbuffer中必须储存有pasv返回信息*/int getport()/*端口号分析相关,通过num数组读取3位端口号,通过定位,转换2部分转换为int型端口号。公式x.x.x.x.aaa.bbb:端口号:aaa*512+bbb(网上查得)或将aaabbb转换为十进制相加(原为十六进制)*/char* num = new char3;int flaga = 2;int flagb = 0;int temp;int j =

24、0;int i;int test;for(int i = 0;i0)if (cmdbufferi=0&cmdbufferi=0;j-)numj=null;if (flaga = 1)temp = test *256;i+;j+;else if(flaga = 0)temp += test;portfordata = temp;coutdataport:portfordataendl;return 1;/*socket创建相关*/int interlizedatasocket()/创建流式socketsocketdata = socket(af_inet,sock_stream,ipproto_

25、tcp);/填充本地socket地址serveraddrdata.sin_family=af_inet;serveraddrdata.sin_port=htons(portfordata);serveraddrdata.sin_addr.s_addr=inet_addr(ipaddress.c_str();/向ftp服务器发送connect请求connect (socketdata, (sockaddr*)&serveraddrdata, sizeof(serveraddrdata);return 1;/*接收list列表,返回应答码*/int receivelist()memset(list

26、buffer,null,4096);int r = recv(socketdata,listbuffer,4096,0);coutlistbufferr=0;temp-)if (cmdbuffertemp = ()break;for(temp;temp=cmdlenght;temp+)if (cmdbuffertemp=0)filelenght = filelenght * 10 + (cmdbuffertemp-0);while(1)ofstream outputfile(filename,ios:out|ios:app);memset(buffer,null,4096);int r = r

27、ecv(socketdata,buffer,4096,0);outputfile.write(buffer,r);if (r 0) coutrecv errorendl;outputfile.close();closesocket(socketdata);return 0;if (r = 0) break;closesocket(socketdata);outputfile.close();return 1;/*发送数据从filename中读取数据*/int senddata(char* filename)memset(buffer,null,4096);ifstream inputfile(

28、filename,ios:in|ios:app);inputfile.read(buffer,sizeof(buffer);coutbufferendl;send(socketdata,buffer,sizeof(buffer),0);inputfile.close();closesocket(socketdata);return 1;ftpclient.cpp#pragma comment(lib,ws2_32)#include#include#include#include#include#include#includeftpclient.husing namespace std;#def

29、ine menu welcome to the ftp server,please input the command and enter!such as: list,cwd,retr,stor,dele,rmd,mkdint main()char* direct = new char256;memset(direct,null,256);direct1 = /;int returnnum;char ip15;int port;char test;char *username = new char50;memset(username,null,50);memcpy(username,anony

30、mous,strlen(anonymous);char pwd50;char temp512;char command4;char parameter256;coutip;couttest;if(test=y|test=y)couttemp;port = (temp0 - 0)*10+(temp1 - 0);memset(temp,null,2);else if (test=n|test=n)port = 21;else couterrorendl;/*用户登录模块*/ftpclient* client = new ftpclient(ip,port);couttest;if(test=y|t

31、est=y)coutusername;else if (test=n|test=n)coutusername:anonymousendl;else couterror check input!setcommand(user ,username);coutusernamesendcommand();returnnum = client-receivecommand();if(returnnum = 331)coutpwd;client-setcommand(pass ,pwd);client-sendcommand();returnnum = client-receivecommand();if

32、(returnnum = 230)while(1)coutmenuendl;cout;cincommand;if(strcmp(command,list)=0|strcmp(command,list)=0)/*连接控制,传输控制,命令传输(需使用socketdata连接的命令,如:list)*/client-setcommand(pasv);client-sendcommand();client-receivecommand();client-getport();client-setcommand(type ,a);client-sendcommand();client-receivecomm

33、and();client-interlizedatasocket();client-setcommand(list ,direct);coutdirectsendcommand();client-receivecommand();client-receivelist();client-receivecommand();else if(strcmp(command,cwd)=0|strcmp(command,cwd)=0)memset(direct,null,512);coutplase input the direct of your will(compelity direct):direct

34、;if(memcmp(direct,/,1)!=0)memset(temp,null,512);memcpy(temp,/,strlen(/);memcpy(temp+strlen(/),direct,strlen(direct);memcpy(direct,temp,strlen(temp);client-setcommand(cwd ,direct);client-sendcommand();client-receivecommand();else if(strcmp(command,retr)=0|strcmp(command,retr)=0)char* filename = new c

35、har512;memset(filename,null,512);/*下载模块*/client-setcommand(pasv);client-sendcommand();client-receivecommand();client-getport();client-setcommand(type ,i);client-sendcommand();client-receivecommand();client-interlizedatasocket();coutfilename;memset(temp,null,512);memcpy(temp,direct,strlen(direct);mem

36、cpy(temp+strlen(direct),/,1);memcpy(temp+strlen(direct)+strlen(/),filename,strlen(filename);client-setcommand(retr ,temp);client-sendcommand();client-receivecommand();client-receivedata(filename);client-receivecommand();delete filename;else if(strcmp(command,stor)=0|strcmp(command,stor)=0)char* file

37、name = new char512;memset(filename,null,512);/* 上载模块*/client-setcommand(pasv);client-sendcommand();client-receivecommand();client-getport();client-setcommand(type ,i);client-sendcommand();client-receivecommand();client-interlizedatasocket();coutfilename;client-setcommand(stor ,filename);client-sendcommand();client-receivecommand();client-senddata(filename);client-receivecommand();delete filename;else if(strcmp(command,dele)=0|strcmp(command,dele)=0)char* filename = new char512;memset(filename,null,strlen(filename);coutfilename;client-setcommand(dele ,filename);client-sendcommand();client-

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论