Skip to content

Instantly share code, notes, and snippets.

@drewxa
Created November 27, 2019 15:49
Show Gist options
  • Save drewxa/1ee65724fb7262c379d8b5ed889c353e to your computer and use it in GitHub Desktop.
Save drewxa/1ee65724fb7262c379d8b5ed889c353e to your computer and use it in GitHub Desktop.
#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