MyFtpClient.cpp
上传用户:tjfeida
上传日期:2013-03-10
资源大小:1917k
文件大小:12k
源码类别:

Ftp客户端

开发平台:

Visual C++

  1. #include "StdAfx.h"
  2. #include ".myftpclient.h"
  3. #include "MyFtpClient.h"
  4. #include "Afxsock.h"
  5. #include <stdio.h>
  6. #include <tchar.h>
  7. #include <process.h>
  8. #include "tchar.h"
  9. MyFtpClient::MyFtpClient(void)
  10. {
  11.  m_pControlRarchive=NULL;
  12.  m_pControlTarchive=NULL;
  13.  m_pControlSocketFile=NULL;
  14.  m_pControlSocket=NULL;
  15.  m_pFireWallCheck=2;
  16. }
  17. //向服务器发出命令并得到响应的函数
  18. BOOL MyFtpClient::FTPCommand(CString command)
  19. {   
  20. if(command!=""&&!WriteString(command))
  21. return FALSE;
  22. if((!(ReadString1()))||(m_pFireWallCheck!=2))
  23. return FALSE;
  24. return TRUE;
  25. }
  26. MyFtpClient::~MyFtpClient(void)
  27. {
  28. CloseControlChannel();
  29. }
  30. //上传或者下载文件
  31. BOOL MyFtpClient::MoveFile(CString RemoteFile, CString LocalFile, bool Pasv, bool GetfFile)
  32. {
  33. CString LeftServer,temp,RightServer;
  34. UINT LocalSocket,ServerSocket,i,j;
  35. CFile File_data;
  36. CSocket Socket_server;
  37. CAsyncSocket Channel_data;
  38. int Number,ReadNumber,SendNumber;
  39. const int BUFFERSIZE=4096;
  40. char CurrentBuffer[BUFFERSIZE];
  41. DWORD IpArgument=0;
  42. if(!File_data.Open(LocalFile,(GetfFile?CFile::modeWrite|CFile::modeCreate:CFile::modeRead)))
  43. {
  44.        
  45. m_strRetmsg.LoadString(58113);
  46. return FALSE;
  47. }
  48. if(!FTPCommand("TYPE I"))
  49. return FALSE;
  50. if(Pasv)
  51. {
  52. if(!FTPCommand("PASV"))
  53. return FALSE;
  54. if((i=m_strRetmsg.Find("("))==-1||(j=m_strRetmsg.Find(")")))
  55. return FALSE;
  56.            //获取IP地址,和端口号的字符段
  57. temp=m_strRetmsg.Mid(i+1,(j-i)-1);
  58. //将端口转化成整形变量
  59. //低字节
  60. i=temp.ReverseFind(',');
  61. ServerSocket=atol(temp.Right(temp.GetLength()-(i+1)));
  62. //高字节
  63. temp=temp.Left(i);
  64. i=temp.ReverseFind(',');
  65. ServerSocket+=256*atol(temp.Right(temp.GetLength()-(i+1)));
  66. //获得IP地址
  67. RightServer=temp.Left(i);
  68. while(1)
  69. {
  70. if((i=RightServer.Find(','))==-1)
  71. break;
  72. RightServer.SetAt(i,'.');
  73. }
  74. }
  75. //通过以上处理此时temp里面放的是以点分隔的ip地址
  76. else
  77. {
  78. m_strRetmsg.LoadString(106);//消息处理
  79. //获得本地的连接ip地址以及端口号信息
  80.             if(!m_pControlSocket->GetSockName(LeftServer,LocalSocket))
  81. return FALSE;
  82.             
  83.            
  84. //将本地的ip地址转化为,分隔的
  85. while(1)
  86. {
  87. if((i=LeftServer.Find('.'))==-1)
  88.    break;
  89.    LeftServer.SetAt(i,',');
  90. }
  91.  
  92. //建立连接或者侦听连接
  93. if((!Socket_server.Create(0,SOCK_STREAM,NULL))||(!Socket_server.Listen()))
  94. return FALSE;
  95.            //获得本地侦听进程的ip以及端口
  96. if(!Socket_server.GetSockName(temp,LocalSocket))
  97. return FALSE;
  98. //将端口转化为字节以点分隔
  99. LeftServer.Format(LeftServer+",%d,%d",LocalSocket/256,LocalSocket%256);
  100. if(!FTPCommand("PORT "+LeftServer))
  101. return FALSE;
  102. }
  103. //发送RETR/STOR/命令到服务器
  104. if(!WriteString((GetfFile?"RETR ":"SOTR ")+RemoteFile))
  105. return FALSE;
  106.           
  107. if(Pasv)
  108. {   
  109. if(!Channel_data.Create())
  110. {
  111.  
  112. AfxMessageBox("建立线程连接失败");
  113. m_strRetmsg.LoadString(106);
  114.                     return FALSE;
  115. }
  116. Channel_data.Connect(RightServer,ServerSocket);
  117. }
  118. if(!ReadString1()||m_pFireWallCheck!=1)
  119. return FALSE;
  120. if(!Pasv&&!Socket_server.Accept(Channel_data))
  121. return FALSE;
  122. if((!Channel_data.AsyncSelect(0))||(Channel_data.IOCtl(FIONBIO,&IpArgument)))
  123. {
  124. AfxMessageBox("建立线程连接失败");
  125. m_strRetmsg.LoadString(106);
  126. return FALSE;
  127. }
  128. while(1)
  129. {
  130. TRY
  131. {
  132. if(GetfFile)
  133. {
  134. if(!(Number=Channel_data.Receive(CurrentBuffer,BUFFERSIZE,0))||Number==SOCKET_ERROR)
  135. break;
  136. else(File_data.Write(CurrentBuffer,Number));
  137. }
  138. else
  139. {
  140. if(!(ReadNumber=File_data.Read(CurrentBuffer,BUFFERSIZE)))
  141. break;
  142. if((SendNumber=Channel_data.Send(CurrentBuffer,ReadNumber,0))==SOCKET_ERROR)
  143. break;
  144. if(ReadNumber!=SendNumber)
  145. File_data.Seek(SendNumber-ReadNumber,CFile::current);
  146. }
  147. }
  148. CATCH(CException,pEx)
  149. {
  150. m_strRetmsg.LoadString(105);
  151. return FALSE;
  152. }
  153. END_CATCH
  154. }
  155. Channel_data.Close();
  156. File_data.Close();
  157. if(!FTPCommand(""))
  158. return FALSE;
  159. return TRUE;
  160. }
  161. void MyFtpClient::LogOffServer(void)
  162. {
  163. WriteString("断开连接");
  164. CloseControlChannel();
  165. WSACleanup();
  166. }
  167. BOOL MyFtpClient::LogOntoServer(CString ServerName, int ServerPort, CString UserName, 
  168. CString PassWord, CString Accept, CString FireWallServer,
  169. CString FireWallUserName, CString FireWallPassWord, 
  170. int FireWordPort, int LogOnType)
  171. {   
  172.      
  173. int nPort,LogOnPoint=0;
  174. const int LogSuccess=-2,LogError=-1;
  175. CString buffer,temp;
  176. const int LOGONNUMBER=9;
  177. int LogonSequence[LOGONNUMBER][100] = {
  178. // 下面的数组保存了针对不同防火墙的登录序列
  179. {0,LogSuccess,3, 1,LogSuccess,6, 2,LogSuccess,LogError}, // 没有防火墙
  180. {3,6,3, 4,6,LogError, 5,LogError,9, 0,LogSuccess,12, 1,LogSuccess,15, 2,LogSuccess,LogError}, // 主机名
  181. {3,6,3, 4,6,LogError, 6,LogSuccess,9, 1,LogSuccess,12, 2,LogSuccess,LogError}, // USER 后跟主机信息的
  182. {7,3,3, 0,LogSuccess,6, 1,LogSuccess,9, 2,LogSuccess,LogError}, //有代理
  183. {3,6,3, 4,6,LogError, 0,LogSuccess,9, 1,LogSuccess,12, 2,LogSuccess,LogError}, // Transparent
  184. {6,LogSuccess,3, 1,LogSuccess,6, 2,LogSuccess,LogError}, // USER with no logon
  185. {8,6,3, 4,6,LogError, 0,LogSuccess,9, 1,LogSuccess,12, 2,LogSuccess,LogError}, //USER fireID@remotehost
  186. {9,LogError,3, 1,LogSuccess,6, 2,LogSuccess,LogError}, //USER remoteID@remotehost fireID
  187. {10,LogSuccess,3, 11,LogSuccess,6, 2,LogSuccess,LogError} // USER remoteID@fireID@remotehost
  188.                                 };
  189. if(LogOnType<0||LogOnType>=LOGONNUMBER)
  190. return  FALSE;
  191.   
  192. //没有防火墙的
  193.        if(!LogOnType)
  194.    {
  195.    temp=ServerName;
  196.    nPort=ServerPort;
  197.    }
  198.       //有防火墙的
  199.    else
  200.    {
  201.    temp=FireWallServer;
  202.    nPort=FireWordPort;
  203.    }
  204.    if(ServerPort!=21)
  205.    ServerName.Format(ServerName+":%d",ServerPort);
  206.    //打开控制通道
  207.    if(!OpenControlChannel(temp,nPort))
  208.    return false;
  209.    
  210.    //发出命令以得到服务器的响应
  211.    if(!FTPCommand(""))
  212.    return false;
  213.    
  214.    
  215.      //各种不同形式的登录
  216.    while(1)
  217.    {
  218.    switch(LogonSequence[LogOnType][LogOnPoint])
  219.    {
  220.    case 0:
  221. temp="USER "+UserName;
  222. break;
  223. case 1:
  224. temp="PASS "+PassWord;
  225. break;
  226. case 2:
  227. temp="ACCT "+Accept;
  228. break;
  229. case 3:
  230. temp="USER "+FireWallUserName;
  231. break;
  232. case 4:
  233. temp="PASS "+FireWallPassWord;
  234. break;
  235. case 5:
  236. temp="SITE "+ServerName;
  237. break;
  238. case 6:
  239. temp="USER "+UserName+"@"+ServerName;
  240. break;
  241. case 7:
  242. temp="OPEN "+ServerName;
  243. break;
  244. case 8:
  245. temp="USER "+FireWallUserName+"@"+ServerName;
  246. break;
  247. case 9:
  248. temp="USER "+UserName+"@"+ServerName+" "+FireWallUserName;
  249. break;
  250. case 10:
  251. temp="USER "+UserName+"@"+FireWallUserName+"@"+ServerName;
  252. break;
  253. case 11:
  254. temp="PASS "+PassWord+"@"+FireWallPassWord;
  255. break;
  256. }
  257.            
  258.    if(!WriteString(temp))
  259.              return FALSE;
  260.    if(!ReadString1())
  261.                return FALSE;
  262.  // AfxMessageBox("ok");
  263.  
  264.    if(m_pFireWallCheck!=2&&m_pFireWallCheck!=3)
  265.    return FALSE;
  266.    
  267.    LogOnPoint=LogonSequence[LogOnType][LogOnPoint+m_pFireWallCheck-1];
  268.    
  269.    switch(LogOnPoint)
  270.    {
  271.    case LogError:
  272.    m_strRetmsg.LoadString(108);
  273.    return FALSE;
  274.    case LogSuccess:
  275.                    return TRUE;
  276.    }
  277.    
  278.    }
  279.                             
  280. }
  281. //获得服务器的响应函数
  282. BOOL MyFtpClient::ReadString1(void)
  283. {
  284. int RetCode;
  285. if(!ReadString2())
  286. return FALSE;
  287.  
  288. if(m_strRetmsg.GetLength()<4||m_strRetmsg.GetAt(3)!='-')
  289. return TRUE;
  290.  
  291. RetCode=atol(m_strRetmsg);
  292. while(1)
  293. {
  294. if(m_strRetmsg.GetLength()>3&&(m_strRetmsg.GetAt(3)==' '&&atol(m_strRetmsg)==RetCode))
  295. return TRUE;
  296. if(!ReadString2())
  297. return FALSE;
  298. }
  299. }
  300. //写命令到服务器
  301. BOOL MyFtpClient::WriteString(CString OutPutString)
  302. {
  303. m_strRetmsg.LoadString(106);
  304. TRY
  305. {
  306. m_pControlTarchive->WriteString(OutPutString+"rn");
  307. m_pControlTarchive->Flush();
  308. }
  309. CATCH(CException,e)
  310. {  
  311. return FALSE;
  312. }
  313. END_CATCH
  314. return TRUE;
  315. }
  316. //列出文件列表
  317. BOOL MyFtpClient::List(void)
  318. {    
  319.    CString LeftServer,temp,RightServer;
  320.    UINT LocalSocket,i;
  321.    CFile File_data;
  322.    CSocket Socket_server;
  323.    CAsyncSocket Channel_data;
  324.    int Number,sum;
  325.    const int BUFFERSIZE=4096;
  326.    DWORD IpArgument=0;
  327.    m_strBuffer.RemoveAll();
  328.    m_strBuffer.SetSize(BUFFERSIZE);
  329.    
  330.    //向FTP发控制命令
  331.    if(!FTPCommand("TYPE I"))
  332.    return FALSE;
  333.    m_strRetmsg.LoadString(106);
  334.    //获得本地主机的ip及端口信息
  335.    if(!m_pControlSocket->GetSockName(LeftServer,LocalSocket))
  336.    return FALSE;
  337.   //将.转化为,
  338.    while(1)
  339.    {
  340.    if((i=LeftServer.Find('.'))==-1)
  341.    break;
  342.    LeftServer.SetAt(i,',');
  343.    }
  344.    if((!Socket_server.Create(0,SOCK_STREAM,NULL))||(!Socket_server.Listen()))
  345.    return FALSE;
  346.    if(!Socket_server.GetSockName(temp,LocalSocket))
  347.    return FALSE;
  348.    LeftServer.Format(LeftServer+",%d,%d",LocalSocket/256,LocalSocket%256);
  349.    if(!FTPCommand("PORT "+LeftServer))
  350.    return FALSE;
  351.    if(!WriteString("LIST"))
  352.    return FALSE;
  353.    if(!ReadString1())
  354.    return FALSE;
  355.    if(!Socket_server.Accept(Channel_data))
  356.    return FALSE;
  357.    if((!Channel_data.AsyncSelect(0))||(!Channel_data.IOCtl(FIONBIO,&IpArgument)))
  358.    {
  359.    m_strRetmsg.LoadString(106);
  360.    return FALSE;
  361.    }
  362.    sum=0;
  363.    while(1)
  364.    {
  365. TRY
  366.    {
  367.    if(!(Number=Channel_data.Receive(m_strBuffer.GetData()+sum,BUFFERSIZE,0))||Number==SOCKET_ERROR)
  368.    break;
  369.    TRACE("Received :%dn",Number);
  370.    Sleep(0);
  371.    sum+=Number;
  372.    m_strBuffer.SetSize(sum+BUFFERSIZE);
  373.    }
  374.    CATCH(CException,e)
  375.    {
  376.    m_strRetmsg.LoadString(105);
  377.    return FALSE;
  378.    }
  379.    END_CATCH
  380.    }
  381.    Channel_data.Close();
  382.    
  383.                  
  384. }
  385. BOOL MyFtpClient::GetLine(int& index)
  386. {
  387. m_strLine.Empty();
  388. int nBytes=m_strBuffer.GetSize();
  389. BOOL bLine=FALSE;
  390. while((bLine==FALSE)&&(index<nBytes))
  391. {
  392. char ch=(char)(m_strBuffer.GetAt(index));
  393. switch(ch)
  394. {
  395. case 'n':
  396. bLine=TRUE;
  397. break;
  398. default:
  399. m_strLine+=ch;
  400. break;
  401. }
  402. ++index;
  403. }
  404. m_strLine=m_strLine.Left(m_strLine.GetLength()-1);
  405. return bLine;
  406. }
  407. //从服务器控制通道获取一行的响应
  408. BOOL MyFtpClient::ReadString2(void)
  409. {    
  410.    
  411. if(!m_pControlRarchive->ReadString(m_strRetmsg))
  412. {
  413. m_strRetmsg.LoadString(106);
  414. return FALSE;
  415. }
  416. if(m_strRetmsg.GetLength()>0)
  417.    m_pFireWallCheck=m_strRetmsg.GetAt(0)-48;
  418.    return TRUE;
  419. }
  420. //打开控制通道
  421. BOOL MyFtpClient::OpenControlChannel(CString serverAddress, int serverPort)
  422. {  
  423. m_strRetmsg.LoadString(104);
  424. if(!(m_pControlSocket=new CSocket))
  425. return FALSE;
  426.    
  427. if(!(m_pControlSocket->Create()))
  428.      return FALSE;
  429.  
  430. m_strRetmsg.LoadString(103);
  431. if(!(m_pControlSocket->Connect(serverAddress,serverPort)))
  432. return FALSE;
  433.  
  434. m_strRetmsg.LoadString(104);
  435. if(!(m_pControlSocketFile=new CSocketFile(m_pControlSocket)))
  436. return FALSE;
  437. if(!(m_pControlRarchive=new CArchive(m_pControlSocketFile,CArchive::load)))
  438. return FALSE;
  439. if(!(m_pControlTarchive=new CArchive(m_pControlSocketFile,CArchive::store)))
  440. return FALSE;
  441. return TRUE;
  442. }
  443. void MyFtpClient::CloseControlChannel(void)
  444. {
  445. if(m_pControlTarchive)
  446. delete m_pControlTarchive;
  447. m_pControlTarchive=NULL;
  448. if(m_pControlRarchive)
  449. delete m_pControlRarchive;
  450. m_pControlRarchive=NULL;
  451. if(m_pControlSocketFile)
  452. delete m_pControlSocketFile;
  453. m_pControlSocketFile=NULL;
  454. if(m_pControlSocket)
  455. delete m_pControlSocket;
  456. m_pControlSocket=NULL;
  457. return;
  458. }