⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tftpclient.cpp

📁 FTPClient的实现文件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "TFTPClient.h"
#include <strings.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#ifndef INADDR_NONE
#define INADDR_NONE (in_addr_t)0xffffffff
#endif

TFTPClient::TFTPClient() 
{
	/* 默认超时设为60秒 */
	m_iTimeOut=(OPTVAL)60;
	m_iMaxWaitTime = (OPTVAL)60;
	/* 默认为不支持断点续传 */
	m_iResume=NO;
	/* 获取主机字节序 */
	m_IsBigOrder=IsBigOrder();
}
/********************************************************
* function:FTPOption
* purpose:设置ftp选项
* return:
*********************************************************/
int  TFTPClient::FTPOption(FTPOPTION option, OPTVAL value){
	switch(option){
	/*超时设置*/
	case TIMEOUT:
		m_iTimeOut = value;
		break;
	case MAXWAITTIME:
		m_iMaxWaitTime = value;
		break;
	/*文件传输数据类型设置*/
	case DATATYPE:
		/* 设置传输数据类型 */
		if( value == BINARY )
			return FTPCommand("TYPE I\r\n"); 
		else if( value == ASCII )
			return FTPCommand("TYPE A\r\n");
		else {
			printf(" DATATYPE does not exist\n");
			return -1;
		}
	/*断点续传设置*/
	case RESUME:
		m_iResume=value;
		break;
	default:
		printf(" option does not exist\n");
		return -1;
	}
	return 0;
}

TFTPClient::~TFTPClient()
{

}

/********************************************************
* function:FTPLogIn
* purpose:登录到FTP Server
* return:   FTP_SUCCEED 成功 ,        FTP_FAIL 失败
*
*********************************************************/

