Tiny Synchronous FileServer using Boost ASIO


This is a tiny example of use for Boost ASIO, here is the code for the server

/**
 * Author: Julien Boucaron <julien.boucaron@free.fr>
 *
 * A tiny example of use of Boost ASIO
 * to create a simple synchronous file_server
 *
 * Released under Boost License
 *
 */

#include <iostream>
#include <fstream>
#include <string>
#include <boost/asio.hpp>

using boost::asio::ip::tcp;

int main()
{
  try
  {
    const unsigned int port = 10000; //port the server listen
    const unsigned int buff_size = 16384; //size of the send buffer

    boost::asio::io_service io_service; //main asio object
    tcp::endpoint endpoint(tcp::v4(), port); //endpoint
    tcp::acceptor acceptor(io_service, endpoint);  //we accept connection there

    //server loop
    while(1) {
      tcp::socket socket(io_service);  //create a socket
      acceptor.accept(socket); //attach to the acceptor
      //we have got a new connection !
      std::cout << " Remote @:port  " << socket.remote_endpoint().address() << " : "
		<< socket.remote_endpoint().port() << std::endl;

      std::fstream file("file"); //we open this file

      char* buff = new char[buff_size]; //creating the buffer
      unsigned int count = 0; //counter
      std::cout << "Sending" << std::endl;
      while( !file.eof() ) { //loop until there is no more data to send
	memset(buff,0,buff_size); //cleanup the buffer
	file.read(buff,buff_size); //read some data 
	boost::system::error_code ignored_error;
	unsigned int len = file.gcount(); //get the effective number of bytes read
	boost::asio::write(socket, boost::asio::buffer(buff,len),
			   boost::asio::transfer_all(), ignored_error); //send
	count+=len; //increment counter
      }

      file.close(); //close file
      delete(buff);  //delete buffer
      std::cout << "Finished" << std::endl;
      std::cout << "Sent "  << count << " bytes" << std::endl;
    }

  }
  catch (std::exception& e)
  {
    std::cerr << e.what() << std::endl;
  }

  return 0;
}

Now, the code for the client

/**
 * Author: Julien Boucaron <julien.boucaron@free.fr>
 *
 * A tiny example of use of Boost ASIO
 * to create a simple synchronous file_client
 *
 * Released under Boost License
 *
 */

#include <iostream>
#include <string>
#include <fstream>
#include <boost/asio.hpp>

using boost::asio::ip::tcp;

int main(int argc, char* argv[])
{
  try
  {

    const char *port = "10000"; //the port we connect
    const unsigned int buff_size = 65536; //the size of the read buffer

    if (argc != 3)
    {
      std::cerr << "Usage: file_client <host> <filename>" << std::endl;
      return 1;
    }
    boost::asio::io_service io_service; //asio main object
    tcp::resolver resolver(io_service); //a resolver for name to @
    tcp::resolver::query query(argv[1], port); //ask the dns for this resolver
    tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); //iterator if multiple answers for a given name
    tcp::resolver::iterator end;

    tcp::socket socket(io_service); //attach a socket to the main asio object
    socket.connect(*endpoint_iterator); //connect to the first returned object

    std::fstream f(argv[2],std::fstream::out); //open in write mode the output file
    unsigned int count = 0; //a counter
    while(1) { //loop until (see break after)
      boost::array<char, buff_size> buf; //create read buffer
      boost::system::error_code error; //in case of error
      size_t len = socket.read_some(boost::asio::buffer(buf), error); //read data
      std::cout << "Read " << len <<  std::endl;
      count += len;
      std::cout << "Read a total of " << count << " bytes " << std::endl;
      if (error == boost::asio::error::eof ) { //if end of file reached
	f.write(buf.data(),len); //finish write data
	f.close();   break; // Connection closed cleanly by peer.
      }
      else if (error) {
        throw boost::system::system_error(error); // Some other error.
      }
      else {
	f.write(buf.data(),len); //write some data 
      }
    }
  }
  catch (std::exception& e)
  {
    std::cout << "Exception: " << e.what() << std::endl;
  }

  return 0;
}

Comments are closed.