教你用Socket编程实现FTP功能_第1页
教你用Socket编程实现FTP功能_第2页
教你用Socket编程实现FTP功能_第3页
教你用Socket编程实现FTP功能_第4页
教你用Socket编程实现FTP功能_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

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

文档简介

1、 题目: 用Socket编程实现FTP 用Socket编程实现FTP 一、目的和意义(功能描述) 学习了TCP/IP这门课,接触最多的是用Windows Sockets编程来实现一些 功能。因此在熟悉了Windows Sockets的编程思想后,我觉的会很容易实现一个FTP的客户应用程序。它能够登录FTP服务器,并从服务器端下载数据。 数据同步传输系统既适合于服务器端的目录遍历,又适合客户端对服务端的上传文件和下载文件。运用Socket(套接字)接口和使用 FTP(文件传输协议)来实现客户端和服务器端之间信息的交互。该数据传输平台分为两个模块:服务器端模块和客户端模块。客户服务器程序通过对编程

2、语言 Visual C+6.0中的调用来实现利用TCP/IP协议中的 FTP协议和封装在NMFTP 内的Socket 接口进行客户端与服务器连接,并完成数据同步工作,例如:上传、下载、浏览、查询、对服务器目录与文件的管理以及执行远程命令等。 服务器端程序则持续的监听网络。当接受到客户端的Socket ,服务器程序提供相应的服务。网络通信模块使用POP3 控件来实现客户端与服务器的信息交流。 函数功能和流程如下:(1)首先创建一个CFtpclient的类的实例。 (2)用LogOnToServer()函数登录到指定的FTP服务器,允许非匿名用户和匿名两种登录方式,默认的端口为21. (3)使用M

3、oveFile()函数来上传下载数据文件,其中第一个参数是本地地址,第二个参数是远程地址,文件传输选用二进制模式。注意,文件传输使用同步模式。 (4)可以使用Ftpcommand()函数来执行FTP指令,包括常用的“CWD/home/mydir”来改变远程服务器上的地址,并处理服务器返回的应答。当这种方式不适用的时候,还可以使用WriteStr()函数和ReadStr()函数向远程服务器发送指令,并自己解释返回的应答。 (5)当所有的文件传输完成之后,使用LogOffServer函数来断开与远程服务器的连接。 二、基本原理 它的原理也相当的简单,客户端程序实现一个命令行或图形界面,将用户命令翻

4、译成 FTP 命令,并发送给服务器端程序。服务器端程序响应 FTP 命令,并将操作成功与否的信息以 FTP 响应形式返回给客户端程序。双方遵守 FTP 协议,完成文件传输服务。 就是利用MFC提供的CSocket类和CAsyncsocket类实现一个客户/服务器模式的数据通信模式,使用CSocketFile类和CArchive类来读写数据。它很好的实现了所有的功能,提供了简洁实用的接口。 三、详细设计 Windows 实现是指实现了Windows Sockets实现,一个Windows SocketsSockets规范所描述的全部功能的一套软件。一般通过DLL文件来实现。Windows环境下进

5、行网络程序设计的最基本方法是应用Windows Sockets来实现,通过使用MFC提供的Windows Sockets类,能够很好的完成FTP的功能。 连接管理: 数据连接有3大用途: (1) 从客户向服务器发送一个文件 (2) 从服务器向客户发送一个文件 (3) 从服务器向客户发送文件或目录列表。 每一个数据连接对传输一个文件或目录序列都要建立一个新的连接。 (1) 客户发出命令要求建立数据连接 (2) 客户在客户主机上未数据连接选择一个固定的端口号 (3) 客户使用PORT命令从控制连接上把端口号发给服务器。 (4) 服务器在控制连接上接收端口号,并向客户端主机上的端口发出主动打开,服务

