现在的位置: 首页 > 综合 > 正文

ftp客户端

2014年02月07日 ⁄ 综合 ⁄ 共 10060字 ⁄ 字号 评论关闭
一个ftp客户端程序,使用了被动模式 

#ifndef    __FTP_H__
#define    __FTP_H__
 
class CFtp
{
public:
       CFtp(char *pszServAddr, int nPort);
       ~CFtp();
public:
       int CreateDataSock();
       int CreateLocalSocket(char *host, int port);
       int Connect();
       int Login(char * pszUsername, char * pszPassword);
       int Login();    
       int Logout();
       void SendCommand(char * pszCommand);
       int GetReply();
       int DoAccept(int sd);
       int DoReceive(int fd, char szBuffer[], int nLen);
      
public:
       char m_RecvBuff[1024*100];
       char m_szRepley[1024*100];      
       char * DispatchCommand(char *pszCommandType, char *pszCommand);
       void ProcessHelp(char *pszCommand);
       void ProcessLs(char *pszCommand);
       void ProcessGet(char *pszCommand);
private:
       char m_szServAddr[25];
       int m_nPort;
       char m_szUsername[32];
       char m_szPassword[32];
       int m_Socket;
 
 
private:
 
//    
//     int Parse(CAlcatelAdapter * pAdapter);
      
//     int GetLine(char * buf,char * line,int *islastline);
};
 
 
#endif
 
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
 
#include "ftp.h"
 
CFtp::CFtp(char * pszServAddr, int nPort)
{
       strncpy(m_szServAddr, pszServAddr, sizeof(m_szServAddr)-1);
       m_nPort = nPort;
}
 
CFtp::~CFtp()
{
       if (m_Socket)
              Logout();
}
 
char * CFtp::DispatchCommand(char *pszCommandType, char *pszCommand)
{
      
       printf("/n/n/n");
       memset(m_RecvBuff, 0, sizeof(m_RecvBuff));
       if(strcmp(pszCommandType, "HELP") == 0){            //help command
              ProcessHelp(pszCommand);
       }else if(strcmp(pszCommandType, "RETR") == 0){   //get command
              ProcessGet(pszCommand);
       }else if(strcmp(pszCommandType, "LIST") == 0){
              ProcessLs(pszCommand);
       }else{
              printf("ERROR command:<%s>", pszCommandType);
       }
      
       return m_RecvBuff;
}
 
void CFtp::ProcessHelp(char *pszCommand)
{
       SendCommand(pszCommand);
       int ret = GetReply();
      
       sprintf(m_RecvBuff, "%s", m_szRepley);
}
 
void CFtp::ProcessLs(char *pszCommand)
{
       int fd,ret;
      
       fd = CreateDataSock();
     if(fd < 0){
            printf("ASB>> create listen socket error!      /n");
            return;
      }
     
       SendCommand(pszCommand);
       if (GetReply() == -1){
              close(fd);
              return;
       }
       sprintf(m_RecvBuff, "%s", m_szRepley);
      
       ret = 1;
       int pos = strlen(m_RecvBuff);
       while(ret > 0){
            ret = DoReceive(fd, m_RecvBuff+pos, sizeof(m_RecvBuff)-pos-1);
       }
 
       GetReply();
       strcat(m_RecvBuff, m_szRepley);
      
     close(fd);
}
 
 
void CFtp::ProcessGet(char *pszCommand)
{
       //printf("ASB>>      ProcessGet()!");
       int ret;
       int fd = 0;
       char szCommand[256];
       char param1[256];
       char param2[256];
       char param3[256];
       char buffer[1024];
      
       //printf("ASB>>      pszCommand=%s /n", pszCommand);
       sprintf(szCommand, "%s", pszCommand);
       sprintf(param1, "%s", strtok(szCommand, " "));
       sprintf(param2, "%s", strtok(NULL, " "));
       sprintf(param3, "%s", strtok(NULL, " "));
      
       printf("p1=%s, p2=%s, p3=%s     /n", param1, param2, param3);
       sprintf(szCommand, "%s %s/r/n", param1, param2);
      
       fd = CreateDataSock();
     if(fd < 0){
            printf("ASB>> create data socket error!");
           return;
     }
     printf("ASB>> create data socket sucess!");
    
     SendCommand(szCommand);
       if(GetReply() == -1){
              close(fd);
              return;
       }
 
       FILE *f;
       f = fopen(param3, "w+");
       for(;;){
              memset(buffer, 0, 1024);
              ret = recv(fd, buffer, 1024-1, 0);
              if (ret > 0){
                     fwrite(buffer, 1, ret, f);
              }else{
                     break;
              }
       }
      
       fclose(f);
       close(fd);
//     if (GetReply() == -1){
//            printf("ASB>> GetFileReplyCode Error! ReplyCode=%d .",ret);
//     }
}
 
