china.com
主页
新闻
体育
游戏
文化
教育
健康
财经
科技
旅游
军事
娱乐
商贸
  科技动态 硬件广场 下载基地 网络教室 网络冲浪 科学博览 移动时代 手机上网 桌面壁纸 科技商情  


用VC++编制FTP客户端应用程序

2000-09-06 09:13:29

  FTP协议将使用两条单独的TCP连接,一条专用于发送FTP命令,另一条则专用于传递数据。初始建立连接时,服务器在21号端口上接收来自客户端的命令连接。当需要传送数据时(文件列表、文件数据等),客户端向服务器发出Port命令,并进入监听状态,等待来自服务器的数据连接请求。

  首先我们利用VC++ 6.0的AppWizard创建一个基于对话框的应用程序,命名为FtpClientDemo。调整主对话框的形式如图1,为程序生成五个基于CAsyncSocket的新类,限于篇幅,只列出主要代码。

241959__b1201t01.jpg
  图1
  ■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);

   }

   charbuffer=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;

   charbuffer=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::OnAccept(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上运行通过。


  摘自《赛迪网》 紫瑗/文

404 Not Found

404 Not Found


nginx


科技检索


中华网推荐

  • 1000名医生在线咨询

  • 中国足球队官方网站

  • 鸦片玫瑰(新版)

  • 精选股票天地

  • 闪光的flash教程

  • 中华网汽车世界

  • 为你的爱情出谋划策

  • 网文精选——野百合集

  • 世界文化遗产在中国

  • 历届香港小姐风姿集



  •  


    网络教室编辑信箱
    版权声明 | 本站检索 | 联系方法 | 刊登广告 | 使用说明 | 关于中华网 | 豁免条款

    版权所有 中华网