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

📄 client.cpp

📁 c++编写的FTP服务器和客户端程序
💻 CPP
字号:
#include <fstream>
#include <sstream>
#include "client.h"
using namespace std;

Client::Client(const string& addr, int port) {
	TcpFactory factory;
	factory.setDest(addr, port);
	pi = factory.connect();

	string text;
	int reply = getReply(text);

	if(reply==120)
		reply = getReply(text);

	if(reply!=220) throw "Connect to server failed";

	passive = false;
	dataType = Tcp::ASCII;
}

Client::~Client() {
	delete pi;
}

int Client::user(const string& username) {
	string text = "USER " + username;
	pi->write(text);
	cout << "\t[C] " << text << endl;

	return getReply(text);
}

int Client::pass(const string& password) {
	string text = "PASS " + password;
	pi->write(text);
	cout << "\t[C] PASS (hidden)" << endl;

	return getReply(text);
}

int Client::cwd(const string& path) {
	string text = "CWD " + path;
	pi->write(text);
	cout << "\t[C] " << text << endl;

	return getReply(text);
}

int Client::cdup() {
	pi->write("CDUP");
	cout << "\t[C] CDUP" << endl;

	string text;
	return getReply(text);
}

int Client::quit() {
	pi->write("QUIT");
	cout << "\t[C] QUIT" << endl;

	string text;
	return getReply(text);
}

int Client::port(int port) {
	int addr = pi->getLocalAddr();
	stringstream ss;
	ss << "PORT " << (addr>>24) << ',' << ((addr>>16)&0xff) << ',';
	ss << ((addr>>8)&0xff) << ',' << (addr&0xff) << ',';
	ss << ((port>>8)&0xff) << ',' << (port&0xff);
	pi->write(ss.str());
	cout << "\t[C] " << ss.str() << endl;

	string text;
	int reply = getReply(text);

	if(reply==200) {
		dtp.setLocalPort(port);
		passive = false;
	}

	return reply;
}

int Client::pasv() {
	pi->write("PASV");
	cout << "\t[C] PASV" << endl;

	string text;
	int reply = getReply(text);

	if(reply==227) {
		int addr = 0;
		int port;
		int i = 27;
		for(int j=0; j<5; j++) {
			int comma = text.find(',', i);
			if(j<4)
				addr = (addr<<8)+atoi(text.substr(i, comma-i).c_str());
			else
				port = atoi(text.substr(i, comma-i).c_str());
			i = comma+1;
		}
		port = (port<<8)+atoi(text.substr(i).c_str());

		passive = true;
		dtp.setDest(addr, port);
		data = dtp.connect();
	}

	return reply;
}

int Client::type(Tcp::DataType type) {
	string text = "TYPE ";
	switch(type) {
	case Tcp::ASCII:
		text += 'A';
		break;
	case Tcp::IMAGE:
		text += 'I';
		break;
	default:
		throw "Unsupported data type";
	}

	pi->write(text);
	cout << "\t[C] " << text << endl;

	int reply = getReply(text);

	if(reply==200)
		dataType = type;

	return reply;
}

int Client::stor(const string& filename) {
	ifstream is(filename.c_str(), dataType==Tcp::ASCII?ios::in:ios::binary);
	if(!is) throw "File not exist";

	string text = "STOR " + filename;
	pi->write(text);
	cout << "\t[C] " << text << endl;

	openDataConnection();
	int reply = getReply(text);

	if(reply==125 || reply==150) {
		data->setDataType(dataType);
		data->writeFromStream(is);
	}

	delete data;
	if(reply==125 || reply==150) reply = getReply(text);

	return reply;
}

int Client::retr(const string& filename) {
	string text = "RETR " + filename;
	pi->write(text);
	cout << "\t[C] " << text << endl;

	openDataConnection();
	int reply = getReply(text);

	if(reply==125 || reply==150) {
		ofstream os(filename.c_str(), dataType==Tcp::ASCII?ios::out:ios::binary);
		data->setDataType(dataType);
		data->readToStream(os);
	}

	delete data;
	if(reply==125 || reply==150) reply = getReply(text);

	return reply;
}

int Client::appe(const string& filename) {
	ifstream is(filename.c_str(), dataType==Tcp::ASCII?ios::in:ios::binary);
	if(!is) throw "File not exist";

	string text = "APPE " + filename;
	pi->write(text);
	cout << "\t[C] " << text << endl;

	openDataConnection();
	int reply = getReply(text);

	if(reply==125 || reply==150) {
		data->setDataType(dataType);
		data->writeFromStream(is);
	}

	delete data;
	if(reply==125 || reply==150) reply = getReply(text);

	return reply;
}

int Client::list(const string& path) {
	string text = path.length() ? "LIST " + path : "LIST";
	pi->write(text);
	cout << "\t[C] " << text << endl;

	openDataConnection();
	int reply = getReply(text);

	if(reply==125 || reply==150) data->readToStream(cout);

	delete data;
	if(reply==125 || reply==150) reply = getReply(text);

	return reply;
}

int Client::pwd(Directory& dir) {
	pi->write("PWD");
	cout << "\t[C] PWD" << endl;

	string text;
	int reply = getReply(text);

	if(reply==257)
		dir.cd(text.substr(5, text.find('"', 5)-5));

	return reply;
}

int Client::abor() {
	pi->write("ABOR");
	cout << "\t[C] ABOR" << endl;

	string text;
	return getReply(text);
}

int Client::syst() {
	pi->write("SYST");
	cout << "\t[C] SYST" << endl;

	string text;
	return getReply(text);
}

int Client::help(const string& command) {
	string text = command.length() ? "HELP " + command : "HELP";
	pi->write(text);
	cout << "\t[C] " << text << endl;

	return getReply(text);
}

bool Client::connect(Client* host) {
	pi->write("PASV");
	cout << "\t[C] PASV" << endl;

	string text;
	if(getReply(text)!=227) return false;

	text.replace(0, 27, "PORT ");
	text.resize(text.find(')'));
	host->pi->write(text);
	cout << "\t[C] " << text << endl;

	return host->getReply(text)==200;
}

bool Client::transfer(Client* host, const string& filename) {
	string text = "RETR " + filename;
	host->pi->write(text);
	cout << "\t[C] " << text << endl;

	int reply = host->getReply(text);
	if(reply!=125 && reply!=150) return false;

	text = "STOR " + filename.substr(filename.rfind('/')+1);
	pi->write(text);
	cout << "\t[C] " << text << endl;

	reply = getReply(text);
	if(reply!=125 && reply!=150) return false;

	host->getReply(text);
	getReply(text);
	return true;
}

int Client::getReply(string& reply) {
	reply = pi->read() + '\n';
	string num = reply.substr(0, 3) + ' ';

	if(reply[3]=='-') {
		string temp;
		do {
			temp = pi->read();
			reply += "\t[R] " + temp + '\n';
		} while(temp.substr(0, 4)!=num);
	}

	cout << "\t[R] " << reply;
	return atoi(num.c_str());
}

void Client::openDataConnection() {
	if(passive)
		passive = false;
	else
		data = dtp.listen();
}

⌨️ 快捷键说明

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