13 #include "common/logger.h"
21 : local_ip_address_{local_ip_address},
22 local_port_num_{local_port_num},
24 tcp_socket_{io_context_},
29 tcp_handler_read_{std::move(tcp_handler_read)} {
31 thread_ = std::thread([
this]() {
32 std::unique_lock<std::mutex> lck(
mutex_);
61 if (ec.value() == boost::system::errc::success) {
63 tcp_socket_.set_option(boost::asio::socket_base::reuse_address{
true});
69 if (ec.value() == boost::system::errc::success) {
72 __FILE__, __LINE__, __func__, [
this](std::stringstream &msg) {
73 Tcp::endpoint
const endpoint_{
tcp_socket_.local_endpoint()};
74 msg <<
"Tcp Socket opened and bound to "
75 <<
"<" << endpoint_.address().to_string() <<
"," << endpoint_.port() <<
">";
77 result.EmplaceValue();
81 __FILE__, __LINE__, __func__,
82 [ec](std::stringstream &msg) { msg <<
"Tcp Socket binding failed with message: " << ec.message(); });
87 __FILE__, __LINE__, __func__,
88 [ec](std::stringstream &msg) { msg <<
"Tcp Socket opening failed with error: " << ec.message(); });
95 std::uint16_t host_port_num) {
100 tcp_socket_.connect(Tcp::endpoint(TcpIpAddress::from_string(std::string{host_ip_address}), host_port_num), ec);
101 if (ec.value() == boost::system::errc::success) {
103 __FILE__, __LINE__, __func__, [
this](std::stringstream &msg) {
104 Tcp::endpoint
const endpoint_{
tcp_socket_.remote_endpoint()};
105 msg <<
"Tcp Socket connected to host "
106 <<
"<" << endpoint_.address().to_string() <<
"," << endpoint_.port() <<
">";
109 std::lock_guard<std::mutex> lock{
mutex_};
113 result.EmplaceValue();
116 __FILE__, __LINE__, __func__,
117 [ec](std::stringstream &msg) { msg <<
"Tcp Socket connect to host failed with error: " << ec.message(); });
127 tcp_socket_.shutdown(TcpSocket::shutdown_both, ec);
128 if (ec.value() == boost::system::errc::success) {
132 result.EmplaceValue();
135 __FILE__, __LINE__, __func__, [ec](std::stringstream &msg) {
136 msg <<
"Tcp Socket disconnection from host failed with error: " << ec.message();
146 boost::asio::write(
tcp_socket_, boost::asio::buffer(tcp_message->GetTxBuffer(), tcp_message->GetTxBuffer().size()),
149 if (ec.value() == boost::system::errc::success) {
151 __FILE__, __LINE__, __func__, [
this](std::stringstream &msg) {
152 Tcp::endpoint
const endpoint_{
tcp_socket_.remote_endpoint()};
153 msg <<
"Tcp message sent to "
154 <<
"<" << endpoint_.address().to_string() <<
"," << endpoint_.port() <<
">";
156 result.EmplaceValue();
159 __FILE__, __LINE__, __func__,
160 [ec](std::stringstream &msg) { msg <<
"Tcp message sending failed with error: " << ec.message(); });
169 result.EmplaceValue();
181 if (ec.value() == boost::system::errc::success) {
183 std::uint32_t
const read_next_bytes = [&rx_buffer]() noexcept -> std::uint32_t {
184 return static_cast<std::uint32_t
>((
static_cast<std::uint32_t
>(rx_buffer[4u] << 24u) & 0xFF000000) |
185 (
static_cast<std::uint32_t
>(rx_buffer[5u] << 16u) & 0x00FF0000) |
186 (
static_cast<std::uint32_t
>(rx_buffer[6u] << 8u) & 0x0000FF00) |
187 (
static_cast<std::uint32_t
>(rx_buffer[7u] & 0x000000FF)));
194 Tcp::endpoint
const endpoint_{
tcp_socket_.remote_endpoint()};
196 std::make_unique<TcpMessage>(endpoint_.address().to_string(), endpoint_.port(), std::move(rx_buffer))};
198 __FILE__, __LINE__, __func__, [endpoint_](std::stringstream &msg) {
199 msg <<
"Tcp Message received from "
200 <<
"<" << endpoint_.address().to_string() <<
"," << endpoint_.port() <<
">";
204 }
else if (ec.value() == boost::asio::error::eof) {
207 __FILE__, __LINE__, __func__,
208 [ec](std::stringstream &msg) { msg <<
"Remote Disconnected with: " << ec.message(); });
212 __FILE__, __LINE__, __func__,
213 [ec](std::stringstream &msg) { msg <<
"Remote Disconnected with undefined error: " << ec.message(); });
static auto GetLibBoostLogger() noexcept -> LibBoostLogger &
boost::system::error_code TcpErrorCodeType
Type alias for tcp error codes.
std::uint16_t local_port_num_
Store local port number.
std::function< void(TcpMessagePtr)> TcpHandlerRead
Tcp function template used for reception.
std::string local_ip_address_
Store local ip address.
TcpSocket tcp_socket_
Store tcp socket.
std::mutex mutex_
mutex to lock critical section
core_type::Result< void, TcpErrorCode > DisconnectFromHost()
Function to Disconnect from host.
TcpHandlerRead tcp_handler_read_
Store the handler.
core_type::Result< void, TcpErrorCode > Destroy()
Function to destroy the socket.
core_type::Result< void, TcpErrorCode > Open()
Function to Open the socket.
std::atomic_bool exit_request_
Flag to terminate the thread.
std::atomic_bool running_
Flag to start the thread.
std::condition_variable cond_var_
Conditional variable to block the thread.
~TcpClientSocket()
Destruct an instance of TcpClientSocket.
core_type::Result< void, TcpErrorCode > Transmit(TcpMessageConstPtr tcp_message)
Function to trigger transmission.
void HandleMessage()
Function to handle the reception of tcp message.
core_type::Result< void, TcpErrorCode > ConnectToHost(std::string_view host_ip_address, std::uint16_t host_port_num)
Function to connect to remote ip address and port number.
TcpClientSocket(std::string_view local_ip_address, std::uint16_t local_port_num, TcpHandlerRead tcp_handler_read)
Constructs an instance of TcpClientSocket.
std::thread thread_
The thread itself.
std::vector< uint8_t > BufferType
Type alias for underlying buffer.
Class type to contains a value (of type ValueType), or an error (of type ErrorType)
std::unique_ptr< const TcpMessage > TcpMessageConstPtr
The unique pointer to const TcpMessage.
constexpr std::uint8_t kDoipheadrSize
Doip HeaderSize.
std::unique_ptr< TcpMessage > TcpMessagePtr
The unique pointer to TcpMessage.