当前位置:   article > 正文

[16 使用C++11开发一个简单的通信程序(Proactor模式)] 16.5 C++11结合asio实现一个简单的客户端程序_c++客户端开发

c++客户端开发

客户端的需求:具备读/写能力,能自动重连。

自动重连用一个线程去检测,读/写能力复用RWHandler。

客户端的实现如下:

  1. class Connector
  2. {
  3. public:
  4. Connector(io_service& ios, const string& strIP, short port) : m_ios(ios), m_socket(ios), m_serverAddr(tcp::endpoint(address::from_string(strIP), port)), m_isConnected(false), m_chkThread(nullptr)
  5. {
  6. CreateEventHandler(ios);
  7. }
  8. ~Connector()
  9. {
  10. }
  11. bool Start()
  12. {
  13. m_eventHandler->GetSocket().async_connect(m_serverAddr, [this](const boost::system::error_code& error){
  14. if (error) {
  15. HandleConnectError(error);
  16. return ;
  17. }
  18. cout << "connect ok" << endl;
  19. m_isConnected = true;
  20. // 连接成功后发起一个异步读操作
  21. m_eventHandler->HandleRead();
  22. });
  23. boost::this_thread::sleep(boost::posix_time::seconds(1));
  24. return m_isConnected;
  25. }
  26. bool IsConnected() const
  27. {
  28. return m_isConnected;
  29. }
  30. void Send(char* data, int len)
  31. {
  32. if(!m_isConnected) {
  33. return ;
  34. }
  35. // 同步写
  36. m_eventHandler->HandleWrite(data, len);
  37. }
  38. private:
  39. void CreateEventHandler(io_service& ios)
  40. {
  41. m_eventHandler = std::make_shared<RWHandler>(ios);
  42. m_eventHandler->SetCallBackError([this](int connid){
  43. HandleRWError(connid);
  44. });
  45. }
  46. void HandleRWError(int connid)
  47. {
  48. m_isConnected = false;
  49. CheckConnnect();
  50. }
  51. void HandleConnectError(const boost::system::error_code &error)
  52. {
  53. m_isConnected = false;
  54. cout << error.message() << endl;
  55. m_eventHandler->CloseSocket();
  56. CheckConnect();
  57. }
  58. void CheckConnect()
  59. {
  60. if (m_chkThread != nullptr) {
  61. return;
  62. }
  63. m_chkThread = std::make_shared<std::thread>([this]{
  64. while(true) {
  65. if(!IsConnected()) {
  66. Start();
  67. }
  68. boost::this_thread::sleep(boost::posix_time::seconds(1));
  69. }
  70. });
  71. }
  72. private:
  73. io_service& m_ios;
  74. tcp::socket m_socket;
  75. // 服务端地址
  76. tcp::endpoint m_serverAddr;
  77. std::shared_ptr<RWHandler> m_eventHandler;
  78. bool m_isConnected;
  79. // 专门检测重连的线程
  80. std::shared_ptr<std::thread> m_chkThread;
  81. };

连接成功后发起了一个异步读操作,它用来判断连接是否断开,因为当连接断开时,HandleRWError会触发重连操作。

客户端的测试代码如下:

  1. int main()
  2. {
  3. io_service ios;
  4. boost::asio::io_service::work work(ios);
  5. boost::thread thd([&ios]{
  6. ios.run();
  7. });
  8. Connector conn(ios, "127.0.0.1", 9900);
  9. conn.Start();
  10. istring str;
  11. if (!conn.IsConnected()) {
  12. cin >> str;
  13. return -1;
  14. }
  15. const int len = 512;
  16. char line[len] = "";
  17. while(cin >> str) {
  18. char header[HEAD_LEN] = {};
  19. // str末尾'/0'
  20. int totalLen = str.length() + 1 + HEAD_LEN;
  21. std::sprintf(header, "%d", totalLen);
  22. memcpy(line, header, HEAD_LEN);
  23. memcpy(line + HEAD_LEN, str.c_str(), str.length() + 1);
  24. conn.Send(line, totalLen);
  25. }
  26. return 0;
  27. }

注意:这里通过boost::asio::io_service::work和单独线程来保证ios::run()不退出。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/663321
推荐阅读
相关标签
  

闽ICP备14008679号