6、器的数据连接使用端口21。 基本套接字 为了更好说明套接字编程原理,给出几个基本的套接字,在以后的篇幅中会给出更详细的使用说明。 1、创建套接字socket() 功能:使用前创建一个新的套接字 格式:SOCKET PASCAL FAR socket(int af,int type,int procotol); 参数:af: 通信发生的区域 type: 要建立的套接字类型 procotol: 使用的特定协议 2、指定本地地址bind() 功能:将套接字地址与所创建的套接字号联系起来。 格式:int PASCAL FAR bind(SOCKET s,const struct sockaddr FA

7、R * name,int namelen); 参数:s: 是由socket()调用返回的并且未作连接的套接字描述符(套接字号)。 其它:没有错误,bind()返回0,否则SOCKET_ERROR 地址结构说明: struct sockaddr_in short sin_family;/AF_INET u_short sin_port;/16位端口号,网络字节顺序 struct in_addr sin_addr;/32位IP地址,网络字节顺序 char sin_zero8;/保留 3、建立套接字连接connect()和accept() 功能:共同完成连接工作 格式:int PASCAL FAR

8、connect(SOCKET s,const struct sockaddr FAR * name,int namelen); SOCKET PASCAL FAR accept(SOCKET s,struct sockaddr FAR * name,int FAR * addrlen); 参数:同上 4、监听连接listen() 功能:用于面向连接服务器,表明它愿意接收连接。 格式:int PASCAL FAR listen(SOCKET s, int backlog); 5、数据传输send()与recv() 功能:数据的发送与接收 格式:int PASCAL FAR send(SOCKET

9、 s,const char FAR * buf,int len,int flags); int PASCAL FAR recv(SOCKET s,const char FAR * buf,int len,int flags); 参数:buf:指向存有传输数据的缓冲区的指针。 6、多路复用select() 功能:用来检测一个或多个套接字状态。 格式:int PASCAL FAR select(int nfds,fd_set FAR * readfds,fd_set FAR * writefds, fd_set FAR * exceptfds,const struct timeval FAR *

10、timeout); 参数:readfds:指向要做读检测的指针 writefds:指向要做写检测的指针 exceptfds:指向要检测是否出错的指针 timeout:最大等待时间 7、关闭套接字closesocket() 功能:关闭套接字s 格式:BOOL PASCAL FAR closesocket(SOCKET s); FTP 下载文件流程 FTP 服务端和客户端之间存在两中连接:一中用于传输 FTP 命令(命令必须由客户端主动发起),连接始终存在;另一中用于向客户端传输数据,每当要传输文件或目录文件列表信息时则建立一个数据连接,数据传输完毕立即断开。 数据连接有两种建立方式:客户端监听某

11、端口,服务器主动发起数据连接。服务器监听某端口,客户端主动发起数据连接。下载文件之前首先需要登陆,登陆的状态图如图 2 所示。如果前面发送的命令均得到成功响应,则表示服务器数据准备完毕。下面需要做的是与服务建立数据连接,开始接受数据,并将接收到的数据保存在本地文件中,直到接收完毕后断开数据连接,下载完毕。通过访问全局变量获得 FTP 服务器 IP 地址和端口号,以及登陆的用户名和密码,登陆服务器。 为了实现FTP下载文件能成功,我觉得用代码和图片解释比较好,但文字描述不清楚,所以用代码的比较多,虽然觉得不好,但我只能这样。 流程图 1流程图 (一)FTP客户端的主要代码 1.头文件 #incl

12、ude stdafx.h #include ListItem.h #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE=_FILE_; #define new DEBUG_NEW #endif 2.创建ParseLine()函数 BOOL CListItem:ParseLine(CString strLine) if(strLine.IsEmpty() return FALSE; char ch = strLine.GetAt(0); if(ch = d | ch = D) m_bDirectory = TRUE; else if(ch =

