www.pudn.com > FTP.rar > ftp_client.cpp, change:2009-06-09,size:34211b


#include "ftp_client.h"
#include <iostream>
using namespace std;

//static char CONFIG_FILE_PATH[]="./configfile.txt";
Login_Infor* BASE_OBJECT::pLoginInfor = new Login_Infor;	

BASE_OBJECT :: BASE_OBJECT()
{
    //memset((BASE_OBJECT::pLoginInfor), 0x00, sizeof(Login_Infor));
    printf("BASE_OBJECT CONSTRUCT!\n");
}

BASE_OBJECT :: ~BASE_OBJECT()
{
    if ((BASE_OBJECT::pLoginInfor) != NULL)
    {
        delete (BASE_OBJECT::pLoginInfor);
        (BASE_OBJECT::pLoginInfor)=NULL;
    }
    printf("BASE_OBJECT DESTRUCT!\n");
}

bool BASE_OBJECT :: getValue(const char* src, char* des1, char* des2)
{
    if ( (src==NULL) || (des1==NULL) || (des2==NULL) )
	  {
	      return false;   	
	  }
	  char* p1;
	  char* p2;
	  char* p3;
	  char tmpArrary[200];
	  memset(tmpArrary, 0x00, sizeof(tmpArrary));
	  if ( (p1=strchr(src, '=')) == NULL )
	  {
	      return false; 	
	  }
	  strncpy(tmpArrary, src, int(p1-src));
	  tmpArrary[int(p1-src)] = '\0';
	  int len = strlen(tmpArrary);
	  for ( int i=0; i<len; i++)
	  {
	      if ( (tmpArrary[i]==UNIX_SPACE) || tmpArrary[i]==UNIX_TABLESPACE )
	      {
	          continue;	
	      }	
	      p2 = &tmpArrary[i];
	      break;
	      
	  }
	  for ( int j=len-1; j>=0; j--)
	  {
	      if ( (tmpArrary[j]==UNIX_SPACE) || tmpArrary[j]==UNIX_TABLESPACE )
	      {
	          continue;	
	      }	
	      p3 = &tmpArrary[j];
	      break;	
	  }
	  strncpy(des1, p2, int(p3-p2)+1);
	  
	  memset(tmpArrary, 0x00, sizeof(tmpArrary));
	  if ( ((p2=strchr(p1, LEFT_SIGN))==NULL) || ((p3=strchr(p1,RIGHT_SIGN))==NULL) )
	  {
	      return false;	
	  }
	  strncpy(tmpArrary, p2+1, int(p3-p2)-1);
	  tmpArrary[int(p3-p2)-1] = '\0';
	  len = strlen(tmpArrary);
	  for ( int i=0; i<len; i++)
	  {
	      if ( (tmpArrary[i]==UNIX_SPACE) || tmpArrary[i]==UNIX_TABLESPACE )
	      {
	          continue;	
	      }	
	      p2 = &tmpArrary[i];
	      break;
	      
	  }
	  for ( int j=len-1; j>=0; j--)
	  {
	      if ( (tmpArrary[j]==UNIX_SPACE) || tmpArrary[j]==UNIX_TABLESPACE )
	      {
	          continue;	
	      }	
	      p3 = &tmpArrary[j];
	      break;	
	  }
	  strncpy(des2, p2, int(p3-p2)+1);
    return true;
}


