-
-
Save mesarvagya/a73f2428417cb10336ef to your computer and use it in GitHub Desktop.
A TCP server sending proper response to the client
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <ctime> | |
#include <iostream> | |
#include <string> | |
#include <boost/bind.hpp> | |
#include <boost/shared_ptr.hpp> | |
#include <boost/enable_shared_from_this.hpp> | |
#include <boost/asio.hpp> | |
#include <boost/algorithm/string.hpp> | |
#include <boost/smart_ptr.hpp> | |
#include <json/reader.h> | |
#include <json/writer.h> | |
#include "rapidjson\document.h" | |
using namespace rapidjson; | |
#include <time.h> | |
namespace { | |
Json::Value to_json(std::string json) | |
{ | |
Json::Value root; | |
Json::Reader reader; | |
/*bool success =*/ reader.parse(json, root); | |
return root; | |
} | |
std::string to_string(Json::Value root) // unused TODO FIXME | |
{ | |
Json::FastWriter writer; | |
std::string json = writer.write(root); | |
return json; | |
} | |
Document to_json_rapidJson(std::string json) | |
{ | |
Document d; | |
d.Parse(json.c_str()); | |
assert(d.IsObject()); | |
return d; | |
} | |
} | |
double elapsed; | |
time_t start_time, end_time; | |
using boost::asio::ip::tcp; | |
int count(0); | |
class tcp_connection : public boost::enable_shared_from_this<tcp_connection> | |
{ | |
public: | |
typedef boost::shared_ptr<tcp_connection> pointer; | |
static pointer create(boost::asio::io_service& io_service) | |
{ | |
return pointer(new tcp_connection(io_service)); | |
} | |
tcp::socket& socket() | |
{ | |
return socket_; | |
} | |
void start() | |
{ | |
//Read from client, make json and send appropriate response | |
boost::asio::async_read_until(socket_, message_,"\\q\\q", | |
boost::bind(&tcp_connection::handle_read, shared_from_this(), | |
boost::asio::placeholders::error, | |
boost::asio::placeholders::bytes_transferred)); | |
} | |
private: | |
tcp_connection(boost::asio::io_service& io_service) | |
: socket_(io_service) | |
{ | |
} | |
void handle_write(const boost::system::error_code& /*error*/, | |
size_t /*bytes_transferred*/) | |
{ | |
} | |
void handle_read(const boost::system::error_code& error, size_t bytes_transferred) | |
{ | |
// std::cout << "Handle Read of connection\n"; | |
/*++count; | |
if(count == 1) | |
{ | |
time(&start_time); | |
}*/ | |
if (error && error != boost::asio::error::eof) { | |
std::cout << "Error: " << error.message() << "\n"; | |
return; | |
} | |
std::string messageP; | |
{ | |
std::stringstream ss; | |
ss << &message_; | |
ss.flush(); | |
messageP = ss.str(); | |
} | |
boost::algorithm::replace_last(messageP, "\\q\\q", ""); | |
//std::cout <<"After \\q\\q Replace: " << messageP << std::endl; | |
Document d = to_json_rapidJson(messageP); | |
/* | |
Json::Value root = to_json(messageP); | |
std::string isHello = root["heartbeat"].asString(); | |
std::string isMessage = root["message"].toStyledString(); | |
if(!isHello.empty()) | |
{ | |
std::string messageTemp = ""; | |
messageSend = boost::make_shared<std::string>(messageTemp); | |
boost::asio::async_write(socket_, boost::asio::buffer(*messageSend), | |
boost::bind(&tcp_connection::handle_write, shared_from_this(), | |
boost::asio::placeholders::error, | |
boost::asio::placeholders::bytes_transferred)); | |
} | |
else if(!isMessage.empty()) | |
{ | |
std::string messageTemp = "{\"success\":\"true\"}"; | |
messageSend = boost::make_shared<std::string>(messageTemp); | |
boost::asio::async_write(socket_, boost::asio::buffer(*messageSend), | |
boost::bind(&tcp_connection::handle_write, shared_from_this(), | |
boost::asio::placeholders::error, | |
boost::asio::placeholders::bytes_transferred)); | |
} | |
*/ | |
if(d.HasMember("heartbeat") && d.HasMember("first_fetch")) | |
{ | |
std::string first = d["first_fetch"].GetString(); | |
if(first == "1") | |
{ | |
std::string messageTemp = "{\"config_changed\":\"true\", \"config\":\"This is config\"}"; | |
messageSend = boost::make_shared<std::string>(messageTemp); | |
boost::asio::async_write(socket_, boost::asio::buffer(*messageSend), | |
boost::bind(&tcp_connection::handle_write, shared_from_this(), | |
boost::asio::placeholders::error, | |
boost::asio::placeholders::bytes_transferred)); | |
} | |
else | |
{ | |
std::string messageTemp = "{\"config_changed\":\"false\"}"; | |
messageSend = boost::make_shared<std::string>(messageTemp); | |
boost::asio::async_write(socket_, boost::asio::buffer(*messageSend), | |
boost::bind(&tcp_connection::handle_write, shared_from_this(), | |
boost::asio::placeholders::error, | |
boost::asio::placeholders::bytes_transferred)); | |
} | |
} | |
else if(d.HasMember("message")) | |
{ | |
std::string messageTemp = "{\"success\":\"true\"}"; | |
messageSend = boost::make_shared<std::string>(messageTemp); | |
boost::asio::async_write(socket_, boost::asio::buffer(*messageSend), | |
boost::bind(&tcp_connection::handle_write, shared_from_this(), | |
boost::asio::placeholders::error, | |
boost::asio::placeholders::bytes_transferred)); | |
} | |
/*if(count == 100000) | |
{ | |
time(&end_time); | |
elapsed = difftime(end_time, start_time); | |
std::cout << "Packet 100K time = " << elapsed << " seconds" << std::endl; | |
}*/ | |
start(); | |
} | |
tcp::socket socket_; | |
boost::asio::streambuf message_; | |
boost::shared_ptr<std::string> messageSend; | |
}; | |
class tcp_server | |
{ | |
public: | |
tcp_server(boost::asio::io_service& io_service) | |
: acceptor_(io_service, tcp::endpoint(tcp::v4(), 1936)) | |
{ | |
start_accept(); | |
} | |
private: | |
void start_accept() | |
{ | |
tcp_connection::pointer new_connection = | |
tcp_connection::create(acceptor_.get_io_service()); | |
acceptor_.async_accept(new_connection->socket(), | |
boost::bind(&tcp_server::handle_accept, this, new_connection, | |
boost::asio::placeholders::error)); | |
} | |
void handle_accept(tcp_connection::pointer new_connection, const boost::system::error_code& error) | |
{ | |
if (!error) | |
{ | |
std::cout << "A client connected" << std::endl; | |
new_connection->start(); | |
} | |
start_accept(); | |
} | |
tcp::acceptor acceptor_; | |
}; | |
int main() | |
{ | |
try | |
{ | |
boost::asio::io_service io_service; | |
tcp_server server(io_service); | |
io_service.run(); | |
} | |
catch (std::exception& e) | |
{ | |
std::cerr << e.what() << std::endl; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment