#ifdef _WIN32 # define NOMINMAX # define _WIN32_WINNT 0x0501 #endif #include #include #include #include #include #include #include #include #include #include #include #include #include // This is a list of files that have to be sent. typedef std::vector FnList; typedef FnList::iterator FnListIt; typedef FnList::const_iterator FnListCIt; FnList FileNameList; std::string filename; std::string file; class tcp_server { public: tcp_server(boost::asio::io_service & io_service, std::string const & address, std::string const & port) : io_service_(&io_service) , socket_(io_service) , sent_(0) { boost::asio::ip::tcp::resolver resolver(io_service); boost::asio::ip::tcp::resolver::query query(address, port); boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); boost::asio::ip::tcp::resolver::iterator end; boost::system::error_code error = boost::asio::error::host_not_found; while (error && endpoint_iterator != end) { socket_.close(); socket_.connect(*endpoint_iterator++, error); } if (error) throw boost::system::system_error(error); std::cout << "Connecting to " << socket_.remote_endpoint() << std::endl; connect_handler(error); } private: void connect_handler(const boost::system::error_code& error) { if (!error) { std::cout << "Transferring " << filename << std::flush; // Put the file name in the buffer std::memcpy(buffer_.c_array(), filename.c_str(), filename.size()); buffer_[filename.size()] = '\n'; // and start the writing process. boost::asio::async_write(socket_, boost::asio::buffer(buffer_, filename.size() + 1), boost::bind(&tcp_server::write_handler, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } else std::cerr << "connect_handler error: " << error << " - " << error.message() << std::endl; } void write_handler(const boost::system::error_code& error, std::size_t bytes_transferred) { if (!error) { if (sent_ < file.size()) { std::cout << "." << std::flush; std::size_t size = std::min(sizeof(buffer_), file.size() - sent_); std::memcpy(buffer_.c_array(), file.c_str() + sent_, size); sent_ += size; //boost::asio::async_write(socket_, boost::asio::buffer(buffer_, size), boost::bind(&tcp_connection::write_handler, shared_from_this())); boost::asio::async_write(socket_, boost::asio::buffer(buffer_, size), boost::bind(&tcp_server::write_handler, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } else { std::cout << " done, bytes transferred: " << bytes_transferred << std::endl; } } else std::cerr << "write_handler error: " << error << " - " << error.message() << std::endl; } boost::asio::io_service *io_service_; boost::asio::ip::tcp::socket socket_; boost::asio::ip::tcp::endpoint endpoint_; boost::array buffer_; std::size_t sent_; }; int main(int argc, const char *argv[]) { if (argc < 4) { std::cerr << argv[0] << " ... " << std::endl; return 1; } // Gather up the file names. for ( int i = 3; i < argc; ++i ) { // Crude check for existance. std::ifstream ifs(argv[i], std::ios::in | std::ios::binary); if ( ifs ) { FileNameList.push_back(argv[i]); } else { std::cerr << argv[i] << " not found." << std::endl; } ifs.close(); } // Process each file // For the moment just write the file name and contents to global variables. try { for ( FnListCIt p = FileNameList.begin(); p != FileNameList.end(); ++p ) { filename = *p; std::ifstream ifs(filename.c_str(), std::ios::in | std::ios::binary); if (!ifs) { continue; } else { std::ostringstream oss; oss << ifs.rdbuf(); file = oss.str(); boost::asio::io_service io_service; //unsigned short port = boost::lexical_cast(argv[2]); // Send the file. tcp_server server(io_service,argv[1],argv[2]); io_service.run(); oss.str(""); } filename.clear(); file.clear(); } } catch (std::exception& e) { std::cerr << e.what() << std::endl; return EXIT_FAILURE; } return EXIT_SUCCESS; }