bool BASE_OBJECT :: analyse(const char* path)
{
    if ( path == NULL ) return false;
    FILE *fp = fopen(path, "r");
    if ( fp == NULL ) return false;
    char tmpArrary[200];
    char option[20];
    char value[50];
    while ( !feof(fp) )
    {
        memset(tmpArrary, 0x00, sizeof(tmpArrary));
        memset(option, 0x00, sizeof(option));
        memset(value, 0x00, sizeof(value));
        if ( fgets(tmpArrary, 1024, fp) == NULL )
        {
            continue;
        }
        if ( tmpArrary[0] == '\n' )
        {
            continue;	
        }	
        if ( !getValue(tmpArrary, option, value) )
        {
            //cout<<tmpArrary<<" get config error!"<<endl;
            printf("%s get config error!\n", tmpArrary);
            return false;   	
        }
        if ( strcmp(option, "SERVER_IP") == 0 )
        {
            strcpy((BASE_OBJECT::pLoginInfor)->serverIp, value);	
        }
        else if ( strcmp(option, "SERVER_PORT") == 0 )
        {
            (BASE_OBJECT::pLoginInfor)->serverPort=(value[0]=='\0' ?21 :atoi(value)); 	
        }
        else if ( strcmp(option, "USER") == 0 )
        {
            strcpy((BASE_OBJECT::pLoginInfor)->user, value);	
        }
        else if ( strcmp(option, "PASSWORD") == 0 )
        {
            strcpy((BASE_OBJECT::pLoginInfor)->password, value);	
        }
    	  else if ( strcmp(option, "TYPE") == 0 )
        {
            (BASE_OBJECT::pLoginInfor)->type=value[0];
        }
        else if ( strcmp(option, "SERVER_PATH") == 0 )
        {
            strcpy((BASE_OBJECT::pLoginInfor)->serverPath, value);	
        }
        else if ( strcmp(option, "LOCAL_IP") == 0 )
        {
            strcpy((BASE_OBJECT::pLoginInfor)->localIp, value);	
        }
        else if ( strcmp(option, "LOCAL_PORT") == 0 )
        {
            (BASE_OBJECT::pLoginInfor)->localPort=(value[0]=='\0' ?0 :atoi(value)); 
        }
        else if ( strcmp(option, "LOCAL_PATH") == 0 )
        {
            strcpy((BASE_OBJECT::pLoginInfor)->localPath, value);	
        }
        else
        	  //cout<<option<<" disabled option!\n";
        	  printf("%s disabled option!\n", option);
    }
    /*printf("SERVER_IP: %s\nSERVER_PORT: %d\nUSER: %s\nPASSWORD: %s\nTYPE: %c\nROM_PATH: %s\n   \
    LOCAL_IP: %s\nLOCAL_PORT: %d\nLOCAL_PATH: %s\n", (BASE_OBJECT::pLoginInfor)->serverIp, (BASE_OBJECT::pLoginInfor)->serverPort, \
    (BASE_OBJECT::pLoginInfor)->user, (BASE_OBJECT::pLoginInfor)->password, (BASE_OBJECT::pLoginInfor)->type, (BASE_OBJECT::pLoginInfor)->serverPath, (BASE_OBJECT::pLoginInfor)->localIp, \
    (BASE_OBJECT::pLoginInfor)->localPort, (BASE_OBJECT::pLoginInfor)->localPath);*/
    fclose(fp);
    return true;
}

bool BASE_OBJECT :: getValueByFixChar(char* src, char des[][10], char sign)
{
    if ( (src==NULL) || (des==NULL) )
    {
        cout<<"str and des not init!"<<endl;
        return false;	
    }	
    char* pos ;
    char* tmpSrc = src;
    int len;
    int i = 0;
    while ( (pos=strchr(tmpSrc, sign)) != NULL )
    {	
        len = int(pos - tmpSrc);
        strncpy(des[i], tmpSrc, len);
        des[i][len] = '\0';
        tmpSrc = ++pos;
        i++;
    }
    if ( tmpSrc[0] != '\0' )
    {
        strcpy(des[i], tmpSrc);	
    }
    return true;
}

bool BASE_OBJECT :: getValueByFixChar2(char* src, char des[][30], char sign)
{
	  if ( (src==NULL) || (des==NULL) ) return false;
	  char* p1 = src;
	  char* p2;
	  int i = 0;
	  int len;
	  while ( (p2=strchr(p1, sign)) != NULL )
	  {
	      if ( p2 != p1) 
	      {
	          len = int(p2 - p1);
	          strncpy(des[i++], p1, len); 
	      }
	      p1 = ++p2;
	      
    }
    if ( p1[0] != '\0' )
    {
        strcpy(des[i], p1);	
    }
    return true;	
}

bool BASE_OBJECT :: copyFile(char* srcFile, char* desFile, char* openSign)
{
    if ( (srcFile==NULL) || (desFile==NULL) ) return false;
    FILE *srcFp = fopen(srcFile, "r");
    FILE *desFp = fopen(desFile, openSign);
    if ( (srcFp==NULL) || (desFp==NULL) )
    {
        return false;	
    }	
    char tmpArr1[1024];
    while ( !feof(srcFp) )
    {
        memset(tmpArr1, 0x00, sizeof(tmpArr1));
        if ( fgets(tmpArr1, 1023, srcFp) == NULL )
        {
            continue;
        }
        fwrite(tmpArr1, strlen(tmpArr1), 1, desFp);
    }
    fclose(srcFp);
    fclose(desFp);
    return true;
}

FTP_CLIENT :: FTP_CLIENT()
{
    memset(&serverAddr, 0x00, sizeof(serverAddr));
    memset(&clientAddr, 0x00, sizeof(clientAddr));
    pLoadTaskInfor = (Load_Task*) malloc(PROC_COUNT*sizeof(Load_Task));
    //memset(&loadTaskInfor, 0x00, sizeof(loadTaskInfor));
    printf("FTP_CLIENT CONSTRUCT!\n");
}

FTP_CLIENT :: ~FTP_CLIENT()
{
	  free(pLoadTaskInfor);
	  pLoadTaskInfor = NULL;
	  printf("FTP_CLIENT DESTRUCT!\n");
}

