用VC++編制FTP客戶端應用程序

發表于:2007-07-14來源:作者:點擊數: 標簽:
FTP協議將使用兩條單獨的TCP連接,一條專用于發送FTP命令,另一條則專用于傳遞數據。初始建立連接時, 服務器 在21號端口上接收來自客戶端的命令連接。當需要傳送數據時(文件列表、文件數據等),客戶端向服務器發出Port命令,并進入監聽狀態,等待來自服務
  FTP協議將使用兩條單獨的TCP連接,一條專用于發送FTP命令,另一條則專用于傳遞數據。初始建立連接時,服務器在21號端口上接收來自客戶端的命令連接。當需要傳送數據時(文件列表、文件數據等),客戶端向服務器發出Port命令,并進入監聽狀態,等待來自服務器的數據連接請求。

  首先我們利用VC++ 6.0的AppWizard創建一個基于對話框的應用程序,命名為FtpClientDemo。為程序生成五個基于CAsyncSocket的新類,這里列出主要代碼。

  CCommandSocket類的主要代碼

  void CCommandSocket::OnReceive(int nErrorCode)

  {

  //這個函數使得服務器的應答消息顯示在編輯框上

   char? buffer=new char[4096];

   memset(buffer,0,4096);

   this-〉Receive(buffer,1024,0);

  //接收應答消息

   MessageList+=buffer;

   m_ReturnMessage-〉SetWindowText(MessageList);

   delete buffer;

  }

  CFileSocket類的主要代碼

    void CFileSocket::OnReceive(int nErrorCode)

  {

  //函數將收到的文件數據寫到文件中

   if(File= =NULL)

   { File=new CFile();

   File-〉Open(FileName,CFile::modeWrite|CFile::modeCreate);

   }

   char?buffer=new char[4096];

   memset(buffer,0,4096);

   this-〉Receive(buffer,4096,0);

   ReceiveString=buffer;

   File-〉Write(ReceiveString,ReceiveString.GetLength( ));

   delete buffer;

  }

  CReceiveSocket類的主要代碼

  void CReceiveSocket::OnReceive(int nErrorCode)

  {

  //接收服務器傳來的文件列表消息

   CString ReceiveString,Temp;

   char?buffer=new char[4096];

   memset(buffer,0,4096);

   this-〉Receive(buffer,4096,0); //接收消息

   ReceiveString+=buffer;

   delete buffer;

  //將文件列表從收到的消息字符串中分離出來,并顯示在列表框中

   while(!ReceiveString.IsEmpty())

   { int p=ReceiveString.Find("\r\n");

  if(p!=-1)

  { Temp=ReceiveString.Left(p);

   ReceiveString=ReceiveString.Right(ReceiveString.GetLength()-p-2);

  DisplayMessage-〉AddString(Temp);

   }

  }

  }

  CPortSocket類主要代碼

  void CPortSocket::OnAclearcase/" target="_blank" >ccept(int nErrorCode)

  {

  //根據不同的標志選擇相應的數據連接類,以接受服務器端的數據連接請求

   if(Flag= =LISTFILE)

  //若程序要求對目錄進行列表,則采用CReceiveSocket類

   {DataSocket=new CReceiveSocket(FileList);

   this-〉Accept(?DataSocket);

   }

   else if(Flag= =DOWNLOAD)

  //若程序要求下載文件,則生成CFileSocket類的對象

  {FileSocket=new CFileSocket(FileName);

  this-〉Accept(?FileSocket);

   }

  }

  主對話框類CFtpClient- DemoDlg的主要代碼

    void CFtpClientDemoDlg::OnFileList()

  //響應“文件列表”按鈕、列表目錄

  { CString Temp;

   if(ControlSocket= =NULL)

   {

  //連接到FTP服務器

  ControlSocket=new CCommandSocket(&&m_ReturnMessage);

  ControlSocket-〉Create();

  m_Server.GetWindowText(Temp);

  ControlSocket-〉Connect(Temp,21);

  //FTP服務器在21號端口接收連接

   }

   m_User.GetWindowText(Temp);

   Temp="USER "+Temp+"\r\n";

   ControlSocket-〉Send(Temp,Temp.GetLength(),0);

  //發User命令,驗證用戶

   m_Pass.GetWindowText(Temp); //m_Pass為“口令”編輯框的對應控制

   Temp="PASS "+Temp+"\r\n";

   ControlSocket-〉Send(Temp,Temp.GetLength(),0);

  //發Pass命令,校驗口令

   LisentPort(LISTFILE);

  //數據連接的對象為目錄列表

   ControlSocket-〉Send("LIST \r\n",7 ,0);

  //發List命令,要求列表目錄

  }

  void CFtpClientDemoDlg::OnDownLoad( )

  //下載文件

  {

   CString String;

   LisentPort(DOWNLOAD);

  //獲得要下戴文件的文件名

   m_LocalFile.GetWindowText(String);

  // m_LocalFile為“文件名”編輯框的對應控制

   String="RETR "+String+"\r\n";

   ControlSocket-〉Send(String,String.GetLength( ),0);

  //發RETR命令,下載文件

  }

  void CFtpClientDemoDlg::LisentPort(UINT Flag)

  {

  //根據要求選擇不同的數據連接對象

   if(LisentSocket!=NULL)

  //清空LisentSocket

   { LisentSocket-〉Close();

   delete LisentSocket;

   LisentSocket=NULL;

   }

   if(Flag= =LISTFILE)

  //如果為目錄列表數據連接對象

   { LisentSocket=new CPortSocket(LISTFILE);

   LisentSocket-〉SetListBox(&&m_FileList);

  //傳列表框到CLisentSocket類中

   }

   else if(Flag= =DOWNLOAD)

  //如果為文件傳輸數據連接對象

   { CString String;

   m_LocalFile.GetWindowText(String);

   LisentSocket=new CPortSocket(DOWNLOAD);

   LisentSocket-〉SetFileName(String);

  //傳文件名到CLisentSocket類中

   }

   LisentSocket-〉Create();

  //建立Socket并進行監聽,等待FTP服務器進行數據連接

   LisentSocket-〉Listen();

  //取得數據連接Socket的IP地址和監聽端口,并把它們作為Port命令的參數

   SOCKADDR_IN listing_address, control_address;

   int addr_size;

   addr_size = sizeof(listing_address);

   LisentSocket-〉GetSockName((SOCKADDR ?)&&listing_address, &&addr_size); //
取IP地址

   ControlSocket-〉GetSockName((SOCKADDR ?)&&control_address, &&addr_size); /
/取端口

  unsigned char ?port = (unsigned char ?)&&(listing_address.sin_port);

   unsigned char ?host = (unsigned char ?)&&(control_address.sin_addr);

   CString strBuffer;

   strBuffer.Format("PORT %i,%i,%i,%i,%i,%i\r\n",(int)host[0], (int)host[1], (
int)host[2], (int)host[3],(int)port[0], (int)port[1]);

   ControlSocket-〉Send(strBuffer,strBuffer.GetLength(),0);

  //發送Port命令,進行數據連接

  }

  以上代碼在VC++ 6.0、Windows 98上運行通過。

原文轉自:http://www.anti-gravitydesign.com

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97