#include "net_base.h" CTcpClient::CTcpClient(asio::io_context& io_context) : io_context_(io_context), socket_(io_context_) { } CTcpClient::~CTcpClient() = default; bool CTcpClient::connect(const std::string& host, const std::string& port) { try { asio::ip::tcp::resolver resolver(io_context_); asio::ip::tcp::resolver::results_type endpoints = resolver.resolve(host, port); asio::connect(socket_, endpoints); TLOGI("Connected to {}:{}", host, port); is_normal_ = true; return true; } catch (const std::exception& ex) { TLOGE("Connection failed: {}", ex.what()); return false; } } void CTcpClient::disconnect() { if (socket_.is_open()) { try { socket_.shutdown(asio::ip::tcp::socket::shutdown_both); socket_.close(); TLOGI("Disconnected."); } catch (const std::exception& ex) { TLOGE("Error during disconnection: {}", ex.what()); } } } bool CTcpClient::send(const char* data, int len) { if (!is_normal_) { TLOGE("abnormal state, will not send."); return false; } try { auto send_size = asio::write(socket_, asio::buffer(data, len)); // TLOGI("Need Send len: {} Real Send len: {}", len, send_size); return static_cast(send_size) == len; } catch (const std::exception& ex) { TLOGE("Send failed: {}", ex.what()); return false; } } void CTcpClient::register_func(ExFun_t&& f) { fun_ = f; } void CTcpClient::async_recv() { auto self(shared_from_this()); socket_.async_read_some(asio::buffer(tmp_buf_), [this, self](std::error_code ec, std::size_t length) { if (ec) { is_normal_ = false; if (ec.value() == 995) { // 正常中止退出 return; } if (ec.value() == 125) { TLOGI("{} exit.", __FUNCTION__); return; } TLOGE("{} {} error => {}", __FUNCTION__, ec.value(), ec.message()); } else { buffer_.push(tmp_buf_.data(), length); while (true) { auto* frame = CTransProtocal::parse(buffer_); if (frame) { if (fun_) { fun_(frame); } delete frame; continue; } break; } async_recv(); } }); } bool CTcpClient::is_normal() const { return is_normal_; }