bool FTP_CLIENT :: ftpInit()
{
	  char recvBuf[4096];
	  serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = inet_addr((BASE_OBJECT::pLoginInfor)->serverIp);
    serverAddr.sin_port = htons((BASE_OBJECT::pLoginInfor)->serverPort);
    if ((controlSock=socket(AF_INET,SOCK_STREAM,0))  0 )
    {
        perror("socket");
        return false;
    }
    if ( connect(controlSock, (struct sockaddr *)&serverAddr, sizeof(serverAddr))  0 )
    {
        perror("connect");
        return false;
    }
    if ( !ftpRecvSucc(controlSock, (char*)"220") )
    {
        printf("ftpInit outtime or error!\n");
        return false;  	
    }
    return true;
}

int FTP_CLIENT :: getOneFileSize(char* path, char* para)
{
    if ( (path==NULL) || (para==NULL) )
    {
        return -1;	
    }	
    FILE* fp = fopen(path, "r+");
    char tmpArr1[1024];
    char tmpArr2[10][30];
    while ( !feof(fp) )
    {
        memset(tmpArr1, 0x00, sizeof(tmpArr1));
        memset(tmpArr2, 0x00, sizeof(tmpArr2));
        if ( fgets(tmpArr1, 1024, fp) == NULL )
        {
            continue;
        }
        if ( tmpArr1[0] == '\n' )
        {
            continue;	
        }	
        if ( !BASE_OBJECT::getValueByFixChar2(tmpArr1, tmpArr2, ' ') )
        {
        	  fclose(fp);
            return -1;	
        }	
        //printf("tmpArr2[8]: %s\n", tmpArr2[8]);
        if ( strncmp(tmpArr2[8], para, strlen(para)) == 0 )
            return (tmpArr2[4]==NULL ?0 :atoi(tmpArr2[4]));
    }
    return 0;
}