13、-) m_bDirectory = FALSE; else if(strLine.Find() != -1 | strLine.Find() != -1) m_bDirectory = TRUE; else m_bDirectory = FALSE; if(strLine.GetLength() 40) return FALSE; m_strName = strLine.Mid(39); m_strDate = strLine.Left(18); m_strName.TrimLeft(); m_strName.TrimRight(); return TRUE; m_bSec = 0; for(

14、int i = 0; i 9; i+) ch = strLine.GetAt(i); if(ch = -) m_bSec |= 0x01; m_bSec 56) ndx = 51; else return FALSE; m_index = ndx; m_strName = strLine.Mid(ndx + 3); m_strName.TrimLeft(); m_strName.TrimRight(); m_strDate = strLine.Mid(ndx - 9, 12); return TRUE; (二)客户端运行后的界面 图2 上面的图是运行后在修改了用户名和密码,查出所需要的文件的I

15、盘和文件名。客户端运行后看到的的服务器端地址是所用电脑的 (三)FTP服务器端代码 1.Socket编程中的()函数 ServerUINT ServerThread(LPVOID lpParameter) SOCKET sListen, sAccept; SOCKADDR_IN inetAddr; DWORD dwFlags; DWORD dwRecvBytes; CServer * server =(CServer*)lpParameter; 2.创建第一个手动重置对象 if (g_events0 = WSACreateEvent() = WSA_INVALID_EVENT) 牰湩晴尨错误:

16、WSACreateEvent failed with error %dn, WSAGetLastError(); return 0; 3. 创建一个线程处理请求 AfxBeginThread(ProcessTreadIO,(LPVOID)server); if (CreateThread(NULL, 0, ProcessTreadIO,(void*)server, 0, &dwThreadId) = NULL) 牰湩晴尨错误:CreateThread failed with error %dn, GetLastError(); return 0; g_dwEventTotal = 1; whi

17、le(!server-m_bStop) /处理入站连接 if (sAccept = accept(sListen, NULL, NULL) = INVALID_SOCKET) 牰湩晴尨错误:accept failed with error %dn, WSAGetLastError(); return 0; /回传欢迎消息 if( !server-WelcomeInfo( sAccept ) ) break; /设置ftp根目录 if( !SetCurrentDirectory( server-m_Directory) ) break; 4.创建一个新的SOCKET_INF结构处理接受的数据so

18、cket. if (g_socketsg_dwEventTotal = (LPSOCKET_INF) GlobalAlloc(GPTR,sizeof(SOCKET_INF) = NULL) GlobalAlloc() failed with error %dn, GetLastError(); 错误:?瀠楲瑮? return 0; 5.初始化新的SOCKET_INF结构 char buffDATA_BUFSIZE; memset( buff,0,DATA_BUFSIZE ); g_socketsg_dwEventTotal-wsaBuf.buf = buff; g_socketsg_dwEve

19、ntTotal-wsaBuf.len = DATA_BUFSIZE; g_socketsg_dwEventTotal-s = sAccept; memset(&(g_socketsg_dwEventTotal-o),0, sizeof(OVERLAPPED); g_socketsg_dwEventTotal-dwBytesSend = 0; g_socketsg_dwEventTotal-dwBytesRecv = 0; g_socketsg_dwEventTotal-nStatus = WSA_RECV; / 接收 6.下载数据的有关代码 /已经有数据传递if( pSI-nStatus =

20、WSA_RECV ) . if( !g_bLoggedIn ) if( server-LoginIn(pSI) = LOGGED_IN ) g_bLoggedIn = TRUE; else if(server-DealCommand( pSI )=FTP_QUIT) continue; / 缓冲区清除 memset( pSI-buffRecv,0,sizeof(pSI-buffRecv) ); pSI-dwBytesRecv = 0; else pSI-dwBytesSend += dwBytesTransferred; 继续接收以后到来的数据 / if(server-RecvReq( pSI ) = -1 ) return -1; return 0; . 接受数据/int CServer:RecvReq( LPSOCKET_INF pSI ) static DWORD dwRecvBytes = 0; pSI-nStatus = WSA_RECV; return 0; 7. 取得文件列表信息,并转换成字符串 BOOL bDetails = strstr(szCmd,LIST)?TRUE:FALSE; char buffDATA_BUFSI

温馨提示

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

评论

0/150

提交评论