深入应用c++11 随书代码

代码并未在作者github上提供

将书中代码敲至vc 并调试运行 依赖BOOST库 

编译环境vs2015 boost1.59

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Client.cpp : 定义控制台应用程序的入口点。
//
 
#include "stdafx.h"
#include <boost/thread.hpp>
#include <thread>
#include <string>
#include "../Common/RWHandler.h"
 
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);
    }
 
    void AsyncSend(char* data, int len)
    {
        if (!m_isConnected)
            return;
        //m_eventHandler->HandleAsyncWrite(data, len);
        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 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));
            }
        });
    }
 
    void HandleConnectError(const boost::system::error_code& error)
    {
        m_isConnected = false;
        cout << error.message() << endl;
        m_eventHandler->CloseSocket();
        CheckConnect();
    }
 
    void HandleRWError(int connid)
    {
        m_isConnected = false;
        CheckConnect();
    }
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;
};
 
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();
    std::string str;
    if (!conn.IsConnected())
    {
        cin >> str;
        return -1;
    }
 
    const int len = 512;
    char line[len] = "";
 
    while (cin >> str)
    {
        char header[HEAD_LEN] = {};
        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;
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Server.cpp : 定义控制台应用程序的入口点。
//
 
#include "stdafx.h"
#include "../Common/RWHandler.h"
#include "../Common/Message.h"
 
#include <boost/asio/buffer.hpp>
#include <unordered_map>
#include <numeric>
 
const int MaxConnectionNum = 65536;
const int MaxRecvSize = 65536;
class Server {
public:
    Server(io_service& ios, short port) :m_ios(ios), m_acceptor(ios, tcp::endpoint(tcp::v4(), port)),
        m_connIdPool(MaxConnectionNum)
    {
        m_connIdPool.resize(MaxConnectionNum);
        std::iota(m_connIdPool.begin(), m_connIdPool.end(), 1);
    }
 
    ~Server(){}
 
    void Accept()
    {
        cout << "Start listening " << endl;
        std::shared_ptr<RWHandler> handler = CreateHandler();
 
        m_acceptor.async_accept(handler->GetSocket(), [this, handler](const boost::system::error_code& error)
        {
            if (error)
            {
                cout << error.value() << " " << error.message() << endl;
                HandleAcpError(handler, error);
                return;
            }
            m_handlers.insert(std::make_pair(handler->GetConnId(),handler));
            cout << "current connect count: " << m_handlers.size() << endl;
 
            handler->HandleRead();
            Accept();
        });
    }
 
private:
    void HandleAcpError(std::shared_ptr<RWHandler> eventHandler, const boost::system::error_code& error)
    {
        cout << "Error,error reason: " << error.value() << error.message() << endl;
        eventHandler->CloseSocket();
        StopAccept();
    }
 
    void StopAccept()
    {
        boost::system::error_code ec;
        m_acceptor.cancel(ec);
        m_acceptor.close(ec);
        m_ios.stop();
    }
 
    std::shared_ptr<RWHandler> CreateHandler()
    {
        int connId = m_connIdPool.front();
        m_connIdPool.pop_front();
        std::shared_ptr<RWHandler> handler = std::make_shared<RWHandler>(m_ios);
        handler->SetConnId(connId);
        handler->SetCallBackError([this](int connId)
        {
            RecyclConnid(connId);
        });
        return handler;
    }
 
    void RecyclConnid(int connId)
    {
        auto it = m_handlers.find(connId);
        if (it != m_handlers.end())
            m_handlers.erase(it);
        //==
        cout << "current connect count: " << m_handlers.size() << endl;
        m_connIdPool.push_back(connId);
    }
private:
    io_service& m_ios;
    tcp::acceptor m_acceptor;
    std::unordered_map<int, std::shared_ptr<RWHandler>> m_handlers;
    list<int> m_connIdPool;
 
};
 
 
int main()
{
    io_service ios;
 
    Server server(ios, 9900);
    server.Accept();
    ios.run();
 
    return 0;
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#pragma once
 
class Message {
public:
    enum { header_length = 4 };
    enum { max_body_length = 512 };
 
    Message() :body_length_(0){ }
 
    const char* data() const { return data_; }
 
    char* data() { return data_; }
 
    size_t length()const { return header_length + body_length_; }
 
    const char* body()const { return data_ + header_length; }
 
    char* body() { return data_ + header_length; }
 
    size_t body_length()const { return body_length_; }
 
    void body_length(size_t new_length)
    {
        body_length_ = new_length;
        if (body_length_ > max_body_length)
            body_length_ = max_body_length;
    }
 
    bool decode_header()
    {
        char header[header_length + 1] = "";
        std::strncat(header, data_, header_length);
        body_length_ = std::atoi(header) - header_length;
        if (body_length_ > max_body_length)
        {
            body_length_ = 0;
            return false;
        }
        return true;
    }
 
    void encode_header()
    {
        char header[header_length + 1] = "";
        std::sprintf(header,"%4d",body_length_);
        std::memcpy(data_,header,header_length);
    }
private:
    char data_[header_length + max_body_length];
    std::size_t body_length_;
};

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#pragma once
#include <array>
#include <functional>
#include <iostream>
 
using namespace std;
 
#include <boost/asio.hpp>
using namespace boost::asio;
using namespace boost::asio::ip;
using namespace boost;
 
const int MAX_IP_PACK_SIZE = 65536;
const int HEAD_LEN = 4;
 
class RWHandler {
public:
    RWHandler(io_service& ios) :m_sock(ios) {}
    ~RWHandler(){}
    void HandleRead() {
        async_read(m_sock, buffer(m_buff), transfer_at_least(HEAD_LEN), [this](const boost::system::error_code& ec,
            size_t size) {
            if (ec != nullptr)
            {
                HandleError(ec);
                return;
            }
            cout << m_buff.data() + HEAD_LEN << endl;
            HandleRead();
        });
    }
 
    void HandleWrite(char* data, int len)
    {
        boost::system::error_code ec;
        write(m_sock, buffer(data, len), ec);
        if (ec != nullptr)
            HandleError(ec);
    }
 
    tcp::socket& GetSocket() { return m_sock; }
 
    void CloseSocket()
    {
        boost::system::error_code ec;
        m_sock.shutdown(tcp::socket::shutdown_send, ec);
        m_sock.close(ec);
    }
 
    void SetConnId(int connId) { m_connId = connId; }
 
    int GetConnId()const { return m_connId; }
 
    template<typename F>void SetCallBackError(F f) { m_callbackError = f; }
 
private:
    void HandleError(const boost::system::error_code& ec)
    {
        CloseSocket();
        cout << ec.message() << endl;
        if (m_callbackError)
            m_callbackError(m_connId);
    }
 
private:
    tcp::socket m_sock;
    std::array<char, MAX_IP_PACK_SIZE> m_buff;
    int m_connId;
    std::function<void(int)> m_callbackError;
};

  

posted on   itdef  阅读(737)  评论(0编辑  收藏  举报

编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示