bool FTP_CLIENT :: ftpCmd(int socketId, FTP_CMD strCmd, int paraInt, char* paraStr, PFV pf)
{
	  char cmd[60];
	  memset(cmd, 0x00, sizeof(cmd));
    switch (strCmd) 
    {
         case USER: {
         	   sprintf(cmd, "USER %s\r\n", (BASE_OBJECT::pLoginInfor)->user);
             if ( !ftpExcute(socketId, cmd, (char *)"331") )
             {
             	   cout<<"ftp send USER: "<<cmd<<" error!\n";
                 return false;	
             }
             break;
         }
         case PASS: {
         	   sprintf(cmd, "PASS %s\r\n", (BASE_OBJECT::pLoginInfor)->password);
             if ( !ftpExcute(socketId, cmd, (char *)"230") )
             {
             	   cout<<"ftp send PASS: "<<cmd<<" error!\n";
                 return false;	
             }
             break;
         }
         case PWD: {
         	   strcpy(cmd, "PWD\r\n");
             if ( !ftpExcute(socketId, cmd, (char *)"257") )
             {
             	   cout<<"ftp send PWD: "<<cmd<<" error!\n";
                 return false;	
             }
             break;
         }  
         case CWD: {    // cd
         	   sprintf(cmd, "CWD %s\r\n", (BASE_OBJECT::pLoginInfor)->serverPath);
             if ( !ftpExcute(socketId, cmd, (char *)"250") )
             {
             	   cout<<"ftp send CWD: "<<cmd<<" error!\n";
                 return false;	
             }
             break;
         }    
         case TYPE: {
         	   sprintf(cmd, "TYPE %c\r\n", (BASE_OBJECT::pLoginInfor)->type);
             if ( !ftpExcute(socketId, cmd, (char *)"200") )
             {
             	   cout<<"ftp send TYPE: "<<cmd<<" error!\n";
                 return false;	
             }
             break;
         }
         case LIST: {
         	   if ( !ftpListen() ) return false;
         	   strcpy(cmd, cmdBuffer);
         	   if ( !ftpExcute(socketId, cmd, (char*)"200") ) return false;
         	   if ( !ftpCmd(socketId, TYPE) ) return false;
             if ( !ftpExcute(socketId, "LIST\r\n", (char *)"150") )
             {
             	   cout<<"ftp send LIST: "<<cmd<<" error!\n";
                 return false;	
             }
             if ( ftpDownLoad(LIST_FILE_PATH) ) return false;
             break;
         }
         case SIZE: {
             if ( !ftpCmd(socketId, LIST) ) return false;
             if ( pf == NULL )
             {
                 tSize = this->getOneFileSize(LIST_FILE_PATH, paraStr);	
             }
             else
                 tSize = pf(LIST_FILE_PATH, paraStr);  
             break;
         }
         case RETR: {   //下载
             if ( !ftpListen() ) return false;
         	   strcpy(cmd, cmdBuffer);
         	   if ( !ftpExcute(socketId, cmd, (char*)"200") ) return false;
         	   if ( !ftpCmd(socketId, TYPE) ) return false;
             if ( !ftpExcute(socketId, "RETR 917.TXT\r\n", (char *)"150") )
             {
             	   cout<<"ftp send RETR 917.TXT: "<<cmd<<" error!\n";
                 return false;	
             }
             if ( !ftpDownLoad("/ztesoft/huff/ftp/dir/917.TXT") ) return false;
             break; 
         }
         case REST: {
             sprintf(cmd, "REST %d\r\n", paraInt);
             if ( !ftpExcute(socketId, cmd, (char *)"350") )
             {
             	   cout<<"ftp send REST: "<<cmd<<" error!\n";
                 return false;	
             } 
         	   break;
         }
         case PRETR: {    //多进程下载
         	   if ( !ftpCmd(socketId, SIZE, 0, paraStr, pf) ) return false;
         	   if ( !ftpCmd(socketId, REST) ) 
         	   {
         	       printf("ftp server not support serveral process load!\n");
         	       return false;	
         	   }
         	   int status, childPid;
         	   int average = tSize/PROC_COUNT;
         	   int offset = 0;
         	   int size = 0;
         	   memset(pLoadTaskInfor, 0x00, sizeof(Load_Task)*PROC_COUNT);
         	   //pthread_loadtask->pthread_load = pLoadTaskInfor;
         	   for (int i=0; i<PROC_COUNT-1; i++)
         	   {
         	       offset += size;
         	       pLoadTaskInfor[i].state = 0;
         	       pLoadTaskInfor[i].offset = offset;
         	       pLoadTaskInfor[i].size = average;
         	       sprintf(pLoadTaskInfor[i].desPath, "./%s_tmp_%d", paraStr, i);
         	       size = average;
         	   }
         	   offset += size;
         	   pLoadTaskInfor[PROC_COUNT-1].state = 0;
         	   pLoadTaskInfor[PROC_COUNT-1].offset = offset;
         	   pLoadTaskInfor[PROC_COUNT-1].size = tSize - offset;
         	   sprintf(pLoadTaskInfor[PROC_COUNT-1].desPath, "./%s_tmp_%d", paraStr, PROC_COUNT-1);
         	   
             int iProc = PROC_COUNT;
             //int procArrary[PROC_COUNT][2];
             //memset(procArrary, 0x00, sizeof(procArrary));
             pid_t pid; 

             while ( iProc-- > 0)
             {
                 pid = fork();
                 if ( pid == 0 )
                 {
                     //子进程连接下载
                     if ( !ftpInit() ) _exit(-1);
                     if ( !ftpCmd(controlSock, USER) )
	                   {
	                       printf("pid=%d send user error!\n", getpid());
	                       _exit(-1);	
	                   }
	                   printf("pid=%d USER finish!\n", getpid());
	                   
	                   if ( !ftpCmd(controlSock, PASS) )
	                   {
	                       printf("pid=%d send pass error!\n", getpid());
	                       _exit(-1);	
	                   }
	                   printf("pid=%d PASS finish!\n", getpid());
                     if ( !ftpListen() ) _exit(-1);
         	           strcpy(cmd, cmdBuffer);
         	           if ( !ftpExcute(controlSock, cmd, (char*)"200") ) _exit(-1);
         	           if ( !ftpCmd(controlSock, TYPE) ) _exit(-1);
         	           printf("pid=%d pLoadTaskInfor[%d].offset: %d\n", getpid(), iProc, pLoadTaskInfor[iProc].offset);
         	           if ( !ftpCmd(controlSock, REST, pLoadTaskInfor[iProc].offset) ) _exit(-1);
         	           	
         	           memset(cmdBuffer, 0x00, sizeof(cmdBuffer));
         	           sprintf(cmdBuffer, "RETR %s\r\n", paraStr);
         	           
                     if ( !ftpExcute(controlSock, cmdBuffer, (char *)"150") )
                     {
                     	   printf("error! pid=%d command: %s", getpid(), cmdBuffer);
                         _exit(-1);	
                     }
                     printf("pid=%d load information: offset=%d, size=%d\n", getpid(), \
                     pLoadTaskInfor[iProc].offset, pLoadTaskInfor[iProc].size);
                     if ( ftpProcDownLoad( &pLoadTaskInfor[iProc] ) ) _exit(-1);
                     ftpCmd(controlSock, QUIT);
                     _exit(0);	
                 }
                 else if ( pid > 0 )
                 {
                     pLoadTaskInfor[iProc].pid=pid;	
                     continue;
                 }
                 else
                 {
                     printf("fork error!\n");
                     perror("fork");
                     exit(0);	
                 }    	
             }
             iProc = PROC_COUNT;
             while ( iProc > 0 )
             {
                 	childPid = wait(&status);
                 	if ( WIFEXITED(status) )
                      printf("child process: %d end normal\n", childPid);
                  else
                  {
                      printf("child process end abnormal!\n");
                      printf("pid: %d exit value is: %d!\n",childPid,WEXITSTATUS(status));
                      exit(0);
                  }

                 	iProc--;
                 	/*for ( i=0; (i<PROC_COUNT) && (procArrary[i][1]==1); i++)
                 	{
                 	    printf("pid= %d running\n",procArrary[i][0]);	
                 	}*/
             }
             //子进程全部下载完成,合并下载的临时文件
             for (int i=0; i<PROC_COUNT; i++)
             {
                 if ( !copyFile(pLoadTaskInfor[i].desPath, paraStr) )
                 {
                     printf("merge files error!\n");	
                     return false;
                 }
                 remove(pLoadTaskInfor[i].desPath);
             }
             break;
             
             
             
         }
         case TRETR: {  //多线程下载
             if ( !ftpCmd(socketId, SIZE, 0, paraStr, pf) ) return false;
         	   if ( !ftpCmd(socketId, REST) ) 
         	   {
         	       printf("ftp server not support serveral process load!\n");
         	       return false;	
         	   }
         	   int status, childPid;
         	   int average = tSize/PROC_COUNT;
         	   int offset = 0;
         	   int size = 0;
         	   memset(pLoadTaskInfor, 0x00, sizeof(Load_Task)*PROC_COUNT);
         	   for (int i=0; i<PROC_COUNT-1; i++)
         	   {
         	       offset += size;
         	       pLoadTaskInfor[i].state = 0;
         	       pLoadTaskInfor[i].offset = offset;
         	       pLoadTaskInfor[i].size = average;
         	       sprintf(pLoadTaskInfor[i].desPath, "./%s_tmp_%d", paraStr, i);
         	       strcpy(pLoadTaskInfor[i].srcPath, paraStr);
         	       size = average;
         	   }
         	   offset += size;
         	   pLoadTaskInfor[PROC_COUNT-1].state = 0;
         	   pLoadTaskInfor[PROC_COUNT-1].offset = offset;
         	   pLoadTaskInfor[PROC_COUNT-1].size = tSize - offset;
         	   sprintf(pLoadTaskInfor[PROC_COUNT-1].desPath, "./%s_tmp_%d", paraStr, PROC_COUNT-1);
         	   strcpy(pLoadTaskInfor[PROC_COUNT-1].srcPath, paraStr);
         	   
         	   pthread_t t_id[PROC_COUNT];
         	   memset(t_id, 0x00, sizeof(t_id));
         	   int ret;
         	   for (int i=0; i<PROC_COUNT; i++)
         	   {
         	       ret = pthread_create(&t_id[i], NULL, FTP_CLIENT::ftpThreadFunc, &pLoadTaskInfor[i]);
         	       if ( ret != 0 )
         	       {
         	           printf("func pthread_create error!\n");
         	           perror("pthread_create");
         	           _exit(-1);	
         	       }
         	       	
         	   }
         	   // 主线程 等待其他线程结束
         	   for ( int i=0; i<PROC_COUNT; i++)
         	   {
                 pthread_join(t_id[i], NULL);

         	   }
         	   for (int i=0; i<PROC_COUNT; i++)
             {
                 if ( !copyFile(pLoadTaskInfor[i].desPath, paraStr) )
                 {
                     printf("merge files error!\n");	
                     return false;
                 }
                 remove(pLoadTaskInfor[i].desPath);
             }
         	   break;
         }
         case STOR: {  //上传
             if ( !ftpListen() ) return false;
         	   strcpy(cmd, cmdBuffer);
         	   if ( !ftpExcute(socketId, cmd, (char*)"200") ) return false;
         	   if ( !ftpCmd(socketId, TYPE) ) return false;
             if ( !ftpExcute(socketId, "STOR configfile.txt\r\n", (char *)"150") )
             {
             	   cout<<"ftp send STOR configfile.txt: "<<cmd<<" error!\n";
                 return false;	
             }
             if ( !ftpUpLoad("/ztesoft/huff/ftp/dir/917.TXT") ) return false;
             break; 
         }
         case QUIT: {
         	   strcpy(cmd, "QUIT\r\n");
             if ( !ftpExcute(socketId, cmd, (char *)"221") )
             {
             	   cout<<"ftp send QUIT: "<<cmd<<" error!\n";
                 return false;	
             }
             break;
         }
         default:
             printf("disabled command!\n");
    }
    return true;        
}

bool FTP_CLIENT :: ftpExcute(int socketId, char* sendCmd, char* returnCode, int waitTimes)
{
    if ( !ftpSendSucc(socketId, sendCmd) ) 
    {
    	  printf("command send outtime or error!: %s", sendCmd);
        return false;
    }
    if ( !ftpRecvSucc(socketId, returnCode, waitTimes) )
    {
        printf("command recv outtime or error!: %s", sendCmd);
        return false;
    }
    return true;
}

bool FTP_CLIENT :: ftpListen()
{
	  if ( (listenSock=socket(AF_INET,SOCK_STREAM,0))  0 )
    {
        perror("socket");
        return false;
    }
    memset(&clientAddr, 0x00, sizeof(clientAddr));
    clientAddr.sin_family = AF_INET;
    clientAddr.sin_addr.s_addr = inet_addr((BASE_OBJECT::pLoginInfor)->localIp);
    clientAddr.sin_port = htons((BASE_OBJECT::pLoginInfor)->localPort);
    if ( bind(listenSock, (struct sockaddr*)&clientAddr, sizeof(clientAddr))  0 )
    {
        perror("bind");
        return false;
    }
    if ( listen(listenSock, 3)  0 )
    {
        perror("listen");
        return false;
    }
    socklen_t sockLen=sizeof(clientAddr);
    if ( getsockname(listenSock, (struct sockaddr*)&clientAddr, (socklen_t*)&sockLen) != 0 )
    {
        perror("getsockname");
        return false;	
    }
    char tmpDou[10][10];
    memset(cmdBuffer, 0x00, sizeof(cmdBuffer));
    memset(tmpDou, 0x00, sizeof(tmpDou));
    getValueByFixChar((BASE_OBJECT::pLoginInfor)->localIp, tmpDou, '.');
    sprintf(cmdBuffer, "PORT %s,%s,%s,%s,%d,%d\r\n", tmpDou[0], tmpDou[1], tmpDou[2], tmpDou[3] \
    ,ntohs(clientAddr.sin_port)/256, ntohs(clientAddr.sin_port)%256);
    printf("%s\n", cmdBuffer);
    return true;	
}

