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

📄 client.cpp

📁 FTP是文件传输协议英文的简称。本程序介绍了FTP协议的原理和实现方法。
💻 CPP
📖 第 1 页 / 共 2 页
字号:

//	str=buffer;
	if(str.find("226")!=std::string::npos)
		bWaitRetCode=FALSE;
	
	if(ReceiveFile(listenSock,currentDir, filename, FALSE, bWaitRetCode)==FALSE)
	{
		cout<<"Error retrieve file "<<filename<<endl;
		return 1;
	}
	return 0;
}

int STOR(const char* currentDir, const char* filename)
{
	char buffer[BUFFER_BLOCK_SIZE];
	int retCode;
	SOCKET listenSock;
	std::string str;
	BOOL bWaitRetCode=TRUE;

	retCode=TYPEA();
	DEAL_RETURN_CODE(retCode);
	retCode=PORT(&listenSock);
	DEAL_RETURN_CODE(retCode);

	sprintf(buffer,"STOR %s\r\n",filename);
	cout<<buffer;
	send(commSock,buffer,strlen(buffer),0);
	retCode=GetResponseCode(150,str);
	DEAL_RETURN_CODE(retCode);

	if(SendFile(listenSock,currentDir,filename)==FALSE)
	{
		cout<<"Error send file "<<filename<<endl;
		return -1;
	}

	retCode=DIR();
	DEAL_RETURN_CODE(retCode);
	return 0;
}

int DIR()
{
	char buffer[BUFFER_BLOCK_SIZE];
	int retCode;
	ifstream file;
	SOCKET listenSock;
	int sizeAddr=sizeof(sockaddr);
	BOOL bDir;
	std::string name;
	std::string::size_type pos=0;
	BOOL bWaitRetCode=TRUE;
	std::string str;

	DIRArray.clear();
	FILEArray.clear();
	LENGTHArray.clear();

	retCode=PWD();
	DEAL_RETURN_CODE(retCode);
	retCode=TYPEA();
	DEAL_RETURN_CODE(retCode);
	retCode=PORT(&listenSock);
	DEAL_RETURN_CODE(retCode);

	strcpy(buffer,"LIST\r\n");
	cout<<buffer;
	send(commSock,buffer,strlen(buffer),0);
	retCode=GetResponseCode(150,str);
	DEAL_RETURN_CODE(retCode);

	name=buffer;
	if(name.find("226")!=std::string::npos)
		bWaitRetCode=FALSE;

	//here, we confront some problem. if buffer has the content of 226 Transfer complete
	//in ReceiveFile, we should not recv the return code of these words.
	//This phenominent happend only when the list is very short.
	if(ReceiveFile(listenSock,".","list.txt", TRUE, bWaitRetCode)==FALSE)
	{
		cout<<"DIR error"<<endl;
		return -1;
	}
	
	file.open("list.txt");//ios::binary
	buffer[0]='\0';
	while(!file.eof())
	{
		file>>buffer;	//file/direcotory's read/write/execute property
		if(buffer[0]=='\0')
			break;
		bDir=buffer[0]=='d';
		file>>buffer;	//user count
		file>>buffer;	//user
		file>>buffer;	//group
		file>>buffer;	//size
		if(!bDir)
			LENGTHArray.push_back(atol(buffer));
		file>>buffer;	//month
		file>>buffer;	//date
		file>>buffer;	//year
		file.getline(buffer,BUFFER_BLOCK_SIZE);//all left are names of file or directory
		name= std::string(buffer);
		//erase blank space 
		pos=0;
		while((pos=name.find(" ", pos))!=std::string::npos)
		{
			if(pos==0)
				name.replace(pos,1, "");
			else
				break;
		}
		if(bDir)
		{
			if(name!=std::string(".") && name!=std::string(".."))
				DIRArray.push_back(name);
		}
		else
			FILEArray.push_back(name);
		buffer[0]='\0';
	}
	file.close();
	return 0;
}

