Boost asio client server

Hello Guys i made a synchronus client and asynchronus server. I am trying to connect them and able to successfully implement them. But i am having trouble with server to keep it alive. also next time if i send the message to the server it refuse to connect. Here is my code
[Client]
#include <boost/asio.hpp>
#include <iostream>
using namespace boost;

class SyncTCPClient {
public:
//constructor
SyncTCPClient(const std::string& raw_ip_address, unsigned short port_num) :
m_ep(asio::ip::address::from_string(raw_ip_address), port_num), m_sock(m_ios)
{
m_sock.open(m_ep.protocol());
}

// method to connect
void connect() {
m_sock.connect(m_ep);
}

// method to close
void close() {
m_sock.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
m_sock.close();
}


std::string emulateLongComputationOp(std::string msg) {
std::string request = msg+ "\n";
std::cout<<msg<<std::endl;
sendRequest(request);
return receiveResponse();
};
private:

// method to send msg
void sendRequest(const std::string& request) {
asio::write(m_sock, asio::buffer(request));
}

// method to recieve responce
std::string receiveResponse() {
asio::streambuf buf;
asio::read_until(m_sock, buf, '\n');
std::istream input(&buf);
std::string response;
std::getline(input, response);
return response;
}
private:
asio::io_service m_ios;
asio::ip::tcp::endpoint m_ep;
asio::ip::tcp::socket m_sock;
};
int main()
{
const std::string raw_ip_address = "127.0.0.1";
const unsigned short port_num = 3333;
try {
SyncTCPClient client(raw_ip_address, port_num);
// Sync connect.
client.connect();


char msg[512]; // currently hardcoded need to discuss
while (std::cin.getline (msg,512)){
client.emulateLongComputationOp(msg);
}

// Close the connection and free resources.
// client.close();
}
catch (system::system_error &e) {
std::cout << "Error on clint main code = " << e.code() << " and Message: " << e.what();
return e.code().value();
}
return 0;
}

[Server]:
//
// blocking_tcp_echo_server.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include <thread>
#include <boost/asio.hpp>
#include <atomic>
#include <memory>
#include <iostream>

using namespace boost;
using namespace std;


class Service {
public:
Service(std::shared_ptr<asio::ip::tcp::socket> sock) : m_sock(sock){

}

void startHandling(){
asio::async_read_until(*m_sock.get(), m_request, '\n',
[this](const boost::system::error_code& ec, std::size_t bytes_transferred)
{
onRequestReceived(ec, bytes_transferred);
});
}

private:
// call back method for server
void onRequestReceived(const boost::system::error_code& ec, std::size_t bytes_transferred) {
if (ec != 0) {
std::cout << "Error on received with code = " << ec.value() << " and Message: " << ec.message();
onFinish();
return;
}

// Process the request.
m_response = ProcessRequest(m_request);

// Initiate asynchronous write operation.
asio::async_write(*m_sock.get(), asio::buffer(m_response),
[this](const boost::system::error_code& ec, std::size_t bytes_transferred)
{
onResponseSent(ec, bytes_transferred);
});
}

// call back method for server
void onResponseSent(const boost::system::error_code& ec, std::size_t bytes_transferred) {
if (ec != 0) {
std::cout << "Error on responce with code = " << ec.value() << " and Message: " << ec.message();
}
onFinish();
}
// Here we perform the cleanup.
void onFinish() {
delete this;
}

// called to prepare responce
std::string ProcessRequest(asio::streambuf &request) {
// In this method we parse the request, process it and prepare the response.
// std::this_thread::sleep_for(std::chrono::milliseconds(100));
// Prepare and return the response message.

// to print
std::istream input(&request);
std::string op;
std::getline(input, op);
std::cout<<"ankit test "<<op<<std::endl;


std::string response = "Ankit\n";
return response;
}
private:
std::shared_ptr<asio::ip::tcp::socket> m_sock;
std::string m_response;
asio::streambuf m_request;
};



class Acceptor {
public:
Acceptor(asio::io_service &ios, unsigned short port_num) :
m_ios(ios), m_acceptor(m_ios, asio::ip::tcp::endpoint(asio::ip::address_v4::any(), port_num)), m_isStopped(false)
{
// Constructor method
}

// Start accepting incoming connection requests.
void Start() {
m_acceptor.listen();
InitAccept();
}

// Stop accepting incoming connection requests.
void Stop() {
m_isStopped.store(true);
}

private:
void InitAccept() {

std::shared_ptr<asio::ip::tcp::socket> sock(new asio::ip::tcp::socket(m_ios));
m_acceptor.async_accept(*sock.get(), [this, sock](const boost::system::error_code& error)
{
onAccept(error, sock);
});
}

// work as callback when connection is accepted or error occured
void onAccept(const boost::system::error_code &ec, std::shared_ptr<asio::ip::tcp::socket> sock)
{

if (ec == 0) {
(new Service(sock))->startHandling();
}
else {
std::cout<< "Error onAccept with code = " <<ec.value() << " and Message: " <<ec.message();
}
// Init next async accept operation if acceptor has not been stopped yet.
if (!m_isStopped.load()) {
InitAccept();
}
else {
// Stop accepting incoming connections and free allocated resources.
m_acceptor.close();
}
}
private:
asio::io_service&m_ios;
asio::ip::tcp::acceptor m_acceptor;
std::atomic<bool> m_isStopped;
};



class Server {
public:
// constructor
Server() {
m_work.reset(new asio::io_service::work(m_ios));
}

// Start the server.
void Start(unsigned short port_num, unsigned int thread_pool_size) {

assert(thread_pool_size > 0);

// Create and start Acceptor.
acc.reset(new Acceptor(m_ios, port_num));
acc->Start();

// Create specified number of threads and add them to the pool.
for (unsigned int i = 0; i < thread_pool_size; i++) {
std::unique_ptr<std::thread> th (new std::thread([this]()
{
m_ios.run();
}));
m_thread_pool.push_back(std::move(th));
}


}
// Stop the server.
void Stop() {
acc->Stop();
m_ios.stop();
for (auto& th : m_thread_pool) {
th->join();
}
}
private:
asio::io_service m_ios;
std::unique_ptr<asio::io_service::work> m_work;
std::unique_ptr<Acceptor> acc;
std::vector<std::unique_ptr<std::thread>> m_thread_pool;
};



const unsigned int DEFAULT_THREAD_POOL_SIZE = 2;
int main()
{
unsigned short port_num = 3333;

try {
Server srv;
unsigned int thread_pool_size = std::thread::hardware_concurrency() * 2;

if (thread_pool_size == 0)
thread_pool_size = DEFAULT_THREAD_POOL_SIZE;


srv.Start(port_num, 1);
std::this_thread::sleep_for(std::chrono::seconds(100));
//srv.Stop();
}
catch(system::system_error&e) {
std::cout << "Error on server main code = " <<e.code() << " and Message: " <<e.what();
}
return 0;
}

Let me know if any further connect is required. Also how to maintain session
Thanks
io_service::run() returns when there is no pending asynchronous operation.
Topic archived. No new replies allowed.