void CFtp::SendCommand(char * pszCommand)
{
       int ret;
      
       ret = send(m_Socket, pszCommand, strlen(pszCommand), 0);
       if (ret < 0){
              printf("ASB>> >>>>>>>>>>%s error. /n     erroninfo:%s   /n", pszCommand, strerror(errno));
              return;
       }else{
              printf("ASB>> >>>>>>>>>>%s", pszCommand);
       }
}
 
int CFtp::GetReply()
{
       int ret = 1;
       int pos = 0;
       char szReplyCode[5];
      
       memset(m_szRepley, 0, sizeof(m_szRepley));
       while(ret > 0){
             ret = DoReceive(m_Socket, m_szRepley+pos, sizeof(m_szRepley)-pos);
            if (ret < 0){
                   printf("ASB>> receive connect reply error. erroninfo:%s   /n",strerror(errno));
                     return -1;
            }
            pos += ret;
       }
      //memset(szReplyCode, 0, sizeof(szReplyCode));
      //memcpy(szReplyCode, m_RecvBuff, 3);
       
     
       //ret = atoi(szReplyCode);
      
       return 0;
}           
 
int CFtp::CreateLocalSocket(char *host, int port)
{
      
       struct sockaddr_in addr;
       m_Socket = socket(AF_INET,SOCK_STREAM,0);
 
       bzero(&addr, sizeof(addr));
       addr.sin_family = AF_INET;
       inet_pton(AF_INET, host, &addr.sin_addr);
       addr.sin_port = htons(port);
      
       if( bind(m_Socket, (struct sockaddr*)&addr, sizeof(addr)) < 0){
              perror("bind");
              return -1;
       }
 
       return 0;
}
 
//连接ftp服务器
int CFtp::Connect()
{
       struct     sockaddr_in remAddr_in;
       int        IntOptVaL=1,ret=0,replyCode;
      
//  m_Socket = socket(AF_INET,SOCK_STREAM,0);
//  if(m_Socket < 0){ 
//          printf("ASB>> Fail to open ftp control stream socket.       /n");
//          return -1;
//  }
 
     setsockopt(m_Socket,SOL_SOCKET,SO_KEEPALIVE,(char*)&IntOptVaL,sizeof(IntOptVaL));
 
     memset((void *)&remAddr_in, 0, sizeof(remAddr_in));
       remAddr_in.sin_family = AF_INET;
       remAddr_in.sin_port = htons(m_nPort);
       remAddr_in.sin_addr.s_addr = inet_addr(m_szServAddr); 
        
       if(connect(m_Socket, (struct sockaddr*)&remAddr_in, sizeof(remAddr_in))<0){
              printf("ASB>> connect :%s error. erroninfo:%s /n",m_szServAddr,strerror(errno));
             close(m_Socket);
             m_Socket = 0;
              return -1;
       }else{
            printf("ASB>> Connect to %s successfully.       /n", m_szServAddr);
     }
   
     replyCode = GetReply();
     if(replyCode != 0){
              printf("ASB>> Fail to connect. ReplyCode:%d    /n", replyCode);
              close(m_Socket);
              m_Socket = 0;
             return -1; /*should close by calling func*/
       }    
    printf("ASB>> **********%s/n", m_szRepley);
   
     return 0;
     
}
 
int CFtp::Login(char * pszUsername, char * pszPassword)
{
       char     szCommand[256];
      
       sprintf(szCommand,"USER %s/r/n", pszUsername);/*send login information:user*/
       SendCommand(szCommand);
       if (GetReply() == -1){
              close(m_Socket);
              m_Socket = 0;
             return -1; /*should close by calling func*/
       }    
       printf("ASB>> **********%s/n", m_szRepley);
      
       sprintf(szCommand,"PASS %s/r/n", pszPassword);/*send login information:pass*/
       SendCommand(szCommand);
       if (GetReply() == -1){
              close(m_Socket);
              m_Socket = 0;
             return -1; /*should close by calling func*/
       }    
       printf("ASB>> **********%s/n", m_szRepley);
                    
       sprintf(szCommand,"TYPE I/r/n");/*send TYPE command*/
       SendCommand(szCommand);
       if (GetReply() == -1){
              close(m_Socket);
              m_Socket = 0;
             return -1; /*should close by calling func*/
       }
       printf("ASB>> **********%s/n", m_szRepley);
 
       return 0;
}
 
