FTP协议浅析 Author:Leen 今日需要用到FTP上传文件,就研读了一下FTP协议。 虽然MFC中有 CFtpConnection 等类 使用起来很简易,但是不方便让我来理解FTP传输文件的过程,P传输解FT文件的过程,而且据说无法在WINCE上使用该类。 FTP使用两个端口,21作为命令传输端口使用 20一般作为主动传输时使用,被动传输时服务器开放端口,并将信息通过21端口发过来, 协议内容详见 RFC959。 假设位于U的用户希望从S上(下)传文件,通常用户需要使用用户FTP进程和服务器通信,下面就是一个例子: 用户发出的本地命令 解释 ftp (host) multics<CR> 连接到S的端口L,建立控制连接 <---- 220 Service ready <CRLF>. 用户名 Doe <CR> need password<CRLF>. USER Doe<CRLF>----> <---- 331 用户名正确 口令 <CR> PASS 口令<CRLF>----> <---- 230 User logged in<CRLF>. retrieve (local type) ASCII<CR> (local pathname) test 1 <CR> (for. pathname) test.pl1<CR> User-FTP opens local file in ASCII. RETR test.pl1<CRLF> ----> <---- 150 文件状态正常,将打开数据连接<CRLF> 服务器于端口U建立数据连接 文件传输中 <---- 226 关闭数据连接,文件传输正确<CRLF> type Image<CR> TYPE I<CRLF> ----> <---- 200 Command OK<CRLF> store (local type) image<CR> (local pathname) file dump<CR> (for.pathname) >udd>cn>fd<CR> User-FTP opens local file in Image. STOR >udd>cn>fd<CRLF> ----> <---- 550 访问拒绝<CRLF> 中止 QUIT <CRLF> ----> 服务器关闭所有连接 互联网各个协议间的层次关系图:
本帖隐藏的内容
一个FPT上传 文件 的请求与应答,参考下图
本帖隐藏的内容
想先我们要做的就是连接FTP服务器 / //连接服务器 //strIp IN IPAddress //iPort IN Port / BOOL CFtpTtansFile::Connect(CString strIp,int iPort) { if(iPort <= 0) return FALSE; //设置服务器信息 m_local.sin_family=AF_INET; m_local.sin_port=htons(iPort); m_local.sin_addr.S_un.S_addr=inet_addr(strIp); m_socketClient = socket(AF_INET,SOCK_STREAM,0); int ret; //联接服务器 ret=connect(m_socketClient,(LPSOCKADDR)&m_local,sizeof(m_local)); //有错的话 if(ret!=0) { int ierror = WSAGetLastError() ; CString strerror ; strerror.Format(_T("联接错误,错误代码:%d"),ierror); AfxMessageBox( strerror ); closesocket(m_socketClient); return FALSE;// -1; } //设置套接字通讯模式为异步模式 DWORD ul= 1; ret = ioctlsocket(m_socketClient,FIONBIO,&ul); if(ret != 0) { AfxMessageBox(_T("设置监听套接字通讯模式为异步模式失败")); return FALSE; } //接收服务器欢迎信息 char szRevbuff[1024]; memset(szRevbuff,0,1024); Safe_recvCmd(m_socketClient,szRevbuff,1024,0); TRACE(szRevbuff); return TRUE; } 连接成功以后服务器会发来消息 220-Serv-U FTP Server v6.4 for WinSock ready... 收到后我们就可发送用户名跟密码进行登录 用户名 密码的格式为 USER ***\r\n 响应: 331 User name okay, need password. PASS ***\r\n 响应:230 User logged in, proceed. //发送用户名 CString strSend; strSend.Format(_T("USER %s\r\n"),strUserName); //发送登录请求 //用户名 if(send(m_socketClient,strSend,strSend.GetLength(),0) == SOCKET_ERROR) { int ierror = WSAGetLastError(); return FALSE; } 切换到我们需要上传文件的目录 CWD /新文件夹/ 应答: 250 Directory changed to /新文件夹 设置数据传输格式 TYPE I//二进制格式 应答: 200 Type set to I. 使用被动传输,让服务器开放端口进行监听 PASV 应答: 227 Entering Passive Mode (192,168,10,10,128,234) 这个字段中: 192,168,10,10, 为IP 128,234)为端口 端口计算方法: 128*256+234 = 33002 这样我们就要再建立一个套接字连接过去 然后要求服务器建立这个文件并打开 STOR 关于FTP标准.doc 应答: 150 Opening BINARY mode data connection for 关于FTP标准.doc. 然后就可以通过33002将文件发送给服务器 关闭该套接字视为传输完毕 //关闭套接字作为传输完成标志 closesocket(sockData); 发送成功的话的典型响应: 226 Transfer complete. 下面我们根据数字顺序列出各个应答码及其意义: 110 重新启动标记应答。在这种情况下文本是确定的,它必须是:MARK yyyy=mmmm,其中yyyy是用户进程数据流标记,mmmm是服务器标记。 120 服务在nnn分钟内准备好 125 数据连接已打开,准备传送 150 文件状态良好,打开数据连接 200 命令成功 202 命令未实现 211 系统状态或系统帮助响应 212 目录状态 213 文件状态 214 帮助信息,信息仅对人类用户有用 215 名字系统类型 220 对新用户服务准备好 221 服务关闭控制连接,可以退出登录 225 数据连接打开,无传输正在进行 226 关闭数据连接,请求的文件操作成功 227 进入被动模式 230 用户登录 250 请求的文件操作完成 257 创建"PATHNAME" 331 用户名正确,需要口令 332 登录时需要帐户信息 350 请求的文件操作需要进一步命令 421 不能提供服务,关闭控制连接 425 不能打开数据连接 426 关闭连接,中止传输 450 请求的文件操作未执行 451 中止请求的操作:有本地错误 452 未执行请求的操作:系统存储空间不足 500 格式错误,命令不可识别 501 参数语法错误 502 命令未实现 503 命令顺序错误 504 此参数下的命令功能未实现 530 未登录 532 存储文件需要帐户信息 550 未执行请求的操作 551 请求操作中止:页类型未知 552 请求的文件操作中止,存储分配溢出 553 未执行请求的操作:文件名不合法 |
|