TcpClient.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /*
  2. * Copyright (c) 2016 The ZLToolKit project authors. All Rights Reserved.
  3. *
  4. * This file is part of ZLToolKit(https://github.com/xia-chu/ZLToolKit).
  5. *
  6. * Use of this source code is governed by MIT license that can be found in the
  7. * LICENSE file in the root of the source tree. All contributing project authors
  8. * may be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #ifndef NETWORK_TCPCLIENT_H
  11. #define NETWORK_TCPCLIENT_H
  12. #include <mutex>
  13. #include <memory>
  14. #include <functional>
  15. #include "Socket.h"
  16. #include "Util/TimeTicker.h"
  17. #include "Util/SSLBox.h"
  18. using namespace std;
  19. namespace toolkit {
  20. //Tcp客户端,Socket对象默认开始互斥锁
  21. class TcpClient : public std::enable_shared_from_this<TcpClient>, public SocketHelper {
  22. public:
  23. typedef std::shared_ptr<TcpClient> Ptr;
  24. TcpClient(const EventPoller::Ptr &poller = nullptr);
  25. ~TcpClient() override;
  26. /**
  27. * 开始连接tcp服务器
  28. * @param url 服务器ip或域名
  29. * @param port 服务器端口
  30. * @param timeout_sec 超时时间,单位秒
  31. */
  32. virtual void startConnect(const string &url, uint16_t port, float timeout_sec = 5);
  33. /**
  34. * 主动断开连接
  35. * @param ex 触发onErr事件时的参数
  36. */
  37. void shutdown(const SockException &ex = SockException(Err_shutdown, "self shutdown")) override;
  38. /**
  39. * 判断是否与服务器连接中
  40. */
  41. virtual bool alive();
  42. /**
  43. * 设置网卡适配器,使用该网卡与服务器通信
  44. * @param local_ip 本地网卡ip
  45. */
  46. virtual void setNetAdapter(const string &local_ip);
  47. protected:
  48. /**
  49. * 连接服务器结果回调
  50. * @param ex 成功与否
  51. */
  52. virtual void onConnect(const SockException &ex) {}
  53. /**
  54. * 收到数据回调
  55. * @param buf 接收到的数据(该buffer会重复使用)
  56. */
  57. virtual void onRecv(const Buffer::Ptr &buf) {}
  58. /**
  59. * 数据全部发送完毕后回调
  60. */
  61. virtual void onFlush() {}
  62. /**
  63. * 被动断开连接回调
  64. * @param ex 断开原因
  65. */
  66. virtual void onErr(const SockException &ex) {}
  67. /**
  68. * tcp连接成功后每2秒触发一次该事件
  69. */
  70. virtual void onManager() {}
  71. private:
  72. void onSockConnect(const SockException &ex);
  73. private:
  74. string _net_adapter = "0.0.0.0";
  75. std::shared_ptr<Timer> _timer;
  76. //对象个数统计
  77. ObjectStatistic<TcpClient> _statistic;
  78. };
  79. //用于实现TLS客户端的模板对象
  80. template<typename TcpClientType>
  81. class TcpClientWithSSL: public TcpClientType {
  82. public:
  83. typedef std::shared_ptr<TcpClientWithSSL> Ptr;
  84. template<typename ...ArgsType>
  85. TcpClientWithSSL(ArgsType &&...args):TcpClientType(std::forward<ArgsType>(args)...) {}
  86. ~TcpClientWithSSL() override{
  87. if (_ssl_box) {
  88. _ssl_box->flush();
  89. }
  90. }
  91. void onRecv(const Buffer::Ptr &buf) override {
  92. if (_ssl_box) {
  93. _ssl_box->onRecv(buf);
  94. } else {
  95. TcpClientType::onRecv(buf);
  96. }
  97. }
  98. ssize_t send(Buffer::Ptr buf) override {
  99. if (_ssl_box) {
  100. auto size = buf->size();
  101. _ssl_box->onSend(buf);
  102. return size;
  103. }
  104. return TcpClientType::send(std::move(buf));
  105. }
  106. //添加public_onRecv和public_send函数是解决较低版本gcc一个lambad中不能访问protected或private方法的bug
  107. inline void public_onRecv(const Buffer::Ptr &buf) {
  108. TcpClientType::onRecv(buf);
  109. }
  110. inline void public_send(const Buffer::Ptr &buf) {
  111. TcpClientType::send(std::move(const_cast<Buffer::Ptr &>(buf)));
  112. }
  113. void startConnect(const string &url, uint16_t port, float timeout_sec = 5) override {
  114. _host = url;
  115. TcpClientType::startConnect(url, port, timeout_sec);
  116. }
  117. protected:
  118. void onConnect(const SockException &ex) override {
  119. if (!ex) {
  120. _ssl_box = std::make_shared<SSL_Box>(false);
  121. _ssl_box->setOnDecData([this](const Buffer::Ptr &buf) {
  122. public_onRecv(buf);
  123. });
  124. _ssl_box->setOnEncData([this](const Buffer::Ptr &buf) {
  125. public_send(buf);
  126. });
  127. if (!isIP(_host.data())) {
  128. //设置ssl域名
  129. _ssl_box->setHost(_host.data());
  130. }
  131. }
  132. TcpClientType::onConnect(ex);
  133. }
  134. private:
  135. string _host;
  136. std::shared_ptr<SSL_Box> _ssl_box;
  137. };
  138. } /* namespace toolkit */
  139. #endif /* NETWORK_TCPCLIENT_H */