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);
}