您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 项目/工程管理 > c语言小项目:用Socket编程实现FTP
题目:用Socket编程实现FTP用Socket编程实现FTP一、目的和意义(功能描述)学习了TCP/IP这门课,接触最多的是用WindowsSockets编程来实现一些功能。因此在熟悉了WindowsSockets的编程思想后,我觉的会很容易实现一个FTP的客户应用程序。它能够登录FTP服务器,并从服务器端下载数据。数据同步传输系统既适合于服务器端的目录遍历,又适合客户端对服务端的上传文件和下载文件。运用Socket(套接字)接口和使用FTP(文件传输协议)来实现客户端和服务器端之间信息的交互。该数据传输平台分为两个模块:服务器端模块和客户端模块。客户服务器程序通过对编程语言VisualC++6.0中的调用来实现利用TCP/IP协议中的FTP协议和封装在NMFTP内的Socket接口进行客户端与服务器连接,并完成数据同步工作,例如:上传、下载、浏览、查询、对服务器目录与文件的管理以及执行远程命令等。服务器端程序则持续的监听网络。当接受到客户端的Socket,服务器程序提供相应的服务。网络通信模块使用POP3控件来实现客户端与服务器的信息交流。函数功能和流程如下:(1)首先创建一个CFtpclient的类的实例。(2)用LogOnToServer()函数登录到指定的FTP服务器,允许非匿名用户和匿名两种登录方式,默认的端口为21.(3)使用MoveFile()函数来上传下载数据文件,其中第一个参数是本地地址,第二个参数是远程地址,文件传输选用二进制模式。注意,文件传输使用同步模式。(4)可以使用Ftpcommand()函数来执行FTP指令,包括常用的“CWD/home/mydir”来改变远程服务器上的地址,并处理服务器返回的应答。当这种方式不适用的时候,还可以使用WriteStr()函数和ReadStr()函数向远程服务器发送指令,并自己解释返回的应答。(5)当所有的文件传输完成之后,使用LogOffServer函数来断开与远程服务器的连接。二、基本原理它的原理也相当的简单,客户端程序实现一个命令行或图形界面,将用户命令翻译成FTP命令,并发送给服务器端程序。服务器端程序响应FTP命令,并将操作成功与否的信息以FTP响应形式返回给客户端程序。双方遵守FTP协议,完成文件传输服务。就是利用MFC提供的CSocket类和CAsyncsocket类实现一个客户/服务器模式的数据通信模式,使用CSocketFile类和CArchive类来读写数据。它很好的实现了所有的功能,提供了简洁实用的接口。三、详细设计WindowsSockets实现,一个WindowsSockets实现是指实现了WindowsSockets规范所描述的全部功能的一套软件。一般通过DLL文件来实现。Windows环境下进行网络程序设计的最基本方法是应用WindowsSockets来实现,通过使用MFC提供的WindowsSockets类,能够很好的完成FTP的功能。连接管理:数据连接有3大用途:(1)从客户向服务器发送一个文件(2)从服务器向客户发送一个文件(3)从服务器向客户发送文件或目录列表。每一个数据连接对传输一个文件或目录序列都要建立一个新的连接。(1)客户发出命令要求建立数据连接(2)客户在客户主机上未数据连接选择一个固定的端口号(3)客户使用PORT命令从控制连接上把端口号发给服务器。(4)服务器在控制连接上接收端口号,并向客户端主机上的端口发出主动打开,服务器的数据连接使用端口21。基本套接字为了更好说明套接字编程原理,给出几个基本的套接字,在以后的篇幅中会给出更详细的使用说明。1、创建套接字——socket()功能:使用前创建一个新的套接字格式:SOCKETPASCALFARsocket(intaf,inttype,intprocotol);参数:af:通信发生的区域type:要建立的套接字类型procotol:使用的特定协议2、指定本地地址——bind()功能:将套接字地址与所创建的套接字号联系起来。格式:intPASCALFARbind(SOCKETs,conststructsockaddrFAR*name,intnamelen);参数:s:是由socket()调用返回的并且未作连接的套接字描述符(套接字号)。其它:没有错误,bind()返回0,否则SOCKET_ERROR地址结构说明:structsockaddr_in{shortsin_family;//AF_INETu_shortsin_port;//16位端口号,网络字节顺序structin_addrsin_addr;//32位IP地址,网络字节顺序charsin_zero[8];//保留}3、建立套接字连接——connect()和accept()功能:共同完成连接工作格式:intPASCALFARconnect(SOCKETs,conststructsockaddrFAR*name,intnamelen);SOCKETPASCALFARaccept(SOCKETs,structsockaddrFAR*name,intFAR*addrlen);参数:同上4、监听连接——listen()功能:用于面向连接服务器,表明它愿意接收连接。格式:intPASCALFARlisten(SOCKETs,intbacklog);5、数据传输——send()与recv()功能:数据的发送与接收格式:intPASCALFARsend(SOCKETs,constcharFAR*buf,intlen,intflags);intPASCALFARrecv(SOCKETs,constcharFAR*buf,intlen,intflags);参数:buf:指向存有传输数据的缓冲区的指针。6、多路复用——select()功能:用来检测一个或多个套接字状态。格式:intPASCALFARselect(intnfds,fd_setFAR*readfds,fd_setFAR*writefds,fd_setFAR*exceptfds,conststructtimevalFAR*timeout);参数:readfds:指向要做读检测的指针writefds:指向要做写检测的指针exceptfds:指向要检测是否出错的指针timeout:最大等待时间7、关闭套接字——closesocket()功能:关闭套接字s格式:BOOLPASCALFARclosesocket(SOCKETs);FTP下载文件流程FTP服务端和客户端之间存在两中连接:一中用于传输FTP命令(命令必须由客户端主动发起),连接始终存在;另一中用于向客户端传输数据,每当要传输文件或目录文件列表信息时则建立一个数据连接,数据传输完毕立即断开。数据连接有两种建立方式:客户端监听某端口,服务器主动发起数据连接。服务器监听某端口,客户端主动发起数据连接。下载文件之前首先需要登陆,登陆的状态图如图2所示。如果前面发送的命令均得到成功响应,则表示服务器数据准备完毕。下面需要做的是与服务建立数据连接,开始接受数据,并将接收到的数据保存在本地文件中,直到接收完毕后断开数据连接,下载完毕。通过访问全局变量获得FTP服务器IP地址和端口号,以及登陆的用户名和密码,登陆服务器。为了实现FTP下载文件能成功,我觉得用代码和图片解释比较好,但文字描述不清楚,所以用代码的比较多,虽然觉得不好,但我只能这样。流程图流程图1(一)FTP客户端的主要代码1.头文件#includestdafx.h#includeListItem.h#ifdef_DEBUG#undefTHIS_FILEstaticcharTHIS_FILE[]=__FILE__;#definenewDEBUG_NEW#endif2.创建ParseLine()函数BOOLCListItem::ParseLine(CStringstrLine){if(strLine.IsEmpty())returnFALSE;charch=strLine.GetAt(0);if(ch=='d'||ch=='D'){m_bDirectory=TRUE;}elseif(ch=='-')m_bDirectory=FALSE;else{if(strLine.Find(DIR)!=-1||strLine.Find(dir)!=-1)m_bDirectory=TRUE;elsem_bDirectory=FALSE;if(strLine.GetLength()40)returnFALSE;m_strName=strLine.Mid(39);m_strDate=strLine.Left(18);m_strName.TrimLeft();m_strName.TrimRight();returnTRUE;}m_bSec=0;for(inti=0;i9;i++){ch=strLine.GetAt(i);if(ch=='-')m_bSec|=0x01;m_bSec=1;}m_strSec=strLine.Mid(1,9);intndx=strLine.Find(':');if(ndx==-1){if(strLine.GetLength()56)ndx=51;elsereturnFALSE;}m_index=ndx;m_strName=strLine.Mid(ndx+3);m_strName.TrimLeft();m_strName.TrimRight();m_strDate=strLine.Mid(ndx-9,12);returnTRUE;}(二)客户端运行后的界面图2上面的图是运行后在修改了用户名和密码,查出所需要的文件的I盘和文件名。客户端运行后看到的的服务器端地址是所用电脑的(三)FTP服务器端代码1.Socket编程中的Server()函数UINTServerThread(LPVOIDlpParameter){SOCKETsListen,sAccept;SOCKADDR_INinetAddr;DWORDdwFlags;DWORDdwRecvBytes;CServer*server=(CServer*)lpParameter;2.创建第一个手动重置对象if((g_events[0]=WSACreateEvent())==WSA_INVALID_EVENT){printf(错误:WSACreateEventfailedwitherror%d\n,WSAGetLastError());return0;}3.创建一个线程处理请求AfxBeginThread(ProcessTreadIO,(LPVOID)server);if(CreateThread(NULL,0,ProcessTreadIO,(void*)server,0,&dwThreadId)==NULL){printf(错误:CreateThreadfailedwitherror%d\n,GetLastError());return0;}g_dwEventTotal=1;while(!server-m_bStop){//处理入站连接if((sAccept=accept(sListen,NULL,NULL))==INVALID_SOCKET){printf(错误:acceptfailedwitherror%d\n,WSAGetLastError());return0;}//回传欢迎消息if(!server-WelcomeInfo(sAccept))break;//设置ftp根目录if(!SetCurrentDirectory(server-m_Directory))break;4.创建一个新的SOCKET_INF结构处理接受的数据socket.if((g_sockets[g_dwEventTotal]=(LPSOCKET_INF)GlobalAlloc(GPTR,sizeof(SOCKET_INF)))==NULL){printf(错误:GlobalAlloc()failedwith
本文标题:c语言小项目:用Socket编程实现FTP
链接地址:https://www.777doc.com/doc-2181611 .html