int DELE(const char* filename)
{
	char buffer[BUFFER_BLOCK_SIZE];
	int retCode;
	std::string str;
	sprintf(buffer,"DELE %s\r\n",filename);
	cout<<buffer;
	send(commSock,buffer,strlen(buffer),0);

	retCode=GetResponseCode(250,str);
	DEAL_RETURN_CODE(retCode);
	
	retCode=TYPEA();
	DEAL_RETURN_CODE(retCode);

	retCode=DIR();
	DEAL_RETURN_CODE(retCode);
	return 0;
}

int RMD(const char* dirname)
{
	char buffer[BUFFER_BLOCK_SIZE];
	std::string str;
	int retCode;
	sprintf(buffer,"RMD %s\r\n",dirname);
	cout<<buffer;
	send(commSock,buffer,strlen(buffer),0);

	retCode=GetResponseCode(250,str);
	DEAL_RETURN_CODE(retCode);

	retCode=TYPEA();
	DEAL_RETURN_CODE(retCode);

	retCode=DIR();
	DEAL_RETURN_CODE(retCode);
	return 0;
}

int DeleteWholeDirectory(const char *dirname)
{
	int retCode;
	int i;
	std::vector<std::string> dirArrays;
	retCode=CWD(dirname);
	DEAL_RETURN_CODE(retCode);
	retCode=PWD();
	DEAL_RETURN_CODE(retCode);
	retCode=DIR();
	DEAL_RETURN_CODE(retCode);
	dirArrays=FILEArray;
	for(i=0;i<dirArrays.size();i++)
	{
		retCode=DELE(dirArrays[i].c_str());
		DEAL_RETURN_CODE(retCode);
	}
	dirArrays=DIRArray;
	for(i=0;i<dirArrays.size();i++)
	{
		retCode=DeleteWholeDirectory(dirArrays[i].c_str());
		DEAL_RETURN_CODE(retCode);
		retCode=CWD("..");
		DEAL_RETURN_CODE(retCode);
		retCode=RMD(dirArrays[i].c_str());
		DEAL_RETURN_CODE(retCode);
	}
	return 0;
}

int DownloadWholeDirectory(const char * parentDir, const char *dirname)
{
	int retCode;
	int i;
	std::vector<std::string> dirArrays;
	std::string dir;
	dir=std::string(parentDir)+"//"+dirname;
	if(!CreateDirectory(dir.c_str(), NULL))
	{
		retCode=GetLastError();
		if(retCode!=183)
		{
			cout<<"Couldn't create new directory: "<<retCode<<endl;
			return -1;
		}
	}
	retCode=CWD(dirname);
	DEAL_RETURN_CODE(retCode);
	retCode=PWD();
	DEAL_RETURN_CODE(retCode);
	retCode=DIR();
	DEAL_RETURN_CODE(retCode);
	for(i=0;i<FILEArray.size();i++)
	{
		//FILEArray[i]=std::string(dirname)+FILEArray[i];
		retCode=RETR(dir.c_str(), FILEArray[i].c_str());
		DEAL_RETURN_CODE(retCode);
	}
//	retCode=DIR();
//	DEAL_RETURN_CODE(retCode);
//	assert(FILEArray.size()==0);
	dirArrays.assign(DIRArray.begin(),DIRArray.end());
	for(i=0;i<dirArrays.size();i++)
	{
		//dirArrays[i]=std::string(dirname)+dirArrays[i];
		retCode=DownloadWholeDirectory(dir.c_str(), dirArrays[i].c_str());
		DEAL_RETURN_CODE(retCode);
		retCode=CWD("..");			//run to father node
		DEAL_RETURN_CODE(retCode);
	}
	return 0;
}

