赞
踩
客户端的需求:具备读/写能力,能自动重连。
自动重连用一个线程去检测,读/写能力复用RWHandler。
客户端的实现如下:
- class Connector
- {
- public:
- 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)
- {
- CreateEventHandler(ios);
- }
-
- ~Connector()
- {
- }
-
- bool Start()
- {
- m_eventHandler->GetSocket().async_connect(m_serverAddr, [this](const boost::system::error_code& error){
- if (error) {
- HandleConnectError(error);
- return ;
- }
- cout << "connect ok" << endl;
- m_isConnected = true;
- // 连接成功后发起一个异步读操作
- m_eventHandler->HandleRead();
- });
-
- boost::this_thread::sleep(boost::posix_time::seconds(1));
- return m_isConnected;
- }
-
- bool IsConnected() const
- {
- return m_isConnected;
- }
-
- void Send(char* data, int len)
- {
- if(!m_isConnected) {
- return ;
- }
- // 同步写
- m_eventHandler->HandleWrite(data, len);
- }
-
- private:
- void CreateEventHandler(io_service& ios)
- {
- m_eventHandler = std::make_shared<RWHandler>(ios);
- m_eventHandler->SetCallBackError([this](int connid){
- HandleRWError(connid);
- });
- }
-
- void HandleRWError(int connid)
- {
- m_isConnected = false;
- CheckConnnect();
- }
-
- void HandleConnectError(const boost::system::error_code &error)
- {
- m_isConnected = false;
- cout << error.message() << endl;
- m_eventHandler->CloseSocket();
- CheckConnect();
- }
-
- void CheckConnect()
- {
- if (m_chkThread != nullptr) {
- return;
- }
-
- m_chkThread = std::make_shared<std::thread>([this]{
- while(true) {
- if(!IsConnected()) {
- Start();
- }
- boost::this_thread::sleep(boost::posix_time::seconds(1));
- }
- });
- }
-
- private:
- io_service& m_ios;
- tcp::socket m_socket;
- // 服务端地址
- tcp::endpoint m_serverAddr;
- std::shared_ptr<RWHandler> m_eventHandler;
- bool m_isConnected;
- // 专门检测重连的线程
- std::shared_ptr<std::thread> m_chkThread;
- };
连接成功后发起了一个异步读操作,它用来判断连接是否断开,因为当连接断开时,HandleRWError会触发重连操作。
客户端的测试代码如下:
- int main()
- {
- io_service ios;
- boost::asio::io_service::work work(ios);
- boost::thread thd([&ios]{
- ios.run();
- });
-
- Connector conn(ios, "127.0.0.1", 9900);
- conn.Start();
-
- istring str;
- if (!conn.IsConnected()) {
- cin >> str;
- return -1;
- }
-
- const int len = 512;
- char line[len] = "";
- while(cin >> str) {
- char header[HEAD_LEN] = {};
- // str末尾'/0'
- int totalLen = str.length() + 1 + HEAD_LEN;
- std::sprintf(header, "%d", totalLen);
- memcpy(line, header, HEAD_LEN);
- memcpy(line + HEAD_LEN, str.c_str(), str.length() + 1);
- conn.Send(line, totalLen);
- }
-
- return 0;
- }
注意:这里通过boost::asio::io_service::work和单独线程来保证ios::run()不退出。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。