2

This example is based on Chapter 1 in book Boost.Asio C++ Network Programming book. I am attempting to build a simple client and synchronous server using Boost.Asio library.

Here is the client code

#define BOOST_ASIO_SEPARATE_COMPILATION
#include <iostream>
#include <boost/asio/impl/src.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/write.hpp>
#include <string>

int main(int argc, char **argv) {
    boost::asio::io_service ioservice;
    boost::asio::ip::tcp::endpoint ep(boost::asio::ip::address::from_string("127.0.0.1"),2001);
    boost::asio::ip::tcp::socket sock(ioservice);
    sock.connect(ep);

    return 0;
}

Here is the server code.

#define BOOST_ASIO_SEPARATE_COMPILATION

#include <stdio.h>
#include <iostream>
#include <boost/asio/impl/src.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio/write.hpp>

using namespace boost::asio;
typedef boost::shared_ptr<boost::asio::ip::tcp::socket> socket_ptr;
void client_session(socket_ptr sock);

int main(int argc, char **argv) {

    io_service ioservice;

    ip::tcp::endpoint ep(ip::tcp::v4(),2001);
    ip::tcp::acceptor acc(ioservice,ep);

    while(true){
      socket_ptr sock(new ip::tcp::socket(ioservice));
      acc.accept(*sock);
      boost::thread(boost::bind(client_session,sock));
    }

    return 0;
}

void client_session(socket_ptr sock)
{
   std::cout << "Handling client session \n";

    while(true){
      char data[512];
      size_t len = sock->read_some(buffer(data));
      if (len > 0)
    boost::asio::write(*sock,buffer("ok",2));

    }
}

After running the server, when I launch client, I get following output on the server

Handling client session
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::system::system_error> >'
      what():  read_some: End of file
    Aborted

I am not sure what's going on here. Please help.

lostpacket
  • 1,383
  • 8
  • 26
  • 38

1 Answers1

2

Your server expects that the client sends some data after connecting, which it does not. The client simply quits after connecting.

The following modification of your client simply sends data in an infinite loop to the server which always responds with "ok".

#define BOOST_ASIO_SEPARATE_COMPILATION
#include <iostream>
#include <boost/asio/impl/src.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/write.hpp>
#include <string>

int main(int argc, char **argv) {
    boost::asio::io_service ioservice;
    boost::asio::ip::tcp::endpoint ep(boost::asio::ip::address::from_string("127.0.0.1"),2001);
    boost::asio::ip::tcp::socket sock(ioservice);
    sock.connect(ep);

    for(;;)
    {
      boost::array<char, 512> buf  = {{ 0 }};
      boost::system::error_code ignored_error;
      boost::asio::write(sock, boost::asio::buffer(buf), ignored_error);
      size_t len = sock.read_some(boost::asio::buffer(buf), ignored_error);
      std::cout.write(buf.data(), len);
    }

    return 0;
}

In order to avoid crashing the server when the client disconnects, you should wrap the read_some call in a try...catch block:

void client_session(socket_ptr sock)
{
  std::cout << "Handling client session \n";

  try
  {
    while(true){
      char data[512];
      size_t len = sock->read_some(buffer(data));
      if (len > 0)
      boost::asio::write(*sock,buffer("ok",2));

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

You should also have a look at the examples in the boost asio documentation: http://www.boost.org/doc/libs/1_58_0/doc/html/boost_asio/tutorial.html

m.s.
  • 16,063
  • 7
  • 53
  • 88