Created
November 27, 2019 15:49
-
-
Save drewxa/1ee65724fb7262c379d8b5ed889c353e to your computer and use it in GitHub Desktop.
This file contains hidden or 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 <boost/array.hpp> | |
#include <boost/asio.hpp> | |
#include <cstdlib> | |
#include <iostream> | |
#include <memory> | |
#include <utility> | |
using boost::asio::ip::tcp; | |
/// Пример 0. Бред какой-то. | |
class Request : public std::enable_shared_from_this<Request> { | |
public: | |
Request(tcp::socket socket) : socket_(std::move(socket)) {} | |
~Request() { std::cout << "~Request()" << std::endl; } | |
void Read() { | |
self_ = shared_from_this(); | |
socket_.async_receive( | |
boost::asio::buffer(data_), | |
[this](boost::system::error_code ec, std::size_t length) { | |
if (!ec) { | |
std::cout << std::string(data_.begin(), data_.begin() + length) | |
<< std::endl; | |
} | |
self_.reset(); | |
}); | |
} | |
private: | |
tcp::socket socket_; | |
std::array<char, 1024> data_; | |
std::shared_ptr<Request> self_; | |
}; | |
class AsyncHttpServer { | |
public: | |
AsyncHttpServer(boost::asio::io_service& io_service, short port) | |
: acceptor_(io_service, tcp::endpoint(tcp::v4(), port)), | |
socket_(io_service) { | |
CreateConnection(); | |
} | |
private: | |
void CreateConnection() { | |
acceptor_.async_accept(socket_, std::bind(&AsyncHttpServer::OnAccept, this, | |
std::placeholders::_1)); | |
} | |
void OnAccept(const boost::system::error_code& ec) { | |
if (!ec) { | |
std::make_shared<Request>(std::move(socket_))->Read(); | |
} | |
CreateConnection(); | |
} | |
tcp::acceptor acceptor_; | |
tcp::socket socket_; | |
}; | |
/// Пример 1. Простой асинхронный Echo сервак | |
void Echo(std::shared_ptr<tcp::socket> socket) { | |
std::shared_ptr<std::vector<char>> data = | |
std::make_shared<std::vector<char>>(1024); | |
auto write_callback = [=](boost::system::error_code ec, size_t n) mutable { | |
Echo(std::move(socket)); | |
data.reset(); | |
}; | |
auto read_callback = [=](boost::system::error_code ec, size_t n) mutable { | |
if (!ec) { | |
socket->async_write_some(boost::asio::buffer(*data, n), write_callback); | |
} | |
}; | |
socket->async_read_some(boost::asio::buffer(*data), read_callback); | |
} | |
void DoAccept(tcp::acceptor& acceptor, boost::asio::io_service& io_service) { | |
std::shared_ptr<tcp::socket> socket = | |
std::make_shared<tcp::socket>(io_service); | |
auto callback = [socket, &acceptor, | |
&io_service](boost::system::error_code ec) { | |
Echo(std::move(socket)); | |
DoAccept(acceptor, io_service); | |
}; | |
acceptor.async_accept(*socket, callback); | |
} | |
/// Пример 2. LockFreeStack с утечками. | |
template <typename T> | |
struct LockFreeStack { | |
void Push(const T& value) { | |
Node* new_head = new Node(value, head_.load()); | |
while (!head_.compare_exchange_weak(new_head->next, new_head)) { | |
} | |
} | |
Node* Pop() { | |
Node* node = head_.load(); | |
while (node && !head_.compare_exchange_weak(node, node->next)) { | |
} | |
return node; | |
} | |
private: | |
struct Node { | |
T data; | |
Node* next; | |
}; | |
std::atomic<Node*> head_; | |
}; | |
int main(int argc, char* argv[]) { | |
try { | |
boost::asio::io_service io_service; | |
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 80)); | |
DoAccept(acceptor, io_service); | |
// AsyncHttpServer s(io_service, std::atoi("80")); | |
io_service.run(); | |
} catch (std::exception& e) { | |
std::cerr << "Exception: " << e.what() << "\n"; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment