/
novemus
/
plexus
Обзор
Документация
Войти
/
novemus
/
plexus
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
tests/tcp_tests.cpp
153 строки
5 KB
novemus
enhance naming and tests
31 мар 2026, 17:09
31 мар 2026, 17:09
878c6d0
Код
Авторство
О чём код?
/* * Copyright (c) 2022 Novemus Band. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * */ #include <boost/bind.hpp> #include <boost/asio.hpp> #include <boost/asio/spawn.hpp> #include <boost/asio/ip/tcp.hpp> #include <boost/system/system_error.hpp> #include <boost/test/unit_test.hpp> #include <plexus/network.h> class tcp_echo_session : public std::enable_shared_from_this<tcp_echo_session> { enum { max_length = 1024 }; char m_data[max_length]; boost::asio::ip::tcp::socket m_socket; public: tcp_echo_session(boost::asio::io_context &io) : m_socket(io) { } boost::asio::ip::tcp::socket& socket() { return m_socket; } void start() { m_socket.async_read_some( boost::asio::buffer(m_data, max_length), boost::bind(&tcp_echo_session::handle_read, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred) ); } protected: void handle_read(const boost::system::error_code &error, size_t transferred) { if (!error) { m_socket.async_write_some( boost::asio::buffer(m_data, transferred), boost::bind(&tcp_echo_session::handle_write, shared_from_this(), boost::asio::placeholders::error) ); } } void handle_write(const boost::system::error_code &error) { if (!error) { m_socket.async_read_some( boost::asio::buffer(m_data, max_length), boost::bind(&tcp_echo_session::handle_read, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred) ); } } }; namespace { class tcp_echo_server { boost::asio::io_context& m_io; boost::asio::ip::tcp::acceptor m_acceptor; public: tcp_echo_server(boost::asio::io_context& io, unsigned short port) : m_io(io) , m_acceptor(m_io, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)) { boost::asio::post(m_io, boost::bind(&tcp_echo_server::start_accept, this)); } protected: void start_accept() { auto session = std::make_shared<tcp_echo_session>(m_io); m_acceptor.async_accept( session->socket(), boost::bind(&tcp_echo_server::handle_accept, this, session, boost::asio::placeholders::error) ); } void handle_accept(std::shared_ptr<tcp_echo_session> session, const boost::system::error_code &error) { if (!error) session->start(); start_accept(); } }; std::shared_ptr<tcp_echo_server> create_tcp_server(boost::asio::io_context& io, unsigned short port) { return std::make_shared<tcp_echo_server>(io, port); } const uint16_t TCP_SERVER_PORT = 8765; const boost::asio::ip::tcp::endpoint TCP_SERVER(boost::asio::ip::make_address("127.0.0.1"), TCP_SERVER_PORT); const boost::asio::ip::tcp::endpoint TCP_CLIENT(boost::asio::ip::tcp::v4(), 0); const boost::asio::ip::tcp::endpoint TCP_FAKE_SERVER(boost::asio::ip::make_address("1.1.1.1"), 1); } BOOST_AUTO_TEST_CASE(tcp_echo_exchange) { boost::asio::io_context io; auto server = create_tcp_server(io, TCP_SERVER_PORT); boost::asio::spawn(io, [&](boost::asio::yield_context yield) { auto client = plexus::network::create_tcp_socket(io, TCP_CLIENT, TCP_FAKE_SERVER); BOOST_REQUIRE_THROW(client->connect(yield, 2000), boost::system::system_error); BOOST_REQUIRE_NO_THROW(client->close()); client = plexus::network::create_tcp_socket(io, TCP_CLIENT, TCP_SERVER); BOOST_REQUIRE_NO_THROW(client->connect(yield)); std::string wb = "Hello, Plexus!"; std::string rb; rb.resize(wb.size()); BOOST_REQUIRE_NO_THROW(BOOST_REQUIRE_EQUAL(client->write(boost::asio::buffer(wb), yield), wb.size())); BOOST_REQUIRE_NO_THROW(BOOST_REQUIRE_EQUAL(client->read(boost::asio::buffer(rb), yield), rb.size())); BOOST_REQUIRE_EQUAL(wb, rb); BOOST_REQUIRE_NO_THROW(BOOST_REQUIRE_EQUAL(client->write(boost::asio::buffer(wb), yield), wb.size())); BOOST_REQUIRE_NO_THROW(BOOST_REQUIRE_EQUAL(client->read(boost::asio::buffer(rb), yield), rb.size())); BOOST_REQUIRE_EQUAL(wb, rb); BOOST_REQUIRE_NO_THROW(client->shutdown()); io.stop(); }, boost::asio::detached); io.run(); }