bool FTP_CLIENT :: ftpDownLoad(const char* pdesPath)
{
	  if ( !ftpRecvSucc(listenSock, (char*)NULL, WAIT_TIMES, false) )
	  {
	      printf("ftpDownLoad recvdata outtime or error!\n");
	      return false;	
	  }
	  bool overFlag1 = true;
	  bool overFlag2 = true;
	  int OutTimes = 1000;
	  int flags;
	  char recvBuf[4096];
    struct timeval tv;
    tv.tv_sec=0;
	  tv.tv_usec=10;
	  fd_set transferfds;
    socklen_t sockLen=sizeof(clientAddr);
    if ( (transferSock=accept(listenSock,(struct sockaddr*)&clientAddr,(socklen_t*)&sockLen))  0 )
    {
        perror("accept");
        return false;	
    }
    flags=fcntl(transferSock,F_GETFL,0);
    fcntl(transferSock, F_SETFL, flags&~O_NONBLOCK);
    FILE *fp = NULL;
    if ( pdesPath != NULL )
    {
        fp = fopen(pdesPath, "w+");	
    }
    while ( overFlag1 && (OutTimes-- > 0) )
    {
    	  //以controlSock接受到"226xxxx"为数据传输结束标志
    	  if ( ftpRecvSucc(controlSock, (char*)"226", 1) )
    	  {
    	      overFlag1 = false;	
    	  }
    	  while ( overFlag2 )
    	  {
            memset(&transferfds, 0x00, sizeof(transferfds));
            FD_SET(transferSock, &transferfds);
            switch ( select(transferSock+1, &transferfds, NULL, NULL, &tv) ) 
            {
                case -1: {
                    printf(" ftp select error!\n");
                    return false;	
                }	
                case 0: {
                	  break;
                }
                default: {
                	
                    if ( !FD_ISSET(transferSock, &transferfds) )
                    {   
                    	  overFlag2 = false;
                        break;
                    }
                    memset(recvBuf, 0x00, sizeof(recvBuf));
                    switch ( recv(transferSock, recvBuf, sizeof(recvBuf)-1, 0) )
                    {   
                        case -1: { 	
                    	      perror("recv");	
                            return false;
                        }
                        case 0: {
                            // 对端关闭
                            overFlag2 = false;
                            break;
                        }
                        default: {
                            if ( fp != NULL )
                            {
                                fwrite(recvBuf, strlen(recvBuf), 1, fp);
                            }
                            OutTimes = 1000;  
                        }
                    }
                }
            }
        } 
        if ( !overFlag1 ) break;	    
    }       
    close(transferSock);
    close(listenSock);
    if ( fp != NULL ) fclose(fp);
    return !overFlag1;
   /* if ( OutTimes == 0 )
    {
        printf("ftpDownLoad outtime\n");
        return false;	
    }
    return true;*/
}