int TFTPClient::FTPLogin(const char *strServer, const char *strUser, const char *strPassword)
{
	struct hostent          *lpHostEnt;          /* Internet host information structure*/
	struct sockaddr_in      sockAddr;            /* Socket address structure  */

	sockAddr.sin_family = AF_INET;
	sockAddr.sin_port = htons(21);

  if (inet_pton(AF_INET, strServer, &sockAddr.sin_addr) <= 0)
  {
  	if (!(lpHostEnt = gethostbyname(strServer))){
			perror("gethostbyname inet_pton error!");
			return -1;
		}
		sockAddr.sin_addr = *((struct in_addr *)*lpHostEnt->h_addr_list);
  }

	if ((m_hControlChannel = socket(AF_INET, SOCK_STREAM, 0)) < 0)	{
		perror("socket() create ");
		return -1;
	}	
	time_t ttTmp = time(NULL);
	if(connect(m_hControlChannel, reinterpret_cast<struct sockaddr *>(&sockAddr), sizeof(sockAddr)) < 0){
		close(m_hControlChannel);
		perror("connect()");
		if(time(NULL) - ttTmp < 5 )	return -11;
		else	return FTP_E_CONNECT;
	}
	
	int ret= WaitResult(m_hControlChannel);
	if(ret != 220){
		close(m_hControlChannel);
		return -11;
	}
	
	/* 发送user命令 */
	char buf[256];
	snprintf(buf, sizeof(buf), (char*)"USER %s\r\n",strUser);
	
	int len=strlen(buf);
	ret = Write(m_hControlChannel, buf, &len);
	if( ret < 0 || len != strlen(buf) ){
		close(m_hControlChannel);
		return FTP_E_CONNECT;
	}
	ret = WaitResult(m_hControlChannel);
	if(ret != 331){
		close(m_hControlChannel);
		return FTP_E_USER;
	}
	/*发送pass命令*/
	snprintf(buf, sizeof(buf), (char*)"PASS %s\r\n", strPassword);
	len = strlen(buf);
	ret = Write(m_hControlChannel,buf,&len);
	if( ret < 0 || len != strlen(buf) ) {
		close(m_hControlChannel);
		return FTP_E_CONNECT;
	}
	ret = WaitResult(m_hControlChannel);
	if(ret != 230){
		close(m_hControlChannel);
		return FTP_E_PASS;
	}
	return 0;
}
/********************************************************
* function:CreateListenSocket
* purpose:create listen socket (let it choose the port) & start the socket listening
* return:   FTP_SUCCEED 成功 ,        FTP_FAIL 失败
*
********************************************************/
int TFTPClient::CreateListenSocket()
{
	struct sockaddr_in sockAddr; 
	/* 分配套接口 */
	if ((m_hListenSocket = socket( AF_INET, SOCK_STREAM, 0 ))<0){
		perror("socket()");
		return -1;
	}
	
	/* Let the system assign a socket address                */
	sockAddr.sin_family = AF_INET;
	sockAddr.sin_port = htons(0);           /* htons() is just a reminder.*/
	sockAddr.sin_addr.s_addr = INADDR_ANY;
	
	/* Bind the socket       */
	if (bind(m_hListenSocket, reinterpret_cast<struct sockaddr *>(&sockAddr), sizeof(sockAddr))){
		close(m_hListenSocket);
		perror("bind()");
		return -1;
	}
	
	int tmpint = fcntl(m_hListenSocket, F_GETFL, 0);
	
	if (fcntl(m_hListenSocket, F_SETFL, tmpint|O_NONBLOCK) < 0){
		close(m_hListenSocket);
		perror("fcntl");
		return -1;
	}
	/* Listen for the FTP server connection */
	if (listen(m_hListenSocket, 3)){
		close(m_hListenSocket);
		perror("listen()");
		return -1;
	}
	
	/* Ask the server to connect to the port monitored by the listener socket*/
	#if defined(_AIX) || defined(__linux__)
		socklen_t iLength = sizeof(sockAddr);
	#else
		int iLength = sizeof(sockAddr);
	#endif

	/* 发送PORT命令 */
	/* Get port number */
	if(getsockname(m_hListenSocket, reinterpret_cast<struct sockaddr *>(&sockAddr),  &iLength) <0){
		close(m_hListenSocket);
		printf("getsockname");
		return -1;
	}
	int iPort=sockAddr.sin_port;
	/* Get local ip address  */
	if(getsockname(m_hControlChannel, reinterpret_cast<struct sockaddr *>(&sockAddr), &iLength) <0){
		close(m_hListenSocket);
		printf("getsockname");
		return -1;
	}
	char strCmd[128];
	//PORT h1,h2,h3,h4,p1,p2
	//where h1 is the high order 8 bits of the internet host  address.

	if(m_IsBigOrder == 1)
		sprintf(strCmd, "PORT %d,%d,%d,%d,%d,%d\r\n",
			(sockAddr.sin_addr.s_addr>>24) & 0x000000ff,
			(sockAddr.sin_addr.s_addr>>16) & 0x000000ff,
			(sockAddr.sin_addr.s_addr>>8) & 0x000000ff,
			(sockAddr.sin_addr.s_addr) & 0x000000ff,
			iPort >> 8,
			iPort & 0xFF);
	else
		sprintf(strCmd, "PORT %d,%d,%d,%d,%d,%d\r\n",
			(sockAddr.sin_addr.s_addr) & 0x000000ff,
			(sockAddr.sin_addr.s_addr>>8) & 0x000000ff,
			(sockAddr.sin_addr.s_addr>>16) & 0x000000ff,
			(sockAddr.sin_addr.s_addr>>24) & 0x000000ff,
			iPort & 0xFF,
			iPort >>8 );

	int len=strlen(strCmd);
	int ret = Write(m_hControlChannel,strCmd,&len);
	if( ret < 0 || len != strlen(strCmd) ){
		close(m_hListenSocket);
		return -1;
	}

	/* here we should get the result: 200 PORT command successful. */
	ret = WaitResult(m_hControlChannel);
	if(ret != 200){
		close(m_hListenSocket);
		return -1;
	}	
	return 0;
}
/*
 *get a file from remote ftp server
 *return 0 -- get successfully
 *return -1 -- some error !
 *return -5 -- remote file doesn't exist
 */
int TFTPClient::GetFile(const char* strRemote, const char* strLocal )
{
	if( CreateListenSocket() < 0 )
		return -1;
        	const char* cpLocalFile = (strLocal == NULL ? strRemote : strLocal);
 	char buf[10240];
	if( m_iResume == YES ) {
	        	struct stat filestat;
		if(stat(cpLocalFile, &filestat) < 0){
			filestat.st_size = 0;
		}
		snprintf(buf, sizeof(buf), (char*)"REST %d\r\n", filestat.st_size);
	
		int len = strlen(buf);
		int ret = Write(m_hControlChannel,buf,&len);
		if( ret < 0 || len != strlen(buf) ){
			close(m_hListenSocket);
			return -2;
		}
		// 如果服务器支持断点续传,那么返回应答应是:
		// 350 Restarting at 0. Send STORE or RETRIEVE to initiate transfer.
		ret = WaitResult(m_hControlChannel);
		if( ret < 0 ) {
			close(m_hListenSocket);
			return -3;
		}
		if( ret/100 != 3 ) {
			m_iResume = NO;
			printf("FTP server does not support rest command\n");
		}	
	}
	
	snprintf(buf, sizeof(buf), (char*)"RETR %s\r\n", strRemote);
	int len = strlen(buf);
	int ret = Write(m_hControlChannel, buf, &len);
	if( ret < 0 || len != strlen(buf) ){
		close(m_hListenSocket);
		return -4;
	}
	
	ret = Accept(m_hListenSocket, NULL, NULL);
	close(m_hListenSocket);
	if(ret > 0 ){
		m_hDataSocket=ret;
	}
	else {		
		ret = WaitResult(m_hControlChannel);
		if(ret == 550 ) return -5 ; 
		return -6;
	}

	ret = WaitResult(m_hControlChannel);
	if(ret != 150){
		close(m_hDataSocket);
		return -7;
	}
	int fd;
	if((fd = open( cpLocalFile, m_iResume == YES ? O_CREAT|O_APPEND|O_RDWR : O_CREAT|O_TRUNC|O_RDWR, 0660)) < 0 ){
		close( m_hDataSocket) ;
		perror("open file");
		return -8;
	}

	int timer = time(0);
	int totallen = 0;
	int tmptime;
	while(1){
		tmptime = time(0);
		if( tmptime >= timer + m_iMaxWaitTime ){
			close(m_hDataSocket);
			printf("time out %d seconds when get a remote file\n", m_iMaxWaitTime);
			close(fd);
			return -9;
		}
		len = 10240;
		ret = Read(m_hDataSocket, buf, &len);	
		if(ret != 0 )
			break;
		else if( len == 0 )
			continue;
	
		timer = tmptime;
		if( write( fd, buf, len) < len) {
			perror("write file");
			close(fd);
			close(m_hDataSocket);
			return -10;
		}
		totallen += len;
	}

	close(fd);	
	close(m_hDataSocket);
	ret = WaitResult(m_hControlChannel);
	if( ret == 226 ) return 0 ;
	return -11;
}
/*
 *put a file to remote ftp server
 *return 0 -- put successfully
 *return -1 -- some error !
 *return -3 -- file doesn't exist
 */
int TFTPClient::PutFile(const char* strLocal, const char* strRemote)
{
	if( CreateListenSocket() < 0 )
		return -1;
 
       	struct stat filestat;

        const char* cpRemoteFile = (strRemote == NULL ? strLocal : strRemote);

	char buf[10240];
	sprintf( buf, "STOR %s\r\n", cpRemoteFile);
	int len = strlen(buf);
	int ret = Write(m_hControlChannel,buf,&len);
	if( ret < 0 || len != strlen(buf) ) {
		close(m_hListenSocket);
		return -2;
	}

	ret=Accept(m_hListenSocket,NULL,NULL);
	close(m_hListenSocket);
	if(ret > 0 )
		m_hDataSocket=ret;
	else {		
		ret = WaitResult(m_hControlChannel);
		if( ret == 550 ) return -3 ;
		return -4;
	}

	ret = WaitResult(m_hControlChannel);
	if(ret != 150){
		close(m_hDataSocket);
		return -5;
	}
	int fd;
	if((fd = open(strLocal, O_RDONLY, 0660)) < 0) {
		close(m_hDataSocket);
		perror("open file");
		return -6;
	}
	if( fstat(fd, &filestat) < 0) {
		printf("File:%s stat error!\n",strLocal);
		close(m_hDataSocket);
		close(fd);
		return -7;
	} 
	int totallen = filestat.st_size;
	int timer = time(0);
	ret = 0;
	int tmplen,tmptime;
	while(totallen > 0) {
		tmptime = time(0);
		if(tmptime >= timer + m_iMaxWaitTime ){
			printf("time out %d seconds in putfile\n", m_iMaxWaitTime);
			ret = -1;
			break;
		}
		if(totallen < 256)
			len = totallen;
		else
			len = 256;

		ret=read( fd, buf, len);
		if(ret<=0)
			break;
		else 
			tmplen = len = ret;
	
		ret=Write(m_hDataSocket,buf,&tmplen);
		if( ret < 0 || tmplen != len ){
			close(fd);
			close(m_hDataSocket);
			return -8;
		}
	
		timer = tmptime;
		totallen -= len;
	}

	close(fd);	
	close(m_hDataSocket);
	ret=WaitResult(m_hControlChannel);
	if( ret != 226 ) return -9;
	return 0;
}

/********************************************************
* function:FTPCmd
* purpose:执行ftp服务器端命令
* return:   FTP_SUCCEED 成功 ,        FTP_FAIL 失败
*CHDIR, CDUP, DEL, LS, PWD, MKDIR, RMDIR,SYSTYPE
*********************************************************/
int TFTPClient::FTPCmd(FTPCMDTYPE cmd, const char* cmdvalue, char* returnvalue, int retmaxsize)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -