FTP文件传输文档格式.docx
《FTP文件传输文档格式.docx》由会员分享,可在线阅读,更多相关《FTP文件传输文档格式.docx(23页珍藏版)》请在冰豆网上搜索。
2.1设计的内容
利用计算机具备Windows环境中套接字socket的编程接口功能,可为用户提供全网范围的进程通信功能。
学会利用已有网络环境设计并实现简单应用层协议,掌握TCP/IP网络应用程序基本的设计方法和实现技巧。
用C++语言实现一个在相同网络环境下的两个不相同的程序如何实现数据上传和下载(实现不同计算机之间的文件传送)。
2.2设计要求
(1)将本地计算机上的一个或多个文件传送到远程计算机上(上传),或从远程计算机上获取一个或多个文件(下载)。
传送文件实质上是将文件进行复制,然后上传到远程计算机上,或者是下载到本地计算机上,对源文件不产生影响。
(2)能够传送多种类型,多种结构,多种格式的文件。
(文本文件,二进制文件,图像文件,声音文件,数据压缩文件)。
此外,还可以选择文件的格式控制以及文件传送的模式等。
用户可以根据通信双方所用的系统及要传送的文件确定在文件传输时选择哪一种文件结构。
(3)提供对本地计算机和远程计算机的目录操作功能。
3课程设计的相关技术
3.1实现软件
操作系统:
windows7(windowsNT以上版本皆可)
编程环境:
VC++6.0
编程语言:
C++
测试环境:
MS-DOS
3.2TCP/IP协议技术
在T
C
P
/
I
P协议族中,有两个互不相同的传输协议:
T
P(传输控制协议)和U
D
P(用户数据报协议)。
P为两台主机提供高可靠性的数据通信。
它所做的工作包括把应用程序交给它的数据分成合适的小块交给下面的网络层,确认接收到的分组,设置发送最后确认分组的超时时钟等。
由于运输层提供了高可靠性的端到端的通信,因此应用层可以忽略所有这些细节。
而另一方面,
U
P则为应用层提供一种非常简单的服务。
它只是把称作数据报的分组从一台主机发送到另一台主机,但并不保证该数据报能到达另一端。
任何必需的可靠性必须由应用层来提供。
3.3TCP/IP协议与Winsock网络编程接口
Winsock规范不是一种网络协议,而是一套开放的、支持多种协议的Windows写的网络编程接口。
Winsock可以访问很多种网络协议,可以把它当作一种协议的封装。
现在的Winsock已经基本上实现了与协议无关,可以使用Winsock来调用协议的功能
3.4WinsockAPI的使用
下面给出了使用Winsock进行编程时涉及的主要函数:
WSAStartup函数、WSACleanup函数、socket函数、closesocket函数、send函数、recv函数、bind函数、listen函数、accept函数、connect函数
4课程设计过程
4.1设计思路
使用Socket进行Client/Server程序设计的一般连接过程是这样的:
Server端Listen(监听)某个端口是否有连接请求,Client端向Server端发出Coonnect(连接)请求,Server端向Client端发回Accept(接受)信息,一个连接就建立起来了。
Server端和Client端都可以通过send,put,dir等方法与对方通信.
1.客户端指定要索取服务器端的哪个文件夹的内容,即在客户端将服务器端某个文件夹的路径发送给服务器端。
2.服务器端解析这个字符串,遍历整个文件夹,将文件夹中的文件逐个传回到客户端。
3.客户端逐个接收服务器端传来的文件,安放到指定的目录下。
4.2设计方案
1.服务器端调用socket的accept()方法,等待客户端联接。
2.客户端发送需要从服务端获得的文件夹路径给服务器端。
3.服务器端根据客户端发来的路径遍历整个路径下的文件及文件夹,并将需要传送到文件记录全路径记录到一个String类型的数组中,并将文件的个数发送给客户端。
4.客户端接收服务器端发来的文件个数,并向服务器端发送关闭联接请求,并关闭客户端连接。
5.服务器端收取关闭连接请求,将socket关闭,进入传输文件循环中。
6.服务器端调用socket的accept()方法,等待客户端联接。
7.客户端根据刚才取得的要传输的文件数,进行循环获取文件,记得每次取完文件要关闭socket连接,这样就不会将多个文件写入到同一个文件中。
4.3系统的基本功能
1.get:
取远方的一个文件
2.put:
传给远方一个文件
3.pwd:
显示远主当前目录
4.dir:
列出远方当前目录
5.cd:
改变远方当前目录
6.?
:
显示你提供的命令
7.quit:
退出返回
4.4客户端的主要工作流程
图4-1客户端的主要工作流程
(1)帮助显示客户端主操作菜单
voidhelp()
{
cout<
<
"
欢迎进入迷你FTP帮助菜单"
endl
<
*********************"
*1.get....................下载(接受)文件*"
*get的用法:
get文件名*"
*2.put....................上传(发送)文件*"
endl
*put的用法:
put文件名*"
*3.pwd..........显示当前文件夹的绝对路径*"
*4.dir............显示远方当前目录的文件*"
*5.cd.............改变远方当前目录和路径*"
*cd的用法(进入下级目录):
cd路径名*"
*cd的用法(进入上级目录):
cd..*"
*6.?
或者help................进入帮助菜单*"
*7.quit..........................退出FTP*"
endl;
}
(2)各种处理命令代码
voidlist(SOCKETsockfd)
{
intnRead;
while(true)
{
nRead=recv(sockclient,rbuff,1024,0);
//recv函数通过sockclient套接口接受数据存入rbuff缓//冲区,返回接受到的字节数
if(nRead==SOCKET_ERROR)
printf("
readresponseerror!
\n"
);
exit
(1);
}
if(nRead==0)//数据读取结束
break;
//显示数据
rbuff[nRead]='
\0'
;
%s"
rbuff);
intSendFile(SOCKETdatatcps,FILE*file)//发送文件,处理put命令
sendingfiledata.."
for(;
)
//从文件中循环读取数据并发送客户端
intr=fread(sbuff,1,1024,file);
//fread函数从file文件读取1个1024长度的数据到sbuff,返//回成功读取的元素个数
if(send(datatcps,sbuff,r,0)==SOCKET_ERROR)
losttheconnectiontoclient!
closesocket(datatcps);
return0;
if(r<
1024)//文件传送结束
done\n"
return1;
DWORDStartSock()//启动winsock
{WSADATAWSAData;
chara[20];
memset(a,0,20);
if(WSAStartup(MAKEWORD(2,2),&
WSAData)!
=0)//加载winsock版本
{printf("
sockinitfail!
return(-1);
if(strncmp(InputIP,a,20)==0){
printf("
请输入连接的主机IP:
scanf("
&
InputIP);
//设置地址结构
ServerAddr.sin_family=AF_INET;
//AF_INET表示使用IP地址族
ServerAddr.sin_addr.s_addr=inet_addr(InputIP);
//指定服务器IP
ServerAddr.sin_port=htons(RECV_PORT);
//设置端口号
return
(1);
//创建套接字
DWORDCreateSocket()
sockclient=socket(AF_INET,SOCK_STREAM,0);
//当socket函数成功调用时返回一个新的SOCKET(SocketDescriptor)
if(sockclient==SOCKET_ERROR)
{printf("
sockclientcreatefail!
\n"
WSACleanup();
return(-1);
return
(1);
DWORDCallServer()//发送连接请求
CreateSocket();
if(connect(sockclient,(structsockaddr*)&
ServerAddr,sizeof(ServerAddr))==SOCKET_ERROR)//connect函数创建与指定外部端口的//连接
printf("
Connectfail\n"
memset(InputIP,0,20);
return(-1);
DWORDTCPSend(chardata[])//发送命令
intlength;
length=send(sockclient,data,strlen(data),0);
//send函数通过sockclient接口发送data里面的//数据,发送成功返回发送的字节数
if(length<
=0)
senddataerror!
closesocket(sockclient);
WSACleanup();
(3)主函数代码
intmain()
{charmessge1[10];
//定义输入要处理的文件名
charmessge2[20];
charorder[30];
//输入的命令
order[0]='
charbuff[80];
//用以存储经过字串格式化的order
FILE*fd;
//File协议主要用于访问本地计算机中的文件,fd指针指向要访问的目标文件
FILE*fd2;
intcount;
intsin_size=sizeof(ServerAddr);
StartSock();
if(CallServer()==-1)returnmain();
//发送连接请求失败,返回主函数
\n请输入命令(输入?
或help进入帮助菜单):
memset(buff,0,80);
//清空数组
memset(messge2,0,20);
memset(order,0,30);
memset(messge1,0,10);
memset(rbuff,0,1024);
memset(sbuff,0,1024);
scanf("
messge1);
if(strncmp(messge1,"
get"
3)==0)
messge2);
put"
cd"
2)==0)
scanf("
strcat(order,messge1);
//把messge1加在order的末尾
strcat(order,"
"
//命令中间的空格
strcat(order,messge2);
//把messge2加在order的末尾
sprintf(buff,order);
//把调整格式的order存入buff
//help和?
if(strncmp(messge1,"
help"
4)==0){
help();
?
1)==0){
quit"
欢迎再次进入迷你FTP,谢谢使用!
closesocket(sockclient);
return0;
}
TCPSend(buff);
//发送buff里面的数据
recv(sockclient,rbuff,1024,0);
printf(rbuff);
if(strncmp(rbuff,"
{
fd=fopen(messge2,"
wb"
//使用二进制方式,打开文件,wb只写打开或新建一//个二进制文件;
只允许写数据。
if(fd==NULL)
{
openfile%sforweitefailed!
messge2);
}
while((count=recv(sockclient,rbuff,1024,0))>
0){
fwrite(rbuff,sizeof(rbuff),count,fd);
}//把count个数据长度为size0f()的数据从//rbuff输入到fd指向的目标文件
fclose(fd);
//关闭文件
}//get
strcpy(filename,rbuff+9);
fd2=fopen(filename,"
rb"
//rb读写打开一个二进制文件,只允许读写数据。
if(fd2){
if(!
SendFile(sockclient,fd2)){
sendfailed!
return0;
fclose(fd2);
}//关闭文件
else//打开文件失败
strcpy(sbuff,"
can'
topenfile!
if(send(sockclient,sbuff,1024,0))
}
}//put
dir"
list(sockclient);
//列出接受到的列表内容
}//dir
pwd"
//列出接受到的内容--绝对路径
2)==0){
}//cd
closesocket(sockclient);
//关闭连接
WSACleanup();
//释放Winsock
returnmain();
}//main
客户端:
#include"
Winsock.h"
windows.h"
stdio.h"
time.h"
#include<
iostream.h>
#defineRECV_PORT3312
#defineSEND_PORT4302
#pragmacomment(lib,"
wsock32.lib"
SOCKETsockclient;
charfilename[20];
//文件名
sockaddr_inServerAddr;
//服务器地址
charrbuff[1024];
//接收缓冲区
charsbuff[1024];
//发送缓冲区
charInputIP[20];
//存储输入的服务器IP
//处理help命令
//处理dir命令
//当socket