bool FTP_CLIENT :: ftpUpLoad(const char* pUpPath )
{
    if ( pUpPath == NULL )
    {
        printf("ftpUpLoad parameter should init!\n");
        return false;	
    } 
    int flags;
    int OutTimes;
    FILE* fp;
    bool overFlag;
    char sendBuf[DEF_BUFFER_SIZE];
    socklen_t sockLen = sizeof(clientAddr);
    if ( !ftpRecvSucc(listenSock, (char*)NULL, WAIT_TIMES, false) )
	  {
	      printf("ftpDownLoad recvdata outtime or error!\n");
	      return false;	
	  }  	
	  if ( (transferSock=accept(listenSock,(struct sockaddr*)&clientAddr,(socklen_t*)&sockLen))  0 )
    {
        perror("accept");
        return false;	
    }
    flags=fcntl(transferSock,F_GETFL,0);
    fcntl(transferSock, F_SETFL, flags&~O_NONBLOCK);
    if ( (fp=fopen(pUpPath, "r"))  0)
    {
        printf("fopen");
        return false;	
    }
    while ( !feof(fp) )
    {
        memset(sendBuf, 0x00, sizeof(sendBuf));
        if ( fgets(sendBuf, DEF_BUFFER_SIZE, fp) == NULL )
        {
            continue;
        }
        overFlag = true;
        OutTimes = WAIT_TIMES;
        while ( overFlag && (OutTimes-- > 0) )
        {
            if ( !ftpSendSucc(transferSock, sendBuf) )
            {
                printf(" ftp send fail, send again!\n");
                continue;
            }
            overFlag = false;
        }
        if ( overFlag ) 
        {
            break;	
        }   	
    }
    fclose(fp);
    close(transferSock);
    close(listenSock);
    return (overFlag==false)? ftpRecvSucc(controlSock, (char*)"226", 1000): false;
}

bool FTP_CLIENT :: ftpSendSucc(int socketId, char* sendCmd)
{
    if ( sendCmd==NULL )
    {
        return false;	
    } 
    bool overFlag = true;
    char sendBuf[4096];
    memset(sendBuf, 0x00, sizeof(sendBuf));
    strcpy(sendBuf, sendCmd);
    struct timeval tv;
    tv.tv_sec=0;
	  tv.tv_usec=10;
	  fd_set writefds;
	  while ( overFlag )
	  {
	      memset(&writefds, 0x00, sizeof(writefds));
        FD_SET(socketId, &writefds);
        switch ( select(socketId+1, NULL, &writefds, NULL, &tv) )
        {
            case -1: {
                perror("select");
                return false;
            }	
            case 0: {
                continue;	
            }
            default: {
                if ( !FD_ISSET(socketId, &writefds) )
                    continue;
                if ( send(socketId, sendBuf, strlen(sendBuf), 0) != strlen(sendBuf) )
                {
                    perror("send");
                    return false;
                }
                overFlag = false;
            }
        }
             	
	  }
	  return true;
}

bool FTP_CLIENT :: ftpRecvSucc(int socketId, char* returnCode, int waitTimes, bool IsNeedRecv)
{
	  int ret = 0;
	  int OutTimes = waitTimes;
    char recvBuf[4096], firstRecv[4096];
    memset(firstRecv, 0x00, sizeof(firstRecv));
    struct timeval tv;
    tv.tv_sec=0;
	  tv.tv_usec=10;
	  fd_set readfds;
	  //printf("ftpRecvSucc1 waiTimes=%d\n", waitTimes);
	  if ( IsNeedRecv )
	  {
	      while ( (OutTimes--) > 0 )
        {
             memset(&readfds, 0x00, sizeof(readfds));
             FD_SET(socketId, &readfds);
             switch ( select(socketId+1, &readfds, NULL, NULL, &tv) )
             {
                 case -1: {
                     perror("select");
                     return false;
                 }
                 case 0: {
                     continue;
                 }
                 default: {
                     if ( !FD_ISSET(socketId, &readfds) )
                         continue;
                     memset(recvBuf, 0x00, sizeof(recvBuf));
                     switch ( recv(socketId, recvBuf, sizeof(recvBuf)-1, 0) )
                     {
                         case -1: {
                             perror("recv");
                             return false;
                         }	
                         case 0: {
                         	   // 对端关闭
                             OutTimes = 0;	
                         }
                         default: {
                             if ( ret == 0 )	
                             {   
                             	   strcpy(firstRecv, recvBuf);
                             	   ret = 1;
                             }
                             printf("%s\n", recvBuf);
                             if ( strlen(recvBuf) == (sizeof(recvBuf)-1) )
                             {
                                 OutTimes = waitTimes;
                                 continue;	
                             }
                             OutTimes--;    	
                         }
                     	
                     } 
                 } 
             }
        }
    }
    else
    {
        while ( (OutTimes--) > 0 )
        {
             memset(&readfds, 0x00, sizeof(readfds));
             FD_SET(socketId, &readfds);
             switch ( select(socketId+1, &readfds, NULL, NULL, &tv) )
             {
                 case -1: {
                     perror("select");
                     return false;
                 }
                 case 0: {
                     continue;
                 }
                 default: {
                     if ( !FD_ISSET(socketId, &readfds) )
                         continue;
                     OutTimes = 0;
                 }
             }             
         }   	
    }
    //printf("ftpRecvSucc2 waiTimes=%d\n", OutTimes);
    if ( returnCode == NULL ) return true;
    return strncmp(firstRecv, returnCode, strlen(returnCode))==0 ?true :false;
}    	
	
bool FTP_CLIENT :: ftpProcDownLoad(const Load_Task* pInfor)
{
    if ( (pInfor==NULL) || (pInfor->desPath==NULL) ) return false;
    int OutTimes = 1000;
	  int flags;
	  int len = 0;
	  int lenAcm = pInfor->size;
	  char recvBuf[4096];
	  bool overFlag = true;
    struct timeval tv;
    tv.tv_sec=0;
	  tv.tv_usec=10;
	  fd_set transferfds;
    socklen_t sockLen=sizeof(clientAddr);
    if ( (transferSock=accept(this->listenSock,(struct sockaddr*)&clientAddr,(socklen_t*)&sockLen))  0 )
    {
        perror("accept");
        return false;	
    }
    flags=fcntl(transferSock,F_GETFL,0);
    fcntl(transferSock, F_SETFL, flags&~O_NONBLOCK);
    FILE *fp = fopen(pInfor->desPath, "w+");
    while ( overFlag && (OutTimes--)>0 )
    {
        memset(&transferfds, 0x00, sizeof(transferfds));
        FD_SET(transferSock, &transferfds);
        switch ( select(transferSock+1, &transferfds, NULL, NULL, &tv) ) 
        {
            case -1: {
                printf(" ftp select error!\n");
                return false;	
            }	
            case 0: {
            	  break;
            }
            default: {
            	
                if ( !FD_ISSET(transferSock, &transferfds) )
                {   
                    break;
                }
                memset(recvBuf, 0x00, sizeof(recvBuf));
                len = recv(transferSock, recvBuf, sizeof(recvBuf)-1, 0);
                if ( len > 0 )
                {
                    len = (len>lenAcm) ?lenAcm :len;
                    fwrite(recvBuf, len, 1, fp);
                    lenAcm = lenAcm - len;
                    if ( lenAcm == 0 ) overFlag = false;
                    OutTimes = 1000;
                }
                else if ( len == 0 )
                {
                    cout<<"lamble1对端关闭\n"<<endl;
                    fclose(fp);
                    return false;
                }
                else
                {
                    perror("recv");
                    fclose(fp);
                    return false;	
                }   
            }
        }
    }
    fclose(fp);
    return true;
        	
}	

void* FTP_CLIENT :: ftpThreadFunc(void* p)
{
    FTP_CLIENT *thread_ftp = new FTP_CLIENT();
    Load_Task* pthread = (Load_Task*)p;
    printf("load task information: srcfilename=%s, offset=%d, size=%d, desfilename=%s\n", \
    pthread->srcPath, pthread->offset, pthread->size, \
    pthread->desPath);
    if ( !thread_ftp->ftpInit() ) 
    {
    	  printf("thread_ftp ftpInit() error!\n");
        _exit(-1);
    }
    if ( !thread_ftp->ftpCmd(thread_ftp->controlSock, USER) )
	  {
	      printf("send user error!\n");
	      _exit(-1);	
	  }
	  
	  if ( !thread_ftp->ftpCmd(thread_ftp->controlSock, PASS) )
	  {
	      printf("send pass error!\n");
	      _exit(-1);	
	  }
    if ( !thread_ftp->ftpListen() ) 
    {
    	  printf("thread_ftp ftplisten() error!\n"); 
    	  _exit(-1);
    }
    if ( !thread_ftp->ftpExcute(thread_ftp->controlSock, thread_ftp->cmdBuffer, (char*)"200") ) 
    {
        printf("thread ftpexcute port error!\n");
        _exit(-1);
    }
    if ( !thread_ftp->ftpCmd(thread_ftp->controlSock, TYPE) ) 
    {
    	  printf("thread ftpcmd type error\n");
        _exit(-1);
    }
   
    if ( !thread_ftp->ftpCmd(thread_ftp->controlSock, REST, pthread->offset) ) 
    {
        printf("thread_ftp ftpcmd REST error!\n");
        _exit(-1); 
    }
    memset(thread_ftp->cmdBuffer, 0x00, sizeof(thread_ftp->cmdBuffer));
    sprintf(thread_ftp->cmdBuffer, "RETR %s\r\n", pthread->srcPath);
    if ( !thread_ftp->ftpExcute(thread_ftp->controlSock, thread_ftp->cmdBuffer, (char *)"150", 1000) )
    {
    	   printf("error! command: %s\n", thread_ftp->cmdBuffer);
        _exit(-1);	
    }
    if ( !thread_ftp->ftpProcDownLoad( pthread ) ) 
    {
        printf("error! when ftpProcDownLoad func\n");
        _exit(-1);
    }
    //忽略超时
    thread_ftp->ftpCmd(thread_ftp->controlSock, QUIT); 

    delete thread_ftp;
    //thread_ftp->ftpCmd(thread_ftp->controlSock, QUIT);
    
    
}