CppServer  1.0.4.0
C++ Server Library
tcp_client.h
Go to the documentation of this file.
1 
9 #ifndef CPPSERVER_ASIO_TCP_CLIENT_H
10 #define CPPSERVER_ASIO_TCP_CLIENT_H
11 
12 #include "tcp_resolver.h"
13 
14 #include "system/uuid.h"
15 #include "time/timespan.h"
16 
17 #include <mutex>
18 #include <vector>
19 
20 namespace CppServer {
21 namespace Asio {
22 
24 
29 class TCPClient : public std::enable_shared_from_this<TCPClient>
30 {
31 public:
33 
38  TCPClient(const std::shared_ptr<Service>& service, const std::string& address, int port);
40 
45  TCPClient(const std::shared_ptr<Service>& service, const std::string& address, const std::string& scheme);
47 
51  TCPClient(const std::shared_ptr<Service>& service, const asio::ip::tcp::endpoint& endpoint);
52  TCPClient(const TCPClient&) = delete;
53  TCPClient(TCPClient&&) = delete;
54  virtual ~TCPClient() = default;
55 
56  TCPClient& operator=(const TCPClient&) = delete;
58 
60  const CppCommon::UUID& id() const noexcept { return _id; }
61 
63  std::shared_ptr<Service>& service() noexcept { return _service; }
65  std::shared_ptr<asio::io_service>& io_service() noexcept { return _io_service; }
67  asio::io_service::strand& strand() noexcept { return _strand; }
69  asio::ip::tcp::endpoint& endpoint() noexcept { return _endpoint; }
71  asio::ip::tcp::socket& socket() noexcept { return _socket; }
72 
74  const std::string& address() const noexcept { return _address; }
76  const std::string& scheme() const noexcept { return _scheme; }
78  int port() const noexcept { return _port; }
79 
81  uint64_t bytes_pending() const noexcept { return _bytes_pending + _bytes_sending; }
83  uint64_t bytes_sent() const noexcept { return _bytes_sent; }
85  uint64_t bytes_received() const noexcept { return _bytes_received; }
86 
88  bool option_keep_alive() const noexcept { return _option_keep_alive; }
90  bool option_no_delay() const noexcept { return _option_no_delay; }
92  size_t option_receive_buffer_limit() const noexcept { return _receive_buffer_limit; }
94  size_t option_receive_buffer_size() const;
96  size_t option_send_buffer_limit() const noexcept { return _send_buffer_limit; }
98  size_t option_send_buffer_size() const;
99 
101  bool IsConnected() const noexcept { return _connected; }
102 
104 
110  virtual bool Connect();
112 
119  virtual bool Connect(const std::shared_ptr<TCPResolver>& resolver);
121 
124  virtual bool Disconnect() { return DisconnectInternal(); }
126 
129  virtual bool Reconnect();
130 
132 
135  virtual bool ConnectAsync();
137 
141  virtual bool ConnectAsync(const std::shared_ptr<TCPResolver>& resolver);
143 
146  virtual bool DisconnectAsync() { return DisconnectInternalAsync(false); }
148 
151  virtual bool ReconnectAsync();
152 
154 
159  virtual size_t Send(const void* buffer, size_t size);
161 
165  virtual size_t Send(std::string_view text) { return Send(text.data(), text.size()); }
166 
168 
174  virtual size_t Send(const void* buffer, size_t size, const CppCommon::Timespan& timeout);
176 
181  virtual size_t Send(std::string_view text, const CppCommon::Timespan& timeout) { return Send(text.data(), text.size(), timeout); }
182 
184 
189  virtual bool SendAsync(const void* buffer, size_t size);
191 
195  virtual bool SendAsync(std::string_view text) { return SendAsync(text.data(), text.size()); }
196 
198 
203  virtual size_t Receive(void* buffer, size_t size);
205 
209  virtual std::string Receive(size_t size);
210 
212 
218  virtual size_t Receive(void* buffer, size_t size, const CppCommon::Timespan& timeout);
220 
225  virtual std::string Receive(size_t size, const CppCommon::Timespan& timeout);
226 
228  virtual void ReceiveAsync();
229 
231 
236  void SetupKeepAlive(bool enable) noexcept { _option_keep_alive = enable; }
238 
245  void SetupNoDelay(bool enable) noexcept { _option_no_delay = enable; }
247 
253  void SetupReceiveBufferLimit(size_t limit) noexcept { _receive_buffer_limit = limit; }
255 
260  void SetupReceiveBufferSize(size_t size);
262 
268  void SetupSendBufferLimit(size_t limit) noexcept { _send_buffer_limit = limit; }
270 
275  void SetupSendBufferSize(size_t size);
276 
277 protected:
279  virtual void onConnected() {}
281  virtual void onDisconnected() {}
282 
284 
291  virtual void onReceived(const void* buffer, size_t size) {}
293 
303  virtual void onSent(size_t sent, size_t pending) {}
304 
306 
312  virtual void onEmpty() {}
313 
315 
320  virtual void onError(int error, const std::string& category, const std::string& message) {}
321 
322 private:
323  // Client Id
324  CppCommon::UUID _id;
325  // Asio service
326  std::shared_ptr<Service> _service;
327  // Asio IO service
328  std::shared_ptr<asio::io_service> _io_service;
329  // Asio service strand for serialized handler execution
330  asio::io_service::strand _strand;
331  bool _strand_required;
332  // Server address, scheme & port
333  std::string _address;
334  std::string _scheme;
335  int _port;
336  // Server endpoint & client socket
337  asio::ip::tcp::endpoint _endpoint;
338  asio::ip::tcp::socket _socket;
339  std::atomic<bool> _resolving;
340  std::atomic<bool> _connecting;
341  std::atomic<bool> _connected;
342  // Client statistic
343  uint64_t _bytes_pending;
344  uint64_t _bytes_sending;
345  uint64_t _bytes_sent;
346  uint64_t _bytes_received;
347  // Receive buffer
348  bool _receiving;
349  size_t _receive_buffer_limit{0};
350  std::vector<uint8_t> _receive_buffer;
351  HandlerStorage _receive_storage;
352  // Send buffer
353  bool _sending;
354  std::mutex _send_lock;
355  size_t _send_buffer_limit{0};
356  std::vector<uint8_t> _send_buffer_main;
357  std::vector<uint8_t> _send_buffer_flush;
358  size_t _send_buffer_flush_offset;
359  HandlerStorage _send_storage;
360  // Options
361  bool _option_keep_alive;
362  bool _option_no_delay;
363 
365  bool DisconnectInternal();
367  bool DisconnectInternalAsync(bool dispatch);
368 
370  void TryReceive();
372  void TrySend();
373 
375  void ClearBuffers();
376 
378  void SendError(std::error_code ec);
379 };
380 
383 } // namespace Asio
384 } // namespace CppServer
385 
386 #endif // CPPSERVER_ASIO_TCP_CLIENT_H
void SetupKeepAlive(bool enable) noexcept
Setup option: keep alive.
Definition: tcp_client.h:236
size_t option_send_buffer_size() const
Get the option: send buffer size.
Definition: tcp_client.cpp:104
virtual size_t Receive(void *buffer, size_t size)
Receive data from the server (synchronous)
Definition: tcp_client.cpp:655
bool IsConnected() const noexcept
Is the client connected?
Definition: tcp_client.h:101
virtual bool Connect()
Connect the client (synchronous)
Definition: tcp_client.cpp:123
virtual size_t Send(const void *buffer, size_t size)
Send data to the server (synchronous)
Definition: tcp_client.cpp:505
TCPClient(const std::shared_ptr< Service > &service, const std::string &address, int port)
Initialize TCP client with a given Asio service, server address and port number.
Definition: tcp_client.cpp:14
virtual bool Disconnect()
Disconnect the client (synchronous)
Definition: tcp_client.h:124
TCPClient(const TCPClient &)=delete
virtual bool SendAsync(const void *buffer, size_t size)
Send data to the server (asynchronous)
Definition: tcp_client.cpp:603
virtual void onSent(size_t sent, size_t pending)
Handle buffer sent notification.
Definition: tcp_client.h:303
virtual bool ReconnectAsync()
Reconnect the client (asynchronous)
Definition: tcp_client.cpp:494
virtual void onReceived(const void *buffer, size_t size)
Handle buffer received notification.
Definition: tcp_client.h:291
virtual size_t Send(std::string_view text)
Send text to the server (synchronous)
Definition: tcp_client.h:165
virtual void onDisconnected()
Handle client disconnected notification.
Definition: tcp_client.h:281
TCPClient(TCPClient &&)=delete
virtual void onConnected()
Handle client connected notification.
Definition: tcp_client.h:279
void SetupReceiveBufferSize(size_t size)
Setup option: receive buffer size.
Definition: tcp_client.cpp:111
asio::ip::tcp::socket & socket() noexcept
Get the client socket.
Definition: tcp_client.h:71
TCPClient & operator=(const TCPClient &)=delete
void SetupNoDelay(bool enable) noexcept
Setup option: no delay.
Definition: tcp_client.h:245
void SetupSendBufferLimit(size_t limit) noexcept
Setup option: send buffer limit.
Definition: tcp_client.h:268
int port() const noexcept
Get the server port number.
Definition: tcp_client.h:78
virtual void onEmpty()
Handle empty send buffer notification.
Definition: tcp_client.h:312
virtual size_t Send(std::string_view text, const CppCommon::Timespan &timeout)
Send text to the server with timeout (synchronous)
Definition: tcp_client.h:181
virtual ~TCPClient()=default
TCPClient & operator=(TCPClient &&)=delete
asio::io_service::strand & strand() noexcept
Get the Asio service strand for serialized handler execution.
Definition: tcp_client.h:67
const std::string & address() const noexcept
Get the server address.
Definition: tcp_client.h:74
virtual void onError(int error, const std::string &category, const std::string &message)
Handle error notification.
Definition: tcp_client.h:320
std::shared_ptr< asio::io_service > & io_service() noexcept
Get the Asio IO service.
Definition: tcp_client.h:65
std::shared_ptr< Service > & service() noexcept
Get the Asio service.
Definition: tcp_client.h:63
asio::ip::tcp::endpoint & endpoint() noexcept
Get the client endpoint.
Definition: tcp_client.h:69
uint64_t bytes_pending() const noexcept
Get the number of bytes pending sent by the client.
Definition: tcp_client.h:81
uint64_t bytes_sent() const noexcept
Get the number of bytes sent by the client.
Definition: tcp_client.h:83
uint64_t bytes_received() const noexcept
Get the number of bytes received by the client.
Definition: tcp_client.h:85
const std::string & scheme() const noexcept
Get the scheme name.
Definition: tcp_client.h:76
virtual bool ConnectAsync()
Connect the client (asynchronous)
Definition: tcp_client.cpp:279
bool option_no_delay() const noexcept
Get the option: no delay.
Definition: tcp_client.h:90
size_t option_receive_buffer_limit() const noexcept
Get the option: receive buffer limit.
Definition: tcp_client.h:92
virtual bool SendAsync(std::string_view text)
Send text to the server (asynchronous)
Definition: tcp_client.h:195
virtual bool DisconnectAsync()
Disconnect the client (asynchronous)
Definition: tcp_client.h:146
size_t option_send_buffer_limit() const noexcept
Get the option: send buffer limit.
Definition: tcp_client.h:96
bool option_keep_alive() const noexcept
Get the option: keep alive.
Definition: tcp_client.h:88
virtual void ReceiveAsync()
Receive data from the server (asynchronous)
Definition: tcp_client.cpp:767
void SetupReceiveBufferLimit(size_t limit) noexcept
Setup option: receive buffer limit.
Definition: tcp_client.h:253
void SetupSendBufferSize(size_t size)
Setup option: send buffer size.
Definition: tcp_client.cpp:117
size_t option_receive_buffer_size() const
Get the option: receive buffer size.
Definition: tcp_client.cpp:97
const CppCommon::UUID & id() const noexcept
Get the client Id.
Definition: tcp_client.h:60
virtual bool Reconnect()
Reconnect the client (synchronous)
Definition: tcp_client.cpp:271
C++ Server project definitions.
Definition: asio.h:56
TCP resolver definition.