Guest User

Untitled

a guest
Apr 2nd, 2016
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.94 KB | None | 0 0
  1. #include <atomic>
  2. #include <chrono>
  3. #include <ctime>
  4. #include <iomanip>
  5. #include <iostream>
  6. #include <memory>
  7. #include <sstream>
  8. #include <string>
  9. #include <thread>
  10.  
  11. #include <boost/asio.hpp>
  12. #include <boost/asio/system_timer.hpp>
  13.  
  14. #include <botan/botan.h>
  15.  
  16. namespace asio = boost::asio;
  17. using boost::asio::ip::tcp;
  18.  
  19. #define PORT 9090
  20.  
  21. std::atomic<uint64_t> stat_conn;
  22. std::atomic<uint64_t> stat_pkt;
  23.  
  24. class client_connection : public std::enable_shared_from_this<client_connection> {
  25. public:
  26. static auto create(asio::io_service &service) {
  27. return std::make_shared<client_connection>(service);
  28. }
  29.  
  30. tcp::socket &socket() { return socket_; }
  31.  
  32. client_connection(asio::io_service &service)
  33. : strand_(service),
  34. socket_(service),
  35. pipe_(new Botan::Hash_Filter("SHA-256"), new Botan::Hex_Encoder,
  36. new Botan::DataSink_Stream(sha256_)) {}
  37.  
  38. void run() {
  39. asio::async_read(
  40. socket_, asio::buffer(data_),
  41. strand_.wrap([self = shared_from_this()](const boost::system::error_code &err,
  42. size_t n) { self->read_cb(err, n); }));
  43. }
  44.  
  45. private:
  46. void read_cb(const boost::system::error_code &error, size_t) {
  47. if (error)
  48. return;
  49.  
  50. stat_pkt++;
  51.  
  52. #if 1
  53. Botan::DataSource_Memory in(data_.data(), data_.size());
  54. pipe_.process_msg(in);
  55. #else
  56. sha256_ << "0123456789012345678901234567890123456789012345678901234567890123";
  57. #endif
  58. asio::async_write(
  59. socket_, asio::buffer(sha256_.str()),
  60. strand_.wrap([self = shared_from_this()](const boost::system::error_code &err,
  61. size_t n) { self->write_cb(err, n); }));
  62. run();
  63. }
  64. void write_cb(const boost::system::error_code &, size_t) { sha256_.str(""); }
  65.  
  66. asio::io_service::strand strand_;
  67. tcp::socket socket_;
  68. Botan::Pipe pipe_;
  69. std::array<unsigned char, 512> data_;
  70. std::stringstream sha256_;
  71. };
  72.  
  73. class server {
  74. public:
  75. server(asio::io_service &service, unsigned short port, unsigned nthr)
  76. : service_{service},
  77. acceptor_{service, tcp::endpoint(tcp::v4(), port)},
  78. timer_{service},
  79. nthr_{nthr},
  80. pkt_{0} {
  81. acceptor_.set_option(tcp::acceptor::reuse_address(true));
  82. start_accept();
  83. start_time_ = std::chrono::system_clock::now();
  84. start_timer();
  85. }
  86.  
  87. void run() {
  88. std::vector<std::thread> thr;
  89. for (unsigned i = 0; i < nthr_; ++i) {
  90. auto t = std::thread([this] { service_.run(); });
  91. thr.push_back(std::move(t));
  92. }
  93.  
  94. for (auto &t : thr) {
  95. t.join();
  96. }
  97. }
  98.  
  99. asio::io_service &service() { return service_; }
  100.  
  101. private:
  102. void start_accept() {
  103. auto conn = client_connection::create(acceptor_.get_io_service());
  104.  
  105. acceptor_.async_accept(conn->socket(), [=](const boost::system::error_code &err) {
  106. accept_cb(conn, err);
  107. });
  108. }
  109.  
  110. void start_timer() {
  111. timer_.expires_from_now(std::chrono::seconds(5));
  112. timer_.async_wait([this](const boost::system::error_code &) { tick(); });
  113. }
  114.  
  115. void accept_cb(std::shared_ptr<client_connection> conn,
  116. const boost::system::error_code &error) {
  117. if (!error) {
  118. stat_conn++;
  119. conn->run();
  120. }
  121. start_accept();
  122. }
  123.  
  124. void tick() {
  125. auto delta = std::chrono::duration_cast<std::chrono::seconds>(
  126. std::chrono::system_clock::now() - start_time_)
  127. .count();
  128. std::cout << "delta: " << delta << "\n";
  129. std::cout << "conn: " << stat_conn << ", pkt: " << stat_pkt << ", time: " << delta
  130. << "\n";
  131. std::cout << stat_pkt / delta << " pkt/s" << std::endl;
  132.  
  133. start_timer();
  134. }
  135.  
  136. asio::io_service &service_;
  137. tcp::acceptor acceptor_;
  138. asio::system_timer timer_;
  139. unsigned nthr_;
  140. uint64_t pkt_;
  141. std::chrono::system_clock::time_point start_time_;
  142. };
  143.  
  144. #define NTHR 6
  145.  
  146. int main() {
  147. try {
  148. asio::io_service service;
  149. server(service, PORT, NTHR).run();
  150. } catch (std::exception &e) {
  151. std::cerr << e.what() << std::endl;
  152. }
  153. return 0;
  154. }
Advertisement
Add Comment
Please, Sign In to add comment