int UploadWholeDirectory(const char* parentDir, const char* dirname)
{
	int retCode;
	WIN32_FIND_DATA FileData; 
	HANDLE hSearch;
	std::string localDir=std::string(parentDir)+"\\"+dirname;
	std::string dir=localDir+"\\*.*";

	hSearch = FindFirstFile(dir.c_str(), &FileData); 
	if (hSearch == INVALID_HANDLE_VALUE) 
		return 0;

	retCode=MKD(dirname);
	DEAL_RETURN_CODE(retCode);
	retCode=CWD(dirname);
	DEAL_RETURN_CODE(retCode);
	retCode=PWD();
	DEAL_RETURN_CODE(retCode);
	retCode=DIR();
	DEAL_RETURN_CODE(retCode);
	
	while (1) 
	{
		if(FileData.dwFileAttributes==FILE_ATTRIBUTE_DIRECTORY)
		{
			if(strcmp(FileData.cFileName,".")!=0 &&
				strcmp(FileData.cFileName,"..")!=0)
			{
				retCode=UploadWholeDirectory(localDir.c_str(), FileData.cFileName);
				DEAL_RETURN_CODE(retCode);
			}
		}
		else 
		{
			retCode=STOR(localDir.c_str(), FileData.cFileName);
			DEAL_RETURN_CODE(retCode);
		}
		if (!FindNextFile(hSearch, &FileData)) 
			break;
	}
	if(!FindClose(hSearch))
		cout<<"Couldn't close search handle."<<endl;
	retCode=CWD("..");
	DEAL_RETURN_CODE(retCode);
	return 0;
}

//-1 invalid name
//0  valid file
//1  valid directory
int IsValidLocalFileOrDirectory(const char* name)
{
	WIN32_FIND_DATA FileData;
	HANDLE hSearch;
	std::string dir=".\\";
	dir+=name;
	hSearch = FindFirstFile(dir.c_str(), &FileData);
	if (hSearch == INVALID_HANDLE_VALUE)
		return -1;
	if(!FindClose(hSearch))
	{
		cout<<"Couldn't close search handle."<<endl;
		return -1;
	}

	if(FileData.dwFileAttributes==FILE_ATTRIBUTE_DIRECTORY)
		return 1;
	else
		return 0;
}

BOOL SendFile(SOCKET listenSock,const char* currentDir, const char* filename)
{
	sockaddr_in clientAddr;
	SOCKET clientSock;
	int sizeAddr=sizeof(sockaddr);
	ifstream file;
	filebuf *fB;
	int length;
	int left;
	char buffer[BUFFER_BLOCK_SIZE];
	std::string str;
	
	if((clientSock=accept(listenSock,(struct sockaddr*)&clientAddr,&sizeAddr))==INVALID_SOCKET)
	{
		cerr<<"Accept error"<<endl;
		closesocket(listenSock);
		return FALSE;
	}
	closesocket(listenSock);
	
	str=std::string(currentDir)+"//"+filename;
	file.open(str.c_str(),ios::binary);
	if(file.fail())
	{
		cerr<<"Fail opening file "<<filename<<endl;
		closesocket(listenSock);
		return FALSE;
	}
	fB=file.rdbuf();
	length=fB->seekoff(0,ios::end,ios::in)-fB->seekoff(0,ios::beg,ios::in);
	fB->seekoff(0,ios::beg,ios::in);
	left=length;
	while(left>0)
	{
		//read buffer
		file.read(buffer,BUFFER_BLOCK_SIZE<left?BUFFER_BLOCK_SIZE:left);
		//send buffer
		if(send(clientSock,buffer,BUFFER_BLOCK_SIZE<left?BUFFER_BLOCK_SIZE:left,0)==SOCKET_ERROR)
		{
			closesocket(clientSock);
			return FALSE;
		}
		left-=BUFFER_BLOCK_SIZE;
		cout<<".";
	}
	cout<<endl;
	file.close();
	closesocket(clientSock); //it's a end signal

	if(GetResponseCode(226,str)!=0)
		return FALSE;

	return TRUE;
}

BOOL ReceiveFile(SOCKET listenSock,const char* currentDir, const char* filename , BOOL bPrint, BOOL bWaitRetCode)
{
	SOCKET clientSock;
	sockaddr_in clientAddr;
	int sizeAddr=sizeof(sockaddr);
	ofstream file;
	char buffer[BUFFER_BLOCK_SIZE+1];
	int retCode;
	std::string str;
	if((clientSock=accept(listenSock,(struct sockaddr*)&clientAddr,&sizeAddr))==INVALID_SOCKET)
	{
		cerr<<"Accept error: "<<GetLastError()<<endl;
		closesocket(listenSock);
		return FALSE;
	}

	closesocket(listenSock);

	//打开要发送的文件
	str=std::string(currentDir)+"//"+filename;
	file.open(str.c_str(),ios::binary);
	if(file.fail())
	{
		cerr<<"Fail opening file "<<filename<<endl;
		closesocket(clientSock);
		return FALSE;
	}
	while(1)
	{
		retCode=recv(clientSock,buffer,BUFFER_BLOCK_SIZE,0);
		if(retCode==SOCKET_ERROR)
		{
			file.close();
			closesocket(clientSock);
			return FALSE;
		}
		if(retCode==0)
			break;
		file.write(buffer,retCode);
		buffer[retCode]='\0';
		if(bPrint)
			cout<<buffer;
		else
			cout<<".";
		cout.flush();
	}
	file.close();
	closesocket(clientSock); //it's a end signal

	if(bWaitRetCode)
	{
		if(GetResponseCode(226,str)!=0)
			return FALSE;
	}
	return TRUE;
}


int DownloadUnfinishedFiles(const char *filename)
{
	SOCKET clientSock,listenSock;
	sockaddr_in clientAddr;
	int sizeAddr=sizeof(sockaddr);
	ofstream file;
	char buffer[BUFFER_BLOCK_SIZE+1];
	int retCode;
	BOOL bWaitRetCode=TRUE;
	std::string str;
	filebuf *fB;
	int length;

	file.open(filename,(ios::binary|ios::app|ios::out)&(~ios::trunc));
	if(file.fail())
	{
		cerr<<"Fail opening file "<<filename<<endl;
		return 1;
	}	
	fB=file.rdbuf();
	length=fB->seekoff(0,ios::end,ios::out)-fB->seekoff(0,ios::beg,ios::out);
	fB->seekoff(0,ios::end,ios::out);
	
	retCode=TYPEA();
	DEAL_RETURN_CODE(retCode);
	retCode=PORT(&listenSock);
	DEAL_RETURN_CODE(retCode);
	retCode=REST(length);
	DEAL_RETURN_CODE(retCode);

	sprintf(buffer,"RETR %s\r\n",filename);
	cout<<buffer;
	send(commSock,buffer,strlen(buffer),0);
	retCode=GetResponseCode(150,str);
	DEAL_RETURN_CODE(retCode);

	if(str.find("226")!=std::string::npos)
		bWaitRetCode=FALSE;

	if((clientSock=accept(listenSock,(struct sockaddr*)&clientAddr,&sizeAddr))==INVALID_SOCKET)
	{
		cerr<<"Accept error: "<<GetLastError()<<endl;
		closesocket(listenSock);
		return 1;
	}
	closesocket(listenSock);

	while(1)
	{
		retCode=recv(clientSock,buffer,BUFFER_BLOCK_SIZE,0);
		if(retCode==SOCKET_ERROR)
		{
			file.close();
			closesocket(clientSock);
			return 1;
		}
		if(retCode==0)
			break;
		file.write(buffer,retCode);
		buffer[retCode]='\0';
		cout<<".";
		cout.flush();
	}
	cout<<endl;
	closesocket(clientSock);
	file.close();

	if(bWaitRetCode)
	{
		retCode=GetResponseCode(226,str);
		DEAL_RETURN_CODE(retCode);
	}

	retCode=REST(0);
	DEAL_RETURN_CODE(retCode);
	return 0;
}

⌨️ 快捷键说明

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