int CFtp::Logout()
{
       char szCommand[256];
 
       sprintf(szCommand,"QUIT/r/n");//send QUIT command
       SendCommand(szCommand);
       if (GetReply() == -1){
              close(m_Socket);
              m_Socket = 0;
             return -1; /*should close by calling func*/
       }
 
       return 0;
}
 
 
int CFtp::DoAccept(int sd)
{
       struct sockaddr_in servaddr;
       size_t addlen;
      
       addlen = sizeof(servaddr);
       int fd = accept(sd, (struct sockaddr*)&servaddr, &addlen);
       if(fd < 0){
              return -1;
       }
       return fd;
}
 
int CFtp::DoReceive(int fd, char szBuffer[], int nLen)
{
       int nOpt = 1;
       fd_set rset;
       struct timeval tv;
      
       setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char*)&nOpt, sizeof(nOpt));
      
       tv.tv_sec = 2;
       tv.tv_usec = 0;
       FD_ZERO(&rset);
       FD_SET(fd, &rset);
       int ret = select(fd+1, &rset, NULL, NULL, &tv);
       if(ret < 0){
              if(errno == EINTR)       return 0;
              return -1;
       }else if(ret == 0){
              return 0; 
       }
       ret = recv(fd, szBuffer, nLen, 0);
       if(ret <= 0){
              return -1;
       }
       return ret;
}
 
 
/*
 *    Desc:      被动模式下提取需要连接服务端的端口,并由此端口创建socket,接收数据
 */
int CFtp::CreateDataSock()
{
 
       int ret = 0;
       int i,j,n,p;
      
       //clear TCP/IP socket data
       ret = 1;
       while(ret > 0){
            ret = DoReceive(m_Socket, m_RecvBuff, sizeof(m_RecvBuff)-1);
       }
      
       SendCommand("PASV/r/n");
 
       char szReplyCode[1024];
      
       memset(szReplyCode, 0, 1024);
     ret = recv(m_Socket, szReplyCode, 1024, 0);
     if (ret < 0){
            printf("ASB>> receive connect reply error. erroninfo:%s   /n",strerror(errno));
              return -1;
     }
       printf("ASB>> **********%s/n", szReplyCode);
      
       szReplyCode[ret-3]='/0';
       char *str1 = szReplyCode+39;
       char *str2 = strchr(str1,',');
       i = atoi(str2 + 1);
       n = 0;
       char str3[1024];
       memset(str3, 0, 1024);
       while(str1[n]!=',')
       {
              str3[n] = str1[n];
              n++;
       }
       j = atoi(str3);
       p = j*256+i;
 
       //create data socket via p(port)
       struct sockaddr_in addr;
       printf("ASB>> PASV is send,port=%d/n", p);
       int datasocket = socket(AF_INET, SOCK_STREAM, 0); //data socket
       if (datasocket == -1)      return -1;
 
       memset(&addr, 0, sizeof(addr));
       addr.sin_family = AF_INET;
       addr.sin_port = htons(p);
       addr.sin_addr.s_addr = inet_addr(m_szServAddr);;
       ret = connect(datasocket, (struct sockaddr*)&addr, sizeof(addr));
       if (ret == -1){
              printf("ASB>> datasocket connect %s:%d fail/n", m_szServAddr, p);
              return -1;
       }
      
       printf("ASB>> datasocket connect %s:%d sucess,datasocket=%d/n", m_szServAddr, p, datasocket);
       return datasocket;
}
 
#if 1
 
int main(void)
{
       CFtp ftp("136.64.1.3", 21);
      
       ftp.Connect();
       ftp.Login("sys", "sys");
      
       ftp.DispatchCommand("HELP", "HELP/r/n");
      
      
       ftp.DispatchCommand("RETR", "RETR test.txt ./test.txt");
 
       ftp.Logout();  
}
#endif

 

抱歉!评论已关闭.