www.pudn.com > FTPServerClient.zip > client.cpp
#include#include #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(); }