• 【项目实战】基于高并发服务器的搜索引擎


    【项目实战】基于高并发服务器的搜索引擎

    作者:爱写代码的刚子
    时间:2024.4.24
    前言:基于高并发服务器的搜索引擎,引用了第三方库cpp-httplib,cppjieba,项目的要点在代码注释中了

    搜索引擎部分代码

    index.html

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js">script>
        <title>本地 boost 搜索引擎title>
        <style>
            * {
                margin: 0;
                padding: 0;
                box-sizing: border-box;
            }
            html, body {
                height: 100%;
                font-family: Arial, sans-serif;
            }
            .container {
                width: 100%;
                display: flex;
                flex-direction: column;
                align-items: center;
            }
            .title {
                width: 100%;
                background-color: #4e6ef2;
                color: #fff;
                text-align: center;
                padding: 10px 0;
                font-size: 24px;
                font-weight: bold;
            }
            .search-container {
                width: 100%;
                background-color: #f2f2f2;
                display: flex;
                justify-content: center;
                align-items: center;
                padding: 20px 0;
                position: relative;
            }
            .search-input {
                width: calc(100% - 130px); /* 调整搜索框宽度 */
                max-width: 300px; /* 设置最大宽度 */
                height: 40px;
                padding: 10px;
                border: 1px solid #ccc;
                border-radius: 20px;
                font-size: 16px;
                outline: none;
            }
            .search-btn {
                width: 100px; /* 调整按钮宽度 */
                height: 40px;
                background-color: #4e6ef2;
                color: #fff;
                border: none;
                border-radius: 20px;
                font-size: 16px;
                cursor: pointer;
                position: absolute;
                right: 10px;
            }
            .result-container {
                width: 100%;
                padding: 20px 0;
                display: flex;
                flex-direction: column;
                align-items: center;
            }
            .result-item {
                width: 90%; /* 修改为百分比宽度,更适应移动设备 */
                max-width: 800px; /* 设置最大宽度 */
                border: 1px solid #ccc;
                border-radius: 5px;
                padding: 10px;
                margin-top: 10px;
            }
            .result-title {
                font-size: 18px;
                color: #4e6ef2;
                text-decoration: none;
            }
            .result-desc {
                font-size: 14px;
                color: #333;
                margin-top: 5px;
            }
            .result-url {
                font-size: 12px;
                color: #666;
                margin-top: 5px;
            }
        style>
    head>
    <body>
    <div class="container">
        <div class="title">boost 搜索引擎div>
        <div class="search-container">
            <input type="text" class="search-input" value="输入搜索关键字..." onfocus="if(this.value=='输入搜索关键字...') this.value='';" onblur="if(this.value=='') this.value='输入搜索关键字...';">
            <button class="search-btn" onclick="Search()">搜索一下button>
        div>
        <div class="result-container">
            
        div>
    div>
    <script>
        function Search() {
            let query = $(".search-input").val().trim();
            if (query == '') {
                return;
            }
            $.ajax({
                type: "GET",
                url: "/s?word=" + query,
                dataType: "json",
                success: function (data) {
                    BuildHtml(data);
                    $(".search-input").css("margin-top", "20px");
                }
            });
        }
    
        function BuildHtml(data) {
            let result_container = $(".result-container");
            result_container.empty();
            if (!data || data.length === 0) {
                result_container.append("
    未找到相关结果
    "
    ); return; } for (let elem of data) { let item = $("

    index.hpp

    #pragma once
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include "util.hpp"
    #include "log.hpp"
    
    namespace ns_index{
        struct DocInfo{
            std::string title;//文档标题
            std::string content;//文档对应的去标签之后的内容
            std::string url;//官网文档url
            uint64_t doc_id; //文档的ID
        };
    
        struct InvertedElem{//倒排的元素
            uint64_t doc_id;
            std::string word;
            int weight;
        };
        //倒排拉链
        typedef std::vector<InvertedElem> InvertedList;
    
        class Index{
        private:
            //正排索引的数据结构用数组,数组的下标天然是文档的ID
            std::vector<DocInfo> forward_index;//正排索引
            //倒排索引一定是一个关键字和一组(个)InvertedElem对应(关键字和倒排拉链的对应关系)
            std::unordered_map<std::string , InvertedList>inverted_index;
        private:
            Index(){}//单例,但是不能delete
            Index(const Index&) = delete;
            Index& operator = (const Index&) = delete;
            static Index *instance;
             static std::mutex mtx;
        public:
            
            ~Index(){}
        public:
            static Index* GetInstance()//多线程环境会存在线程安全
            {
                if(nullptr==instance)
                {
                    mtx.lock();
                    if(nullptr==instance)
                    {
                        instance = new Index();
                    }
                    mtx.unlock();
                }
    
                return instance;
            }
    
    
            //根据doc_id找到文档内容
            DocInfo* GetForwardIndex(uint64_t doc_id)
            {
                if(doc_id >= forward_index.size())
                {
                    //std::cerr<<"doc_id out range,error!"<
                    LOG2(DEBUG,"doc_id out range,error!");
                    return nullptr;
                }
                return &forward_index[doc_id];
            }
            //根据关键字string,获得倒排拉链
            InvertedList *GetInvertedList(const std::string &word)
            {
                auto iter = inverted_index.find(word);
                if(iter==inverted_index.end())
                {
                    //std::cerr<
                    LOG2(WARNING,"用户没搜到");
                    return nullptr;
                }
                return &(iter->second);
            }
            //根据去标签,格式化之后的文档,构建正排和倒排索引
            //data/raw_html/raw.txt
            bool BuildIndex(const std::string &input)//parse处理完毕的数据交给我(文件的路径)
            {
                std::ifstream in(input,std::ios::in | std::ios::binary);
                if(!in.is_open()){
                    //std::cerr<<"sorry,"<
                    LOG2(FATAL,"open error");
                    return false;
                }
                //读取文件
                std::string line;//每一行是一个文件
                int count = 0;
                while(std::getline(in,line))
                {
                    //建立正排索引
                    DocInfo* doc=BuildForwardIndex(line);
                    if(doc==nullptr)
                    {
                        //std::cerr<<"build"<
                        LOG2(DEBUG,"建立正排索引错误");
                        continue;
                    }
                    BuildInvertedIndex(*doc);
                    count++;
                    if(count % 50==0)
                    {
                        //std::cout<< "当前已经建立的索引文档:"<
                        LOG2(NORMAL,"当前已经建立的索引文档: " + std::to_string(count));
                    }
    
                }
                return true;
            }
            private:
            DocInfo *BuildForwardIndex(const std::string &line)
            {
                //1. 解析line,字符串切分 line -> 3个string,(title、content、url)
               
                std::vector<std::string> results;
                const std::string sep ="\3";//行内分隔符
                ns_util::StringUtil::Split(line,&results,sep);
    
                if(results.size()!=3){
                    return nullptr;
                }
                //2. 字符串进行填充到DoInfo
                DocInfo doc;
                doc.title = results[0];
                doc.content = results[1];
                doc.url = results[2];
                doc.doc_id = forward_index.size();//先进行保存,再插入,对应的id就是当前doc在vector下的下标
                //3. 插入到正排索引的vector
                forward_index.push_back(std::move(doc));//doc.html文件内容会比较大,避免拷贝应使用move
                return &forward_index.back();
            }
            bool BuildInvertedIndex(const DocInfo &doc)
            {
                //DocInfo(title,content,url,doc_id)
                //world -> 倒排拉链
                struct word_cnt{
                    int title_cnt;
                    int content_cnt;
    
                    word_cnt():title_cnt(0),content_cnt(0){}
                };
                std::unordered_map<std::string,word_cnt> word_map;//用来暂存词频的映射表
    
                //对标题进行分词
                std::vector<std::string> title_words;
                ns_util::JiebaUtil::CutString2(doc.title,&title_words);//调用了CutString2
                //对标题进行词频统计
                for(auto &s : title_words){
                    boost::to_lower(s);
                    word_map[s].title_cnt++;
                }
    
                //对文档内容进行分词
                std::vector<std::string> content_words;
                ns_util::JiebaUtil::CutString2(doc.content,&content_words);
                //对内容进行词频统计
                for(auto &s : content_words){
                    boost::to_lower(s);
                    word_map[s].content_cnt++;
                }
    
    #define X 10
    #define Y 1
                //Hello.HELLO.hello(倒排索引的大小写要忽略)
                //根据文档内容,形成一个或者多个InvertedElem(倒排拉链)
                //因为当前我们是一个一个文档进行处理的,一个文档会包含多个“词”,都应当对应到当前的doc_id
                for(auto &word_pair : word_map){
                    InvertedElem item;
                    item.doc_id = doc.doc_id;
                    item.word = word_pair.first;
                    item.weight = X*word_pair.second.title_cnt + Y*word_pair.second.content_cnt;//相关性
                    InvertedList &inverted_list = inverted_index[word_pair.first];
                    inverted_list.push_back(std::move(item));
                }
    
    
                //1.需要对title && content都要先分词
                //title: 吃/葡萄
                //content:吃/葡萄/不吐/葡萄皮
    
                //词和文档的相关性(非常复杂,我们采用词频:在标题中出现的词,可以认为相关性更高一些,在内容中出现相关性低一些)
                //2.词频统计
    
    
                //知道了在文档中,标题和内容每个词出现的次数
                //3. 自定义相关性
    
    
    
    
                //jieba的使用————cppjieba
                
                return true;
            }
        };
        Index* Index::instance = nullptr;
        std::mutex Index::mtx;
    
    }
    
    • 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
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205

    log.hpp

    #pragma once
    
    #include 
    #include 
    #include 
    
    #define NORMAL 1
    #define WARNING 2
    #define DEBUG 3
    #define FATAL 4
    
    
    #define LOG2(LEVEL,MESSAGE) log(#LEVEL,MESSAGE,__FILE__,__LINE__)
    //@brief:时间戳转日期时间
    static inline std::string getDateTimeFromTS(time_t ts) {
    	if(ts<0) {
    		return "";
    	}
    	struct tm tm = *localtime(&ts);
    	static char time_str[32]{0};
    	snprintf(time_str,sizeof(time_str),"%04d-%02d-%02d %02d:%02d:%02d",tm.tm_year+1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec);
    	return std::string(time_str);
    }
    
    void log(std::string level,std::string message,std::string file,int line)
    {
        std::cout<<"["<<level<<"]"<<"["<<getDateTimeFromTS(time(nullptr))<<"]"<<"["<<message<<"]"<<"["<<file<<":"<<line<<"]"<<std::endl;
    }
    
    
    • 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

    parser.cc(用于对网页的html文件切分且存储索引关系)

    #include 
    #include 
    #include 
    #include 
    #include "util.hpp"
    #include "log.hpp"
    const std::string src_path = "data/input";
    const std::string output = "data/raw_html/raw.txt";//结尾没有'/'
    
    typedef struct DocInfo{
        std::string title;//文档的标题
        std::string content;//文档内容
        std::string url;//该文档在官网中的url
    }DocInfo_t;
    //const & 输入
    //* 输出
    //& 输入输出
    bool EnumFile(const std::string &src_path,std::vector<std::string> *file_list);
    bool ParseHtml(const std::vector<std::string> &files_list,std::vector<DocInfo_t> *results);
    bool SaveHtml(const std::vector<DocInfo_t> &results,const std::string &output);
    
    int main()
    {
        std::vector<std::string> files_list;
        //第一步,递归式的把每个html文件名带路径,保存到files_list中,方便后期进行一个一个的文件进行读取
        if(!EnumFile(src_path, &files_list))
        {
            //std::cerr<<"enum file error!" <
            LOG2(FATAL,"enum file error!");
            return 1;
        }
        //第二步,按照files_list读取每个文件的内容,并进行解析
        std::vector<DocInfo_t> results;
        if(!ParseHtml(files_list,&results))
        {
            //std::cerr <<"parse html error"<
            LOG2(FATAL,"parse html error");
            return 2;
        }
        //第三步,把解析完毕的各个文件的内容,写入到output中,按照\3作为每个文档的分割符
        if(!SaveHtml(results,output))
        {
            //std::cerr<<"save html error"<
            LOG2(FATAL,"save html error");
            return 3;
        }
        
        return 0;
    }
    
    
    bool EnumFile(const std::string &src_path,std::vector<std::string> *files_list)
    {
        namespace fs = boost::filesystem;
        fs::path root_path(src_path);
    
        //判断路径是否存在,不存在就没必要往后走了
        if(!fs::exists(root_path))
        { 
            //std::cerr<< src_path<<"not exists"<
            LOG2(FATAL,"src_path not exists");
            return false;
        }
        //定义一个空的迭代器,用来进行判断递归结束
        fs::recursive_directory_iterator end;
        for(fs::recursive_directory_iterator iter(root_path);iter != end;iter++){
            //判断文件是否是普通文件(html是普通文件)
            if(!fs::is_regular_file(*iter))
            {
                continue;
            }
            if(iter->path().extension()!= ".html"){//判断文件路径名的后缀是否符合要求 path()提取路径字符串,是一个路径对象   ,extension()提取后缀(.以及之后的部分)
                 continue;
            }
            //std::cout<<"debug: " <path().string()<
            //当前的路径一定是一个合法的,以.html结束的普通网页文件、
            files_list->push_back(iter->path().string());//将所有带路径的html保存到files_list,方便后续进行文本分析
    
        }
        return true;
    }
    static bool ParseTitle(const std::string &file,std::string *title){
        
        std::size_t begin = file.find(""</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span><span class="token punctuation">(</span>begin <span class="token operator">==</span> std<span class="token double-colon punctuation">::</span>string<span class="token double-colon punctuation">::</span>npos<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
            <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        std<span class="token double-colon punctuation">::</span>size_t end <span class="token operator">=</span> file<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token string">"");
        if(end==std::string::npos)
        {
            return false;
        }
        begin+=std::string(""</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    
        <span class="token keyword">if</span><span class="token punctuation">(</span>begin<span class="token operator">></span>end<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
            <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    
        <span class="token operator">*</span>title <span class="token operator">=</span> file<span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span>begin<span class="token punctuation">,</span>end<span class="token operator">-</span>begin<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">static</span> <span class="token keyword">bool</span> <span class="token function">ParseContent</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>file<span class="token punctuation">,</span>std<span class="token double-colon punctuation">::</span>string <span class="token operator">*</span>content<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
        
        <span class="token comment">//去标签,基于一个简易的状态机编写</span>
        <span class="token keyword">enum</span> <span class="token class-name">status</span><span class="token punctuation">{<!-- --></span>
            LABLE<span class="token punctuation">,</span>
            CONTENT
        <span class="token punctuation">}</span><span class="token punctuation">;</span>
        <span class="token keyword">enum</span> <span class="token class-name">status</span> s<span class="token operator">=</span>LABLE<span class="token punctuation">;</span>
        <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">char</span> c <span class="token operator">:</span>file<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
            <span class="token keyword">switch</span><span class="token punctuation">(</span>s<span class="token punctuation">)</span>
            <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">case</span> LABLE<span class="token operator">:</span>
                    <span class="token keyword">if</span><span class="token punctuation">(</span>c<span class="token operator">==</span><span class="token char">'>'</span><span class="token punctuation">)</span> s<span class="token operator">=</span> CONTENT<span class="token punctuation">;</span>
                    <span class="token keyword">break</span><span class="token punctuation">;</span>
                <span class="token keyword">case</span> CONTENT<span class="token operator">:</span>
                    <span class="token keyword">if</span><span class="token punctuation">(</span>c<span class="token operator">==</span><span class="token char">'<'</span><span class="token punctuation">)</span> s<span class="token operator">=</span> LABLE<span class="token punctuation">;</span>
                    <span class="token keyword">else</span>
                    <span class="token punctuation">{<!-- --></span>
                        <span class="token comment">//我们不想要保留原始文件中的‘\n’,因为我们想用\n作为html解析之后文本的分隔符</span>
                        <span class="token keyword">if</span><span class="token punctuation">(</span>c<span class="token operator">==</span><span class="token char">'\n'</span><span class="token punctuation">)</span>c<span class="token operator">=</span><span class="token char">' '</span><span class="token punctuation">;</span>
                        content<span class="token operator">-></span><span class="token function">push_back</span><span class="token punctuation">(</span>c<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                    <span class="token keyword">break</span><span class="token punctuation">;</span>
                <span class="token keyword">default</span><span class="token operator">:</span>
                    <span class="token keyword">break</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
    
        <span class="token punctuation">}</span>
        
        <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">static</span> <span class="token keyword">bool</span> <span class="token function">ParseUrl</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>file_path<span class="token punctuation">,</span>std<span class="token double-colon punctuation">::</span>string <span class="token operator">*</span>url<span class="token punctuation">)</span>
    <span class="token punctuation">{<!-- --></span>
        std<span class="token double-colon punctuation">::</span>string url_head <span class="token operator">=</span>  <span class="token string">"https://www.boost.org/doc/libs/1_78_0/doc/html"</span><span class="token punctuation">;</span>
        std<span class="token double-colon punctuation">::</span>string url_tail <span class="token operator">=</span> file_path<span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span>src_path<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//越过长度截取</span>
        <span class="token operator">*</span>url <span class="token operator">=</span> url_head <span class="token operator">+</span> url_tail<span class="token punctuation">;</span>
        <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    
    <span class="token comment">//for debug</span>
    <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">ShowDoc</span><span class="token punctuation">(</span><span class="token keyword">const</span> DocInfo_t <span class="token operator">&</span>doc<span class="token punctuation">)</span>
    <span class="token punctuation">{<!-- --></span>
        std<span class="token double-colon punctuation">::</span>cout<span class="token operator"><<</span><span class="token string">"title:"</span><span class="token operator"><<</span>doc<span class="token punctuation">.</span>title <span class="token operator"><<</span> std<span class="token double-colon punctuation">::</span>endl<span class="token punctuation">;</span>
        std<span class="token double-colon punctuation">::</span>cout<span class="token operator"><<</span><span class="token string">"content:"</span><span class="token operator"><<</span>doc<span class="token punctuation">.</span>content <span class="token operator"><<</span> std<span class="token double-colon punctuation">::</span>endl<span class="token punctuation">;</span>
        std<span class="token double-colon punctuation">::</span>cout<span class="token operator"><<</span><span class="token string">"url:"</span><span class="token operator"><<</span>doc<span class="token punctuation">.</span>url <span class="token operator"><<</span> std<span class="token double-colon punctuation">::</span>endl<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    
    <span class="token keyword">bool</span> <span class="token function">ParseHtml</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span> <span class="token operator">&</span>files_list<span class="token punctuation">,</span>std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>DocInfo_t<span class="token operator">></span> <span class="token operator">*</span>results<span class="token punctuation">)</span>
    <span class="token punctuation">{<!-- --></span>
        <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>file <span class="token operator">:</span> files_list<span class="token punctuation">)</span>
        <span class="token punctuation">{<!-- --></span>
            <span class="token comment">//1.读取文件,Read()</span>
            std<span class="token double-colon punctuation">::</span>string result<span class="token punctuation">;</span>
            <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span>ns_util<span class="token double-colon punctuation">::</span><span class="token class-name">FileUtil</span><span class="token double-colon punctuation">::</span><span class="token function">ReadFile</span><span class="token punctuation">(</span>file<span class="token punctuation">,</span><span class="token operator">&</span>result<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
                <span class="token keyword">continue</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//2.解析指定的文件,提取title</span>
            DocInfo_t doc<span class="token punctuation">;</span>
            <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">ParseTitle</span><span class="token punctuation">(</span>result<span class="token punctuation">,</span><span class="token operator">&</span>doc<span class="token punctuation">.</span>title<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
                <span class="token keyword">continue</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//3.解析指定的文件,提取content</span>
            <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">ParseContent</span><span class="token punctuation">(</span>result<span class="token punctuation">,</span><span class="token operator">&</span>doc<span class="token punctuation">.</span>content<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
                <span class="token keyword">continue</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//4.解析指定的文件路径,构建url</span>
            <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">ParseUrl</span><span class="token punctuation">(</span>file<span class="token punctuation">,</span><span class="token operator">&</span>doc<span class="token punctuation">.</span>url<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
                <span class="token keyword">continue</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//done,一定是完成了解析任务,当前文档的相关结果都保存在doc中</span>
            results<span class="token operator">-></span><span class="token function">push_back</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">move</span><span class="token punctuation">(</span>doc<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//bug to do细节,本质会发生拷贝,效率可能会比较低 (move是细节)</span>
            <span class="token comment">//std::cout<<1<<std::endl;</span>
            <span class="token comment">//for debug</span>
            <span class="token comment">//ShowDoc(doc);</span>
            <span class="token comment">//break;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">bool</span> <span class="token function">SaveHtml</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>DocInfo_t<span class="token operator">></span> <span class="token operator">&</span>results<span class="token punctuation">,</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>output<span class="token punctuation">)</span>
    <span class="token punctuation">{<!-- --></span>   
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">SEP</span> <span class="token char">'\3'</span></span>
        <span class="token comment">//按照二进制方式进行写入</span>
        std<span class="token double-colon punctuation">::</span>ofstream <span class="token function">out</span><span class="token punctuation">(</span>output<span class="token punctuation">,</span>std<span class="token double-colon punctuation">::</span>ios<span class="token double-colon punctuation">::</span>out <span class="token operator">|</span> std<span class="token double-colon punctuation">::</span>ios<span class="token double-colon punctuation">::</span>binary<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span>out<span class="token punctuation">.</span><span class="token function">is_open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
            <span class="token comment">//std::cerr<<"open "<<output <<"failed!"<<std::endl;</span>
            <span class="token function">LOG2</span><span class="token punctuation">(</span>FATAL<span class="token punctuation">,</span><span class="token string">"open output failed!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token comment">//就可以进行文件内容的写入了</span>
        <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">auto</span> <span class="token operator">&</span>item <span class="token operator">:</span> results<span class="token punctuation">)</span>
        <span class="token punctuation">{<!-- --></span>
            std<span class="token double-colon punctuation">::</span>string out_string<span class="token punctuation">;</span>
            out_string <span class="token operator">=</span> item<span class="token punctuation">.</span>title<span class="token punctuation">;</span>
            out_string<span class="token operator">+=</span>SEP<span class="token punctuation">;</span>
            out_string <span class="token operator">+=</span>item<span class="token punctuation">.</span>content<span class="token punctuation">;</span>
            out_string <span class="token operator">+=</span>SEP<span class="token punctuation">;</span>
            out_string <span class="token operator">+=</span>item<span class="token punctuation">.</span>url<span class="token punctuation">;</span>
            out_string<span class="token operator">+=</span><span class="token char">'\n'</span><span class="token punctuation">;</span>
    
            out<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span>out_string<span class="token punctuation">.</span><span class="token function">c_str</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>out_string<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    
        out<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    
    <span class="token comment">//strstr 前闭后开</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li><li style="color: rgb(153, 153, 153);">39</li><li style="color: rgb(153, 153, 153);">40</li><li style="color: rgb(153, 153, 153);">41</li><li style="color: rgb(153, 153, 153);">42</li><li style="color: rgb(153, 153, 153);">43</li><li style="color: rgb(153, 153, 153);">44</li><li style="color: rgb(153, 153, 153);">45</li><li style="color: rgb(153, 153, 153);">46</li><li style="color: rgb(153, 153, 153);">47</li><li style="color: rgb(153, 153, 153);">48</li><li style="color: rgb(153, 153, 153);">49</li><li style="color: rgb(153, 153, 153);">50</li><li style="color: rgb(153, 153, 153);">51</li><li style="color: rgb(153, 153, 153);">52</li><li style="color: rgb(153, 153, 153);">53</li><li style="color: rgb(153, 153, 153);">54</li><li style="color: rgb(153, 153, 153);">55</li><li style="color: rgb(153, 153, 153);">56</li><li style="color: rgb(153, 153, 153);">57</li><li style="color: rgb(153, 153, 153);">58</li><li style="color: rgb(153, 153, 153);">59</li><li style="color: rgb(153, 153, 153);">60</li><li style="color: rgb(153, 153, 153);">61</li><li style="color: rgb(153, 153, 153);">62</li><li style="color: rgb(153, 153, 153);">63</li><li style="color: rgb(153, 153, 153);">64</li><li style="color: rgb(153, 153, 153);">65</li><li style="color: rgb(153, 153, 153);">66</li><li style="color: rgb(153, 153, 153);">67</li><li style="color: rgb(153, 153, 153);">68</li><li style="color: rgb(153, 153, 153);">69</li><li style="color: rgb(153, 153, 153);">70</li><li style="color: rgb(153, 153, 153);">71</li><li style="color: rgb(153, 153, 153);">72</li><li style="color: rgb(153, 153, 153);">73</li><li style="color: rgb(153, 153, 153);">74</li><li style="color: rgb(153, 153, 153);">75</li><li style="color: rgb(153, 153, 153);">76</li><li style="color: rgb(153, 153, 153);">77</li><li style="color: rgb(153, 153, 153);">78</li><li style="color: rgb(153, 153, 153);">79</li><li style="color: rgb(153, 153, 153);">80</li><li style="color: rgb(153, 153, 153);">81</li><li style="color: rgb(153, 153, 153);">82</li><li style="color: rgb(153, 153, 153);">83</li><li style="color: rgb(153, 153, 153);">84</li><li style="color: rgb(153, 153, 153);">85</li><li style="color: rgb(153, 153, 153);">86</li><li style="color: rgb(153, 153, 153);">87</li><li style="color: rgb(153, 153, 153);">88</li><li style="color: rgb(153, 153, 153);">89</li><li style="color: rgb(153, 153, 153);">90</li><li style="color: rgb(153, 153, 153);">91</li><li style="color: rgb(153, 153, 153);">92</li><li style="color: rgb(153, 153, 153);">93</li><li style="color: rgb(153, 153, 153);">94</li><li style="color: rgb(153, 153, 153);">95</li><li style="color: rgb(153, 153, 153);">96</li><li style="color: rgb(153, 153, 153);">97</li><li style="color: rgb(153, 153, 153);">98</li><li style="color: rgb(153, 153, 153);">99</li><li style="color: rgb(153, 153, 153);">100</li><li style="color: rgb(153, 153, 153);">101</li><li style="color: rgb(153, 153, 153);">102</li><li style="color: rgb(153, 153, 153);">103</li><li style="color: rgb(153, 153, 153);">104</li><li style="color: rgb(153, 153, 153);">105</li><li style="color: rgb(153, 153, 153);">106</li><li style="color: rgb(153, 153, 153);">107</li><li style="color: rgb(153, 153, 153);">108</li><li style="color: rgb(153, 153, 153);">109</li><li style="color: rgb(153, 153, 153);">110</li><li style="color: rgb(153, 153, 153);">111</li><li style="color: rgb(153, 153, 153);">112</li><li style="color: rgb(153, 153, 153);">113</li><li style="color: rgb(153, 153, 153);">114</li><li style="color: rgb(153, 153, 153);">115</li><li style="color: rgb(153, 153, 153);">116</li><li style="color: rgb(153, 153, 153);">117</li><li style="color: rgb(153, 153, 153);">118</li><li style="color: rgb(153, 153, 153);">119</li><li style="color: rgb(153, 153, 153);">120</li><li style="color: rgb(153, 153, 153);">121</li><li style="color: rgb(153, 153, 153);">122</li><li style="color: rgb(153, 153, 153);">123</li><li style="color: rgb(153, 153, 153);">124</li><li style="color: rgb(153, 153, 153);">125</li><li style="color: rgb(153, 153, 153);">126</li><li style="color: rgb(153, 153, 153);">127</li><li style="color: rgb(153, 153, 153);">128</li><li style="color: rgb(153, 153, 153);">129</li><li style="color: rgb(153, 153, 153);">130</li><li style="color: rgb(153, 153, 153);">131</li><li style="color: rgb(153, 153, 153);">132</li><li style="color: rgb(153, 153, 153);">133</li><li style="color: rgb(153, 153, 153);">134</li><li style="color: rgb(153, 153, 153);">135</li><li style="color: rgb(153, 153, 153);">136</li><li style="color: rgb(153, 153, 153);">137</li><li style="color: rgb(153, 153, 153);">138</li><li style="color: rgb(153, 153, 153);">139</li><li style="color: rgb(153, 153, 153);">140</li><li style="color: rgb(153, 153, 153);">141</li><li style="color: rgb(153, 153, 153);">142</li><li style="color: rgb(153, 153, 153);">143</li><li style="color: rgb(153, 153, 153);">144</li><li style="color: rgb(153, 153, 153);">145</li><li style="color: rgb(153, 153, 153);">146</li><li style="color: rgb(153, 153, 153);">147</li><li style="color: rgb(153, 153, 153);">148</li><li style="color: rgb(153, 153, 153);">149</li><li style="color: rgb(153, 153, 153);">150</li><li style="color: rgb(153, 153, 153);">151</li><li style="color: rgb(153, 153, 153);">152</li><li style="color: rgb(153, 153, 153);">153</li><li style="color: rgb(153, 153, 153);">154</li><li style="color: rgb(153, 153, 153);">155</li><li style="color: rgb(153, 153, 153);">156</li><li style="color: rgb(153, 153, 153);">157</li><li style="color: rgb(153, 153, 153);">158</li><li style="color: rgb(153, 153, 153);">159</li><li style="color: rgb(153, 153, 153);">160</li><li style="color: rgb(153, 153, 153);">161</li><li style="color: rgb(153, 153, 153);">162</li><li style="color: rgb(153, 153, 153);">163</li><li style="color: rgb(153, 153, 153);">164</li><li style="color: rgb(153, 153, 153);">165</li><li style="color: rgb(153, 153, 153);">166</li><li style="color: rgb(153, 153, 153);">167</li><li style="color: rgb(153, 153, 153);">168</li><li style="color: rgb(153, 153, 153);">169</li><li style="color: rgb(153, 153, 153);">170</li><li style="color: rgb(153, 153, 153);">171</li><li style="color: rgb(153, 153, 153);">172</li><li style="color: rgb(153, 153, 153);">173</li><li style="color: rgb(153, 153, 153);">174</li><li style="color: rgb(153, 153, 153);">175</li><li style="color: rgb(153, 153, 153);">176</li><li style="color: rgb(153, 153, 153);">177</li><li style="color: rgb(153, 153, 153);">178</li><li style="color: rgb(153, 153, 153);">179</li><li style="color: rgb(153, 153, 153);">180</li><li style="color: rgb(153, 153, 153);">181</li><li style="color: rgb(153, 153, 153);">182</li><li style="color: rgb(153, 153, 153);">183</li><li style="color: rgb(153, 153, 153);">184</li><li style="color: rgb(153, 153, 153);">185</li><li style="color: rgb(153, 153, 153);">186</li><li style="color: rgb(153, 153, 153);">187</li><li style="color: rgb(153, 153, 153);">188</li><li style="color: rgb(153, 153, 153);">189</li><li style="color: rgb(153, 153, 153);">190</li><li style="color: rgb(153, 153, 153);">191</li><li style="color: rgb(153, 153, 153);">192</li><li style="color: rgb(153, 153, 153);">193</li><li style="color: rgb(153, 153, 153);">194</li><li style="color: rgb(153, 153, 153);">195</li><li style="color: rgb(153, 153, 153);">196</li><li style="color: rgb(153, 153, 153);">197</li><li style="color: rgb(153, 153, 153);">198</li><li style="color: rgb(153, 153, 153);">199</li><li style="color: rgb(153, 153, 153);">200</li><li style="color: rgb(153, 153, 153);">201</li><li style="color: rgb(153, 153, 153);">202</li><li style="color: rgb(153, 153, 153);">203</li><li style="color: rgb(153, 153, 153);">204</li><li style="color: rgb(153, 153, 153);">205</li><li style="color: rgb(153, 153, 153);">206</li><li style="color: rgb(153, 153, 153);">207</li><li style="color: rgb(153, 153, 153);">208</li></ul></pre> 
    <h4><a name="t7"></a><a id="searcherhpp_621"></a>searcher.hpp</h4> 
    <pre data-index="4" class="set-code-hide prettyprint"><code class="prism language-cpp has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">pragma</span> <span class="token expression">once</span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">"index.hpp"</span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">"util.hpp"</span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><algorithm></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><jsoncpp/json/json.h></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">"log.hpp"</span></span>
    <span class="token comment">//#include <vector></span>
    <span class="token keyword">namespace</span> ns_searcher<span class="token punctuation">{<!-- --></span>
    
        <span class="token keyword">struct</span> <span class="token class-name">InvertedElemPrint</span><span class="token punctuation">{<!-- --></span>
            <span class="token keyword">uint64_t</span> doc_id<span class="token punctuation">;</span>
            <span class="token keyword">int</span> weight<span class="token punctuation">;</span>
    
            std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span> words<span class="token punctuation">;</span>
            <span class="token function">InvertedElemPrint</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token function">doc_id</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token function">weight</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span>
            
        <span class="token punctuation">}</span><span class="token punctuation">;</span>
    
        <span class="token keyword">class</span> <span class="token class-name">Searcher</span><span class="token punctuation">{<!-- --></span>
            <span class="token keyword">private</span><span class="token operator">:</span>
                ns_index<span class="token double-colon punctuation">::</span>Index <span class="token operator">*</span>index<span class="token punctuation">;</span>
            <span class="token keyword">public</span><span class="token operator">:</span>
                <span class="token function">Searcher</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span>
                <span class="token operator">~</span><span class="token function">Searcher</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span>
            <span class="token keyword">public</span><span class="token operator">:</span>
                <span class="token keyword">void</span> <span class="token function">InitSearcher</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>input<span class="token punctuation">)</span>
                <span class="token punctuation">{<!-- --></span>
                    <span class="token comment">//1. 获取或者创建index对象</span>
                    index <span class="token operator">=</span> ns_index<span class="token double-colon punctuation">::</span><span class="token class-name">Index</span><span class="token double-colon punctuation">::</span><span class="token function">GetInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token comment">//std::cout <<"获取index单例成功..."<<std::endl;</span>
                    <span class="token function">LOG2</span><span class="token punctuation">(</span>NORMAL<span class="token punctuation">,</span><span class="token string">"获取index单例成功..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token comment">//2. 根据index对象建立索引</span>
                    index<span class="token operator">-></span><span class="token function">BuildIndex</span><span class="token punctuation">(</span>input<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//CutString</span>
                    <span class="token comment">//std::cout<<"建立正排和倒排索引成功..."<<std::endl;</span>
                    <span class="token function">LOG2</span><span class="token punctuation">(</span>NORMAL<span class="token punctuation">,</span><span class="token string">"建立正排和倒排索引成功..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token comment">//query:搜索关键字</span>
                <span class="token comment">//json_string:返回给用户浏览器的搜索结果</span>
                <span class="token keyword">void</span> <span class="token function">Search</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>query<span class="token punctuation">,</span>std<span class="token double-colon punctuation">::</span>string <span class="token operator">*</span>json_string<span class="token punctuation">)</span>
                <span class="token punctuation">{<!-- --></span>
                    <span class="token comment">//1. [分词]:对我们的query进行按照searcher的要求进行分词</span>
                    std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span> words<span class="token punctuation">;</span>
                    ns_util<span class="token double-colon punctuation">::</span><span class="token class-name">JiebaUtil</span><span class="token double-colon punctuation">::</span><span class="token function">CutString</span><span class="token punctuation">(</span>query<span class="token punctuation">,</span><span class="token operator">&</span>words<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token comment">//2. [触发]:就是根据分词的各个“词,进行index查找”,建立index是忽略大小写,所以搜索关键字也需要</span>
                    <span class="token comment">//ns_index::InvertedList inverted_list_all;</span>
                    std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>InvertedElemPrint<span class="token operator">></span> inverted_list_all<span class="token punctuation">;</span>
                    std<span class="token double-colon punctuation">::</span>unordered_map<span class="token operator"><</span><span class="token keyword">uint64_t</span><span class="token punctuation">,</span>InvertedElemPrint<span class="token operator">></span> tokens_map<span class="token punctuation">;</span>
                    <span class="token keyword">for</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span>string word <span class="token operator">:</span> words<span class="token punctuation">)</span>
                    <span class="token punctuation">{<!-- --></span>
                        boost<span class="token double-colon punctuation">::</span><span class="token function">to_lower</span><span class="token punctuation">(</span>word<span class="token punctuation">)</span><span class="token punctuation">;</span>
    
                        ns_index<span class="token double-colon punctuation">::</span>InvertedList <span class="token operator">*</span>inverted_list <span class="token operator">=</span> index<span class="token operator">-></span><span class="token function">GetInvertedList</span><span class="token punctuation">(</span>word<span class="token punctuation">)</span><span class="token punctuation">;</span>
                        <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token keyword">nullptr</span> <span class="token operator">==</span> inverted_list<span class="token punctuation">)</span>
                        <span class="token punctuation">{<!-- --></span>
                            <span class="token keyword">continue</span><span class="token punctuation">;</span>
                        <span class="token punctuation">}</span>
                        <span class="token comment">//不完美的地方(去重)</span>
                        <span class="token comment">//inverted_list_all.insert(inverted_list_all.end(),inverted_list->begin(),inverted_list->end());</span>
                        <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">auto</span> <span class="token operator">&</span>elem <span class="token operator">:</span> <span class="token operator">*</span>inverted_list<span class="token punctuation">)</span>
                        <span class="token punctuation">{<!-- --></span>
                            <span class="token keyword">auto</span> <span class="token operator">&</span>item <span class="token operator">=</span> tokens_map<span class="token punctuation">[</span>elem<span class="token punctuation">.</span>doc_id<span class="token punctuation">]</span><span class="token punctuation">;</span>
                            <span class="token comment">//item一定是doc_id相同的print节点</span>
                            item<span class="token punctuation">.</span>doc_id <span class="token operator">=</span>elem<span class="token punctuation">.</span>doc_id<span class="token punctuation">;</span>
                            item<span class="token punctuation">.</span>weight <span class="token operator">+=</span> elem<span class="token punctuation">.</span>weight<span class="token punctuation">;</span>
                            item<span class="token punctuation">.</span>words<span class="token punctuation">.</span><span class="token function">push_back</span><span class="token punctuation">(</span>elem<span class="token punctuation">.</span>word<span class="token punctuation">)</span><span class="token punctuation">;</span>
                        <span class="token punctuation">}</span>
                    <span class="token punctuation">}</span>
                    <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">auto</span><span class="token operator">&</span>item <span class="token operator">:</span> tokens_map<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
                        inverted_list_all<span class="token punctuation">.</span><span class="token function">push_back</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">move</span><span class="token punctuation">(</span>item<span class="token punctuation">.</span>second<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                        
                    <span class="token punctuation">}</span>
                    <span class="token comment">//3. [合并排序]:汇总查找结果,按照相关性(weight)降序排序</span>
                    <span class="token comment">/*std::sort(inverted_list_all.begin(),inverted_list_all.end(),\
                    [](const ns_index::InvertedElem &e1,const ns_index::InvertedElem &e2){
                        return e1.weight>e2.weight;
                    }
                    
                    );
                    */</span>
                   std<span class="token double-colon punctuation">::</span><span class="token function">sort</span><span class="token punctuation">(</span>inverted_list_all<span class="token punctuation">.</span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>inverted_list_all<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>\
                   <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">const</span> InvertedElemPrint<span class="token operator">&</span>e1<span class="token punctuation">,</span><span class="token keyword">const</span> InvertedElemPrint<span class="token operator">&</span> e2<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> e1<span class="token punctuation">.</span>weight <span class="token operator">></span>e2<span class="token punctuation">.</span>weight<span class="token punctuation">;</span>
                   <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token comment">//4. [构建]:根据查找出来的结果,构建json串————jsoncpp----通过jsoncpp完成序列化和反序列化</span>
                    Json<span class="token double-colon punctuation">::</span>Value root<span class="token punctuation">;</span>
                    <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">auto</span> <span class="token operator">&</span>item <span class="token operator">:</span> inverted_list_all<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
                        ns_index<span class="token double-colon punctuation">::</span>DocInfo <span class="token operator">*</span>doc <span class="token operator">=</span> index<span class="token operator">-></span><span class="token function">GetForwardIndex</span><span class="token punctuation">(</span>item<span class="token punctuation">.</span>doc_id<span class="token punctuation">)</span><span class="token punctuation">;</span>
                        <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token keyword">nullptr</span> <span class="token operator">==</span> doc<span class="token punctuation">)</span>
                        <span class="token punctuation">{<!-- --></span>
                            <span class="token keyword">continue</span><span class="token punctuation">;</span>
                        <span class="token punctuation">}</span>
                        Json<span class="token double-colon punctuation">::</span>Value elem<span class="token punctuation">;</span>
                        elem<span class="token punctuation">[</span><span class="token string">"title"</span><span class="token punctuation">]</span> <span class="token operator">=</span> doc<span class="token operator">-></span>title<span class="token punctuation">;</span>
                        elem<span class="token punctuation">[</span><span class="token string">"desc"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">GetDesc</span><span class="token punctuation">(</span>doc<span class="token operator">-></span>content<span class="token punctuation">,</span>item<span class="token punctuation">.</span>words<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">//content是文档的去标签的结果,但是不是我们想要的,我们要的是一部分</span>
                        elem<span class="token punctuation">[</span><span class="token string">"url"</span><span class="token punctuation">]</span> <span class="token operator">=</span> doc<span class="token operator">-></span>url<span class="token punctuation">;</span>
    
                        <span class="token comment">//foe debug</span>
                        <span class="token comment">//elem["id"]= (int)item.doc_id;//doc_id是64位的uint64_t</span>
                        <span class="token comment">//elem["weight"] = item.weight;</span>
                    
                        root<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span>elem<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>   
                    <span class="token comment">//Json::StyledWriter writer;</span>
                    Json<span class="token double-colon punctuation">::</span>FastWriter writer<span class="token punctuation">;</span>
                    <span class="token operator">*</span>json_string <span class="token operator">=</span> writer<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span>root<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
    
                std<span class="token double-colon punctuation">::</span>string <span class="token function">GetDesc</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>html_content<span class="token punctuation">,</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>word<span class="token punctuation">)</span>
                <span class="token punctuation">{<!-- --></span>
                    <span class="token comment">//找到word在html_content中的首次出现,然后往前找50个字节(如果没有,从begin开始),往后找100个字节(如果没有,到end就可以),截取出这部分内容</span>
                    <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>size_t prev_step <span class="token operator">=</span> <span class="token number">50</span><span class="token punctuation">;</span>
                    <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>size_t next_step <span class="token operator">=</span><span class="token number">100</span><span class="token punctuation">;</span>
                    <span class="token comment">//1. 找到首次出现</span>
                    <span class="token keyword">auto</span> iter <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span><span class="token function">search</span><span class="token punctuation">(</span>html_content<span class="token punctuation">.</span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>html_content<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>word<span class="token punctuation">.</span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>word<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">int</span> x<span class="token punctuation">,</span><span class="token keyword">int</span> y<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
                        <span class="token keyword">return</span> <span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">tolower</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token operator">==</span>std<span class="token double-colon punctuation">::</span><span class="token function">tolower</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    
                    <span class="token keyword">if</span><span class="token punctuation">(</span>iter <span class="token operator">==</span> html_content<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
                    <span class="token punctuation">{<!-- --></span>
                        <span class="token keyword">return</span> <span class="token string">"None1"</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                    std<span class="token double-colon punctuation">::</span>size_t pos <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span><span class="token function">distance</span><span class="token punctuation">(</span>html_content<span class="token punctuation">.</span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>iter<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token comment">/*std::size_t pos = html_content.find(word);
                    if(pos == std::string::npos){
                        return "None1";//这种情况是不存在的
                    }*/</span>
                    <span class="token comment">//2. 获取start,end           //这里有一个大坑,就是std::size_t是一个无符号数,无符号数相减为正数</span>
                    std<span class="token double-colon punctuation">::</span>size_t start <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
                    std<span class="token double-colon punctuation">::</span>size_t end <span class="token operator">=</span> html_content<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span>
                    <span class="token comment">//如果之前有50个字符,就更新开始位置</span>
                    <span class="token keyword">if</span><span class="token punctuation">(</span>pos  <span class="token operator">></span>start<span class="token operator">+</span> prev_step<span class="token punctuation">)</span> start <span class="token operator">=</span> pos <span class="token operator">-</span>prev_step<span class="token punctuation">;</span><span class="token comment">//换成加法</span>
                    <span class="token keyword">if</span><span class="token punctuation">(</span>pos <span class="token operator">+</span> next_step <span class="token operator"><</span>end<span class="token punctuation">)</span> end <span class="token operator">=</span> pos <span class="token operator">+</span> next_step<span class="token punctuation">;</span>
                    <span class="token comment">//3. 截取子串,return</span>
                    <span class="token keyword">if</span><span class="token punctuation">(</span>start <span class="token operator">>=</span> end<span class="token punctuation">)</span><span class="token keyword">return</span> <span class="token string">"None2"</span><span class="token punctuation">;</span>
                     
                    std<span class="token double-colon punctuation">::</span>string desc <span class="token operator">=</span> html_content<span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span>start<span class="token punctuation">,</span>end<span class="token operator">-</span>start<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    std<span class="token double-colon punctuation">::</span>string result<span class="token operator">=</span><span class="token string">"..."</span> <span class="token operator">+</span> desc <span class="token operator">+</span> <span class="token string">"..."</span><span class="token punctuation">;</span>
                    <span class="token keyword">return</span> result<span class="token punctuation">;</span>
                
                <span class="token punctuation">}</span>
             
        <span class="token punctuation">}</span><span class="token punctuation">;</span>
    
    
    <span class="token punctuation">}</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li><li style="color: rgb(153, 153, 153);">39</li><li style="color: rgb(153, 153, 153);">40</li><li style="color: rgb(153, 153, 153);">41</li><li style="color: rgb(153, 153, 153);">42</li><li style="color: rgb(153, 153, 153);">43</li><li style="color: rgb(153, 153, 153);">44</li><li style="color: rgb(153, 153, 153);">45</li><li style="color: rgb(153, 153, 153);">46</li><li style="color: rgb(153, 153, 153);">47</li><li style="color: rgb(153, 153, 153);">48</li><li style="color: rgb(153, 153, 153);">49</li><li style="color: rgb(153, 153, 153);">50</li><li style="color: rgb(153, 153, 153);">51</li><li style="color: rgb(153, 153, 153);">52</li><li style="color: rgb(153, 153, 153);">53</li><li style="color: rgb(153, 153, 153);">54</li><li style="color: rgb(153, 153, 153);">55</li><li style="color: rgb(153, 153, 153);">56</li><li style="color: rgb(153, 153, 153);">57</li><li style="color: rgb(153, 153, 153);">58</li><li style="color: rgb(153, 153, 153);">59</li><li style="color: rgb(153, 153, 153);">60</li><li style="color: rgb(153, 153, 153);">61</li><li style="color: rgb(153, 153, 153);">62</li><li style="color: rgb(153, 153, 153);">63</li><li style="color: rgb(153, 153, 153);">64</li><li style="color: rgb(153, 153, 153);">65</li><li style="color: rgb(153, 153, 153);">66</li><li style="color: rgb(153, 153, 153);">67</li><li style="color: rgb(153, 153, 153);">68</li><li style="color: rgb(153, 153, 153);">69</li><li style="color: rgb(153, 153, 153);">70</li><li style="color: rgb(153, 153, 153);">71</li><li style="color: rgb(153, 153, 153);">72</li><li style="color: rgb(153, 153, 153);">73</li><li style="color: rgb(153, 153, 153);">74</li><li style="color: rgb(153, 153, 153);">75</li><li style="color: rgb(153, 153, 153);">76</li><li style="color: rgb(153, 153, 153);">77</li><li style="color: rgb(153, 153, 153);">78</li><li style="color: rgb(153, 153, 153);">79</li><li style="color: rgb(153, 153, 153);">80</li><li style="color: rgb(153, 153, 153);">81</li><li style="color: rgb(153, 153, 153);">82</li><li style="color: rgb(153, 153, 153);">83</li><li style="color: rgb(153, 153, 153);">84</li><li style="color: rgb(153, 153, 153);">85</li><li style="color: rgb(153, 153, 153);">86</li><li style="color: rgb(153, 153, 153);">87</li><li style="color: rgb(153, 153, 153);">88</li><li style="color: rgb(153, 153, 153);">89</li><li style="color: rgb(153, 153, 153);">90</li><li style="color: rgb(153, 153, 153);">91</li><li style="color: rgb(153, 153, 153);">92</li><li style="color: rgb(153, 153, 153);">93</li><li style="color: rgb(153, 153, 153);">94</li><li style="color: rgb(153, 153, 153);">95</li><li style="color: rgb(153, 153, 153);">96</li><li style="color: rgb(153, 153, 153);">97</li><li style="color: rgb(153, 153, 153);">98</li><li style="color: rgb(153, 153, 153);">99</li><li style="color: rgb(153, 153, 153);">100</li><li style="color: rgb(153, 153, 153);">101</li><li style="color: rgb(153, 153, 153);">102</li><li style="color: rgb(153, 153, 153);">103</li><li style="color: rgb(153, 153, 153);">104</li><li style="color: rgb(153, 153, 153);">105</li><li style="color: rgb(153, 153, 153);">106</li><li style="color: rgb(153, 153, 153);">107</li><li style="color: rgb(153, 153, 153);">108</li><li style="color: rgb(153, 153, 153);">109</li><li style="color: rgb(153, 153, 153);">110</li><li style="color: rgb(153, 153, 153);">111</li><li style="color: rgb(153, 153, 153);">112</li><li style="color: rgb(153, 153, 153);">113</li><li style="color: rgb(153, 153, 153);">114</li><li style="color: rgb(153, 153, 153);">115</li><li style="color: rgb(153, 153, 153);">116</li><li style="color: rgb(153, 153, 153);">117</li><li style="color: rgb(153, 153, 153);">118</li><li style="color: rgb(153, 153, 153);">119</li><li style="color: rgb(153, 153, 153);">120</li><li style="color: rgb(153, 153, 153);">121</li><li style="color: rgb(153, 153, 153);">122</li><li style="color: rgb(153, 153, 153);">123</li><li style="color: rgb(153, 153, 153);">124</li><li style="color: rgb(153, 153, 153);">125</li><li style="color: rgb(153, 153, 153);">126</li><li style="color: rgb(153, 153, 153);">127</li><li style="color: rgb(153, 153, 153);">128</li><li style="color: rgb(153, 153, 153);">129</li><li style="color: rgb(153, 153, 153);">130</li><li style="color: rgb(153, 153, 153);">131</li><li style="color: rgb(153, 153, 153);">132</li><li style="color: rgb(153, 153, 153);">133</li><li style="color: rgb(153, 153, 153);">134</li><li style="color: rgb(153, 153, 153);">135</li><li style="color: rgb(153, 153, 153);">136</li><li style="color: rgb(153, 153, 153);">137</li><li style="color: rgb(153, 153, 153);">138</li><li style="color: rgb(153, 153, 153);">139</li><li style="color: rgb(153, 153, 153);">140</li><li style="color: rgb(153, 153, 153);">141</li><li style="color: rgb(153, 153, 153);">142</li><li style="color: rgb(153, 153, 153);">143</li><li style="color: rgb(153, 153, 153);">144</li><li style="color: rgb(153, 153, 153);">145</li></ul></pre> 
    <h4><a name="t8"></a><a id="utilhpp_771"></a>util.hpp</h4> 
    <pre data-index="5" class="set-code-hide prettyprint"><code class="prism language-cpp has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">pragma</span> <span class="token expression">once</span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><iostream></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><string></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><fstream></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><vector></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">"boost_1_84_0/boost/algorithm/string.hpp"</span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">"../cppjieba/include/cppjieba/Jieba.hpp"</span></span>
    <span class="token comment">//#include "cppjieba/jieba"</span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">"log.hpp"</span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><mutex></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><unordered_map></span></span>
    <span class="token keyword">namespace</span> ns_util<span class="token punctuation">{<!-- --></span>
        <span class="token keyword">class</span> <span class="token class-name">FileUtil</span>
        <span class="token punctuation">{<!-- --></span>
        <span class="token keyword">public</span><span class="token operator">:</span>
            <span class="token keyword">static</span> <span class="token keyword">bool</span> <span class="token function">ReadFile</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>file_path<span class="token punctuation">,</span>std<span class="token double-colon punctuation">::</span>string <span class="token operator">*</span>out<span class="token punctuation">)</span>
            <span class="token punctuation">{<!-- --></span>
                std<span class="token double-colon punctuation">::</span>ifstream <span class="token function">in</span><span class="token punctuation">(</span>file_path<span class="token punctuation">,</span>std<span class="token double-colon punctuation">::</span>ios<span class="token double-colon punctuation">::</span>in<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span>in<span class="token punctuation">.</span><span class="token function">is_open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
                <span class="token punctuation">{<!-- --></span>
                    <span class="token comment">//std::cerr << "open_file" << file_path <<"error" <<std::endl;</span>
                    <span class="token function">LOG2</span><span class="token punctuation">(</span>FATAL<span class="token punctuation">,</span><span class="token string">"open_file error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
        
                std<span class="token double-colon punctuation">::</span>string line<span class="token punctuation">;</span>
                <span class="token keyword">while</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">getline</span><span class="token punctuation">(</span>in<span class="token punctuation">,</span>line<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span><span class="token comment">//如何理解getline读取到文件结束呢??getline到返回值是一个&,while(bool),本质是因为重载了强制类型转换</span>
                    <span class="token operator">*</span>out <span class="token operator">+=</span> line<span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                in<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
    
        <span class="token punctuation">}</span><span class="token punctuation">;</span>
        <span class="token keyword">class</span> <span class="token class-name">StringUtil</span><span class="token punctuation">{<!-- --></span>
        <span class="token keyword">public</span><span class="token operator">:</span>
            <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">Split</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&</span>target<span class="token punctuation">,</span>std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span><span class="token operator">*</span>out<span class="token punctuation">,</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&</span> sep<span class="token punctuation">)</span>
            <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//boost split</span>
                boost<span class="token double-colon punctuation">::</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token operator">*</span>out<span class="token punctuation">,</span>target<span class="token punctuation">,</span>boost<span class="token double-colon punctuation">::</span><span class="token function">is_any_of</span><span class="token punctuation">(</span>sep<span class="token punctuation">)</span><span class="token punctuation">,</span>boost<span class="token double-colon punctuation">::</span>token_compress_on<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span><span class="token punctuation">;</span>
        <span class="token keyword">const</span> <span class="token keyword">char</span><span class="token operator">*</span> <span class="token keyword">const</span> DICT_PATH <span class="token operator">=</span> <span class="token string">"./dict/jieba.dict.utf8"</span><span class="token punctuation">;</span>
        <span class="token keyword">const</span> <span class="token keyword">char</span><span class="token operator">*</span> <span class="token keyword">const</span> HMM_PATH <span class="token operator">=</span> <span class="token string">"./dict/hmm_model.utf8"</span><span class="token punctuation">;</span>
        <span class="token keyword">const</span> <span class="token keyword">char</span><span class="token operator">*</span> <span class="token keyword">const</span> USER_DICT_PATH <span class="token operator">=</span> <span class="token string">"./dict/user.dict.utf8"</span><span class="token punctuation">;</span>
        <span class="token keyword">const</span> <span class="token keyword">char</span><span class="token operator">*</span> <span class="token keyword">const</span> IDF_PATH <span class="token operator">=</span> <span class="token string">"./dict/idf.utf8"</span><span class="token punctuation">;</span>
        <span class="token keyword">const</span> <span class="token keyword">char</span><span class="token operator">*</span> <span class="token keyword">const</span> STOP_WORD_PATH <span class="token operator">=</span> <span class="token string">"./dict/stop_words.utf8"</span><span class="token punctuation">;</span>
        
        <span class="token keyword">class</span> <span class="token class-name">JiebaUtil</span>
        <span class="token punctuation">{<!-- --></span>
        <span class="token keyword">private</span><span class="token operator">:</span>
            <span class="token comment">//static cppjieba::Jieba jieba;</span>
            cppjieba<span class="token double-colon punctuation">::</span>Jieba jieba<span class="token punctuation">;</span>
            std<span class="token double-colon punctuation">::</span>unordered_map<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token punctuation">,</span><span class="token keyword">bool</span><span class="token operator">></span> stop_words<span class="token punctuation">;</span>    
        <span class="token keyword">private</span><span class="token operator">:</span>
            <span class="token function">JiebaUtil</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token function">jieba</span><span class="token punctuation">(</span>DICT_PATH<span class="token punctuation">,</span>HMM_PATH<span class="token punctuation">,</span>USER_DICT_PATH<span class="token punctuation">,</span>IDF_PATH<span class="token punctuation">,</span>STOP_WORD_PATH<span class="token punctuation">)</span>
            <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span>
            <span class="token function">JiebaUtil</span><span class="token punctuation">(</span><span class="token keyword">const</span> JiebaUtil<span class="token operator">&</span><span class="token punctuation">)</span><span class="token operator">=</span><span class="token keyword">delete</span><span class="token punctuation">;</span>
            JiebaUtil<span class="token operator">&</span> <span class="token keyword">operator</span><span class="token operator">=</span><span class="token punctuation">(</span>JiebaUtil <span class="token keyword">const</span><span class="token operator">&</span><span class="token punctuation">)</span><span class="token operator">=</span><span class="token keyword">delete</span><span class="token punctuation">;</span>
            <span class="token keyword">static</span> JiebaUtil <span class="token operator">*</span>instance<span class="token punctuation">;</span>
        <span class="token keyword">public</span><span class="token operator">:</span>
            <span class="token keyword">static</span> JiebaUtil<span class="token operator">*</span><span class="token function">get_instance</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
            <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">static</span> std<span class="token double-colon punctuation">::</span>mutex mtx<span class="token punctuation">;</span>
                <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token keyword">nullptr</span><span class="token operator">==</span>instance<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
                    mtx<span class="token punctuation">.</span><span class="token function">lock</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token keyword">nullptr</span> <span class="token operator">==</span>instance<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
                        instance <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token function">JiebaUtil</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                        instance<span class="token operator">-></span><span class="token function">InitJiebaUtil</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                    mtx<span class="token punctuation">.</span><span class="token function">unlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> instance<span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">InitJiebaUtil</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
            <span class="token punctuation">{<!-- --></span>
                std<span class="token double-colon punctuation">::</span>ifstream <span class="token function">in</span><span class="token punctuation">(</span>STOP_WORD_PATH<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span>in<span class="token punctuation">.</span><span class="token function">is_open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
                <span class="token punctuation">{<!-- --></span>
                    <span class="token function">LOG2</span><span class="token punctuation">(</span>FATAL<span class="token punctuation">,</span><span class="token string">"load stop words fill error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token keyword">return</span> <span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                std<span class="token double-colon punctuation">::</span>string line<span class="token punctuation">;</span>
                <span class="token keyword">while</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">getline</span><span class="token punctuation">(</span>in<span class="token punctuation">,</span>line<span class="token punctuation">)</span><span class="token punctuation">)</span>
                <span class="token punctuation">{<!-- --></span>
                    stop_words<span class="token punctuation">.</span><span class="token function">insert</span><span class="token punctuation">(</span><span class="token punctuation">{<!-- --></span>line<span class="token punctuation">,</span><span class="token boolean">true</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    
                <span class="token punctuation">}</span>
                in<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">CutStringHelper</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>src<span class="token punctuation">,</span>std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span><span class="token operator">*</span>out<span class="token punctuation">)</span>
            <span class="token punctuation">{<!-- --></span>
               
                
                jieba<span class="token punctuation">.</span><span class="token function">CutForSearch</span><span class="token punctuation">(</span>src<span class="token punctuation">,</span><span class="token operator">*</span>out<span class="token punctuation">)</span><span class="token punctuation">;</span>
                std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span> <span class="token function">v</span><span class="token punctuation">(</span><span class="token operator">*</span>out<span class="token punctuation">)</span><span class="token punctuation">;</span>
    
                <span class="token comment">//  //for debug</span>
                <span class="token comment">// for(auto e : v)</span>
                <span class="token comment">// {<!-- --></span>
                <span class="token comment">//     std::cout<<"暂停词测试存储 v:"<<e<<"----"<<std::endl;</span>
                <span class="token comment">// }</span>
                
    
    
                <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">auto</span> iter<span class="token operator">=</span>out<span class="token operator">-></span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>iter<span class="token operator">!=</span>out<span class="token operator">-></span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">auto</span> it <span class="token operator">=</span>stop_words<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token operator">*</span>iter<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token keyword">if</span><span class="token punctuation">(</span>it<span class="token operator">!=</span>stop_words<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
                    <span class="token punctuation">{<!-- --></span>
                        <span class="token comment">//说明当前的string是暂停词,需要去掉</span>
                        iter <span class="token operator">=</span> out<span class="token operator">-></span><span class="token function">erase</span><span class="token punctuation">(</span>iter<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                    <span class="token keyword">else</span>
                    <span class="token punctuation">{<!-- --></span>
                        iter<span class="token operator">++</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                <span class="token punctuation">}</span>
    
                <span class="token keyword">if</span><span class="token punctuation">(</span>out<span class="token operator">-></span><span class="token function">empty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
                <span class="token punctuation">{<!-- --></span>
                    <span class="token comment">//std::cout<< "out为空"<<std::endl;</span>
                    <span class="token operator">*</span>out <span class="token operator">=</span> v<span class="token punctuation">;</span>
    
                <span class="token punctuation">}</span>
                
                <span class="token comment">//debug</span>
    
                <span class="token comment">// std::cout<< out->empty()<<std::endl;</span>
                <span class="token comment">// for(auto e : *out)</span>
                <span class="token comment">// {<!-- --></span>
                <span class="token comment">//     std::cout<<"暂停词测试out 后:"<<e<<"----"<<std::endl;</span>
                <span class="token comment">// }</span>
                
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">CutString_has_stop_words</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>src<span class="token punctuation">,</span>std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span><span class="token operator">*</span>out<span class="token punctuation">)</span>
            <span class="token punctuation">{<!-- --></span>
                jieba<span class="token punctuation">.</span><span class="token function">CutForSearch</span><span class="token punctuation">(</span>src<span class="token punctuation">,</span><span class="token operator">*</span>out<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token keyword">public</span><span class="token operator">:</span>
    
            <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">CutString</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>src<span class="token punctuation">,</span>std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span> <span class="token operator">*</span>out<span class="token punctuation">)</span>
            <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//debug</span>
                <span class="token comment">//std::cout<< "CutStringHelper" << std::endl;</span>
    
                ns_util<span class="token double-colon punctuation">::</span><span class="token class-name">JiebaUtil</span><span class="token double-colon punctuation">::</span><span class="token function">get_instance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">CutStringHelper</span><span class="token punctuation">(</span>src<span class="token punctuation">,</span>out<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token comment">//jieba.CutForSearch(src,*out);</span>
            <span class="token punctuation">}</span>
    
            <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">CutString2</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>src<span class="token punctuation">,</span>std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span> <span class="token operator">*</span>out<span class="token punctuation">)</span>
            <span class="token punctuation">{<!-- --></span>
    
                <span class="token comment">//debug</span>
                <span class="token comment">//std::cout<< "CutString2()" << std::endl;</span>
                ns_util<span class="token double-colon punctuation">::</span><span class="token class-name">JiebaUtil</span><span class="token double-colon punctuation">::</span><span class="token function">get_instance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">CutString_has_stop_words</span><span class="token punctuation">(</span>src<span class="token punctuation">,</span>out<span class="token punctuation">)</span><span class="token punctuation">;</span>
    
            
     
            <span class="token punctuation">}</span>
        
        <span class="token comment">//cppjieba::Jieba JiebaUtil::jieba(DICT_PATH,HMM_PATH,USER_DICT_PATH,IDF_PATH,STOP_WORD_PATH);</span>
        <span class="token punctuation">}</span><span class="token punctuation">;</span>
        JiebaUtil <span class="token operator">*</span>JiebaUtil<span class="token double-colon punctuation">::</span>instance <span class="token operator">=</span> <span class="token keyword">nullptr</span><span class="token punctuation">;</span>
    <span class="token comment">//加static是因为这个函数要被外部使用,加了static可以不创建对象就可以使用</span>
    <span class="token punctuation">}</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li><li style="color: rgb(153, 153, 153);">39</li><li style="color: rgb(153, 153, 153);">40</li><li style="color: rgb(153, 153, 153);">41</li><li style="color: rgb(153, 153, 153);">42</li><li style="color: rgb(153, 153, 153);">43</li><li style="color: rgb(153, 153, 153);">44</li><li style="color: rgb(153, 153, 153);">45</li><li style="color: rgb(153, 153, 153);">46</li><li style="color: rgb(153, 153, 153);">47</li><li style="color: rgb(153, 153, 153);">48</li><li style="color: rgb(153, 153, 153);">49</li><li style="color: rgb(153, 153, 153);">50</li><li style="color: rgb(153, 153, 153);">51</li><li style="color: rgb(153, 153, 153);">52</li><li style="color: rgb(153, 153, 153);">53</li><li style="color: rgb(153, 153, 153);">54</li><li style="color: rgb(153, 153, 153);">55</li><li style="color: rgb(153, 153, 153);">56</li><li style="color: rgb(153, 153, 153);">57</li><li style="color: rgb(153, 153, 153);">58</li><li style="color: rgb(153, 153, 153);">59</li><li style="color: rgb(153, 153, 153);">60</li><li style="color: rgb(153, 153, 153);">61</li><li style="color: rgb(153, 153, 153);">62</li><li style="color: rgb(153, 153, 153);">63</li><li style="color: rgb(153, 153, 153);">64</li><li style="color: rgb(153, 153, 153);">65</li><li style="color: rgb(153, 153, 153);">66</li><li style="color: rgb(153, 153, 153);">67</li><li style="color: rgb(153, 153, 153);">68</li><li style="color: rgb(153, 153, 153);">69</li><li style="color: rgb(153, 153, 153);">70</li><li style="color: rgb(153, 153, 153);">71</li><li style="color: rgb(153, 153, 153);">72</li><li style="color: rgb(153, 153, 153);">73</li><li style="color: rgb(153, 153, 153);">74</li><li style="color: rgb(153, 153, 153);">75</li><li style="color: rgb(153, 153, 153);">76</li><li style="color: rgb(153, 153, 153);">77</li><li style="color: rgb(153, 153, 153);">78</li><li style="color: rgb(153, 153, 153);">79</li><li style="color: rgb(153, 153, 153);">80</li><li style="color: rgb(153, 153, 153);">81</li><li style="color: rgb(153, 153, 153);">82</li><li style="color: rgb(153, 153, 153);">83</li><li style="color: rgb(153, 153, 153);">84</li><li style="color: rgb(153, 153, 153);">85</li><li style="color: rgb(153, 153, 153);">86</li><li style="color: rgb(153, 153, 153);">87</li><li style="color: rgb(153, 153, 153);">88</li><li style="color: rgb(153, 153, 153);">89</li><li style="color: rgb(153, 153, 153);">90</li><li style="color: rgb(153, 153, 153);">91</li><li style="color: rgb(153, 153, 153);">92</li><li style="color: rgb(153, 153, 153);">93</li><li style="color: rgb(153, 153, 153);">94</li><li style="color: rgb(153, 153, 153);">95</li><li style="color: rgb(153, 153, 153);">96</li><li style="color: rgb(153, 153, 153);">97</li><li style="color: rgb(153, 153, 153);">98</li><li style="color: rgb(153, 153, 153);">99</li><li style="color: rgb(153, 153, 153);">100</li><li style="color: rgb(153, 153, 153);">101</li><li style="color: rgb(153, 153, 153);">102</li><li style="color: rgb(153, 153, 153);">103</li><li style="color: rgb(153, 153, 153);">104</li><li style="color: rgb(153, 153, 153);">105</li><li style="color: rgb(153, 153, 153);">106</li><li style="color: rgb(153, 153, 153);">107</li><li style="color: rgb(153, 153, 153);">108</li><li style="color: rgb(153, 153, 153);">109</li><li style="color: rgb(153, 153, 153);">110</li><li style="color: rgb(153, 153, 153);">111</li><li style="color: rgb(153, 153, 153);">112</li><li style="color: rgb(153, 153, 153);">113</li><li style="color: rgb(153, 153, 153);">114</li><li style="color: rgb(153, 153, 153);">115</li><li style="color: rgb(153, 153, 153);">116</li><li style="color: rgb(153, 153, 153);">117</li><li style="color: rgb(153, 153, 153);">118</li><li style="color: rgb(153, 153, 153);">119</li><li style="color: rgb(153, 153, 153);">120</li><li style="color: rgb(153, 153, 153);">121</li><li style="color: rgb(153, 153, 153);">122</li><li style="color: rgb(153, 153, 153);">123</li><li style="color: rgb(153, 153, 153);">124</li><li style="color: rgb(153, 153, 153);">125</li><li style="color: rgb(153, 153, 153);">126</li><li style="color: rgb(153, 153, 153);">127</li><li style="color: rgb(153, 153, 153);">128</li><li style="color: rgb(153, 153, 153);">129</li><li style="color: rgb(153, 153, 153);">130</li><li style="color: rgb(153, 153, 153);">131</li><li style="color: rgb(153, 153, 153);">132</li><li style="color: rgb(153, 153, 153);">133</li><li style="color: rgb(153, 153, 153);">134</li><li style="color: rgb(153, 153, 153);">135</li><li style="color: rgb(153, 153, 153);">136</li><li style="color: rgb(153, 153, 153);">137</li><li style="color: rgb(153, 153, 153);">138</li><li style="color: rgb(153, 153, 153);">139</li><li style="color: rgb(153, 153, 153);">140</li><li style="color: rgb(153, 153, 153);">141</li><li style="color: rgb(153, 153, 153);">142</li><li style="color: rgb(153, 153, 153);">143</li><li style="color: rgb(153, 153, 153);">144</li><li style="color: rgb(153, 153, 153);">145</li><li style="color: rgb(153, 153, 153);">146</li><li style="color: rgb(153, 153, 153);">147</li><li style="color: rgb(153, 153, 153);">148</li><li style="color: rgb(153, 153, 153);">149</li><li style="color: rgb(153, 153, 153);">150</li><li style="color: rgb(153, 153, 153);">151</li><li style="color: rgb(153, 153, 153);">152</li><li style="color: rgb(153, 153, 153);">153</li><li style="color: rgb(153, 153, 153);">154</li><li style="color: rgb(153, 153, 153);">155</li><li style="color: rgb(153, 153, 153);">156</li><li style="color: rgb(153, 153, 153);">157</li><li style="color: rgb(153, 153, 153);">158</li><li style="color: rgb(153, 153, 153);">159</li><li style="color: rgb(153, 153, 153);">160</li><li style="color: rgb(153, 153, 153);">161</li><li style="color: rgb(153, 153, 153);">162</li><li style="color: rgb(153, 153, 153);">163</li><li style="color: rgb(153, 153, 153);">164</li><li style="color: rgb(153, 153, 153);">165</li><li style="color: rgb(153, 153, 153);">166</li></ul></pre> 
    <h4><a name="t9"></a><a id="http_servercc_944"></a>http_server.cc(用于启动服务器和搜索引擎)</h4> 
    <pre data-index="6" class="set-code-hide prettyprint"><code class="prism language-cpp has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">"searcher.hpp"</span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">"httplib.h"</span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">"../http.hpp"</span></span>
    
    <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string root_path <span class="token operator">=</span> <span class="token string">"./wwwroot"</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string input <span class="token operator">=</span> <span class="token string">"data/raw_html/raw.txt"</span><span class="token punctuation">;</span>
    
    ns_searcher<span class="token double-colon punctuation">::</span>Searcher search<span class="token punctuation">;</span>
    
    
    std<span class="token double-colon punctuation">::</span>string <span class="token function">RequestStr</span><span class="token punctuation">(</span><span class="token keyword">const</span> HttpRequest <span class="token operator">&</span>req<span class="token punctuation">)</span>
    <span class="token punctuation">{<!-- --></span>
        std<span class="token double-colon punctuation">::</span>stringstream ss<span class="token punctuation">;</span>
        ss <span class="token operator"><<</span> req<span class="token punctuation">.</span>_method <span class="token operator"><<</span> <span class="token string">" "</span> <span class="token operator"><<</span> req<span class="token punctuation">.</span>_path <span class="token operator"><<</span> <span class="token string">" "</span> <span class="token operator"><<</span> req<span class="token punctuation">.</span>_version <span class="token operator"><<</span> <span class="token string">"\r\n"</span><span class="token punctuation">;</span>
        <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">auto</span> it <span class="token operator">:</span> req<span class="token punctuation">.</span>_params<span class="token punctuation">)</span>
        <span class="token punctuation">{<!-- --></span>
            ss <span class="token operator"><<</span> it<span class="token punctuation">.</span>first <span class="token operator"><<</span> <span class="token string">": "</span> <span class="token operator"><<</span> it<span class="token punctuation">.</span>second <span class="token operator"><<</span> <span class="token string">"\r\n"</span><span class="token punctuation">;</span>
            <span class="token function">DBG_LOG</span><span class="token punctuation">(</span><span class="token string">"RequestStr_params: first:%s ,second:%s"</span><span class="token punctuation">,</span> it<span class="token punctuation">.</span>first<span class="token punctuation">,</span> it<span class="token punctuation">.</span>second<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">auto</span> it <span class="token operator">:</span> req<span class="token punctuation">.</span>_headers<span class="token punctuation">)</span>
        <span class="token punctuation">{<!-- --></span>
            ss <span class="token operator"><<</span> it<span class="token punctuation">.</span>first <span class="token operator"><<</span> <span class="token string">": "</span> <span class="token operator"><<</span> it<span class="token punctuation">.</span>second <span class="token operator"><<</span> <span class="token string">"\r\n"</span><span class="token punctuation">;</span>
            <span class="token function">DBG_LOG</span><span class="token punctuation">(</span><span class="token string">"RequestStr_headers: first:%s ,second:%s"</span><span class="token punctuation">,</span> it<span class="token punctuation">.</span>first<span class="token punctuation">.</span><span class="token function">c_str</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> it<span class="token punctuation">.</span>second<span class="token punctuation">.</span><span class="token function">c_str</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    
        ss <span class="token operator"><<</span> <span class="token string">"\r\n"</span><span class="token punctuation">;</span>
        ss <span class="token operator"><<</span> req<span class="token punctuation">.</span>_body<span class="token punctuation">;</span>
        <span class="token keyword">return</span> ss<span class="token punctuation">.</span><span class="token function">str</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">void</span> <span class="token function">Hello</span><span class="token punctuation">(</span><span class="token keyword">const</span> HttpRequest <span class="token operator">&</span>req<span class="token punctuation">,</span> HttpResponse <span class="token operator">*</span>rsp<span class="token punctuation">)</span>
    <span class="token punctuation">{<!-- --></span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>req<span class="token punctuation">.</span><span class="token function">HasParam</span><span class="token punctuation">(</span><span class="token string">"word"</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
        <span class="token punctuation">{<!-- --></span>
            rsp<span class="token operator">-></span><span class="token function">SetContent</span><span class="token punctuation">(</span><span class="token string">"必须要有搜索关键字!"</span><span class="token punctuation">,</span> <span class="token string">"text/plain; charset=utf-8"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">return</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    
        <span class="token comment">// rsp.set_content("hello world!你好世界\n","text/plain; charset=utf-8");</span>
    
        <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string word <span class="token operator">=</span> req<span class="token punctuation">.</span><span class="token function">GetParam</span><span class="token punctuation">(</span><span class="token string">"word"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 获取名为word的参数值</span>
        <span class="token comment">// debug</span>
        <span class="token comment">// std::cout<<"test:"<<word<<std::endl;</span>
    
        <span class="token comment">// std::cout<<"用户在搜索:"<<word<<std::endl;</span>
        <span class="token comment">//LOG2(NORMAL, "用户搜索的:" + word);</span>
        std<span class="token double-colon punctuation">::</span>string json_string<span class="token punctuation">;</span>
        search<span class="token punctuation">.</span><span class="token function">Search</span><span class="token punctuation">(</span>word<span class="token punctuation">,</span> <span class="token operator">&</span>json_string<span class="token punctuation">)</span><span class="token punctuation">;</span>
        rsp<span class="token operator">-></span><span class="token function">SetContent</span><span class="token punctuation">(</span>json_string<span class="token punctuation">,</span> <span class="token string">"application/json"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment">//rsp->SetContent(RequestStr(req), "text/plain");</span>
    <span class="token punctuation">}</span>
    
    <span class="token keyword">void</span> <span class="token function">Login</span><span class="token punctuation">(</span><span class="token keyword">const</span> HttpRequest <span class="token operator">&</span>req<span class="token punctuation">,</span> HttpResponse <span class="token operator">*</span>rsp<span class="token punctuation">)</span>
    <span class="token punctuation">{<!-- --></span>
    
      
        rsp<span class="token operator">-></span><span class="token function">SetContent</span><span class="token punctuation">(</span><span class="token function">RequestStr</span><span class="token punctuation">(</span>req<span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token string">"text/plain"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    
    <span class="token keyword">void</span> <span class="token function">PutFile</span><span class="token punctuation">(</span><span class="token keyword">const</span> HttpRequest <span class="token operator">&</span>req<span class="token punctuation">,</span> HttpResponse <span class="token operator">*</span>rsp<span class="token punctuation">)</span>
    <span class="token punctuation">{<!-- --></span>
        rsp<span class="token operator">-></span><span class="token function">SetContent</span><span class="token punctuation">(</span><span class="token function">RequestStr</span><span class="token punctuation">(</span>req<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"text/plain"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    
    <span class="token keyword">void</span> <span class="token function">DelFile</span><span class="token punctuation">(</span><span class="token keyword">const</span> HttpRequest <span class="token operator">&</span>req<span class="token punctuation">,</span> HttpResponse <span class="token operator">*</span>rsp<span class="token punctuation">)</span>
    <span class="token punctuation">{<!-- --></span>
        rsp<span class="token operator">-></span><span class="token function">SetContent</span><span class="token punctuation">(</span><span class="token function">RequestStr</span><span class="token punctuation">(</span>req<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"text/plain"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>       
    <span class="token punctuation">{<!-- --></span>
      
        search<span class="token punctuation">.</span><span class="token function">InitSearcher</span><span class="token punctuation">(</span>input<span class="token punctuation">)</span><span class="token punctuation">;</span>
        HttpServer <span class="token function">server</span><span class="token punctuation">(</span><span class="token number">8085</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        server<span class="token punctuation">.</span><span class="token function">SetThreadCount</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        server<span class="token punctuation">.</span><span class="token function">SetBaseDir</span><span class="token punctuation">(</span>root_path<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 设置静态资源根目录,告诉服务器有静态资源请求到来,需要到哪里去找资源路径</span>
        server<span class="token punctuation">.</span><span class="token function">Get</span><span class="token punctuation">(</span><span class="token string">"/s"</span><span class="token punctuation">,</span> Hello<span class="token punctuation">)</span><span class="token punctuation">;</span>
        server<span class="token punctuation">.</span><span class="token function">Post</span><span class="token punctuation">(</span><span class="token string">"/login"</span><span class="token punctuation">,</span> Login<span class="token punctuation">)</span><span class="token punctuation">;</span>
        server<span class="token punctuation">.</span><span class="token function">Put</span><span class="token punctuation">(</span><span class="token string">"/1234.txt"</span><span class="token punctuation">,</span> PutFile<span class="token punctuation">)</span><span class="token punctuation">;</span>
        server<span class="token punctuation">.</span><span class="token function">Delete</span><span class="token punctuation">(</span><span class="token string">"/1234.txt"</span><span class="token punctuation">,</span> DelFile<span class="token punctuation">)</span><span class="token punctuation">;</span>
        server<span class="token punctuation">.</span><span class="token function">Listen</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        
    
        <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li><li style="color: rgb(153, 153, 153);">39</li><li style="color: rgb(153, 153, 153);">40</li><li style="color: rgb(153, 153, 153);">41</li><li style="color: rgb(153, 153, 153);">42</li><li style="color: rgb(153, 153, 153);">43</li><li style="color: rgb(153, 153, 153);">44</li><li style="color: rgb(153, 153, 153);">45</li><li style="color: rgb(153, 153, 153);">46</li><li style="color: rgb(153, 153, 153);">47</li><li style="color: rgb(153, 153, 153);">48</li><li style="color: rgb(153, 153, 153);">49</li><li style="color: rgb(153, 153, 153);">50</li><li style="color: rgb(153, 153, 153);">51</li><li style="color: rgb(153, 153, 153);">52</li><li style="color: rgb(153, 153, 153);">53</li><li style="color: rgb(153, 153, 153);">54</li><li style="color: rgb(153, 153, 153);">55</li><li style="color: rgb(153, 153, 153);">56</li><li style="color: rgb(153, 153, 153);">57</li><li style="color: rgb(153, 153, 153);">58</li><li style="color: rgb(153, 153, 153);">59</li><li style="color: rgb(153, 153, 153);">60</li><li style="color: rgb(153, 153, 153);">61</li><li style="color: rgb(153, 153, 153);">62</li><li style="color: rgb(153, 153, 153);">63</li><li style="color: rgb(153, 153, 153);">64</li><li style="color: rgb(153, 153, 153);">65</li><li style="color: rgb(153, 153, 153);">66</li><li style="color: rgb(153, 153, 153);">67</li><li style="color: rgb(153, 153, 153);">68</li><li style="color: rgb(153, 153, 153);">69</li><li style="color: rgb(153, 153, 153);">70</li><li style="color: rgb(153, 153, 153);">71</li><li style="color: rgb(153, 153, 153);">72</li><li style="color: rgb(153, 153, 153);">73</li><li style="color: rgb(153, 153, 153);">74</li><li style="color: rgb(153, 153, 153);">75</li><li style="color: rgb(153, 153, 153);">76</li><li style="color: rgb(153, 153, 153);">77</li><li style="color: rgb(153, 153, 153);">78</li><li style="color: rgb(153, 153, 153);">79</li><li style="color: rgb(153, 153, 153);">80</li><li style="color: rgb(153, 153, 153);">81</li><li style="color: rgb(153, 153, 153);">82</li><li style="color: rgb(153, 153, 153);">83</li></ul></pre> 
    <h3><a name="t10"></a><a id="_1036"></a>高并发服务器部分</h3> 
    <h4><a name="t11"></a><a id="httphpp_1040"></a>http.hpp</h4> 
    <pre data-index="7" class="set-code-hide prettyprint"><code class="prism language-cpp has-numbering" onclick="mdcp.signin(event)" style="position: unset;">
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><iostream></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><fstream></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><string></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><vector></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><regex></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><sys/stat.h></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">"../server.hpp"</span></span>
    
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">DEFALT_TIMEOUT</span> <span class="token expression"><span class="token number">10</span></span></span>
    
    std<span class="token double-colon punctuation">::</span>unordered_map<span class="token operator"><</span><span class="token keyword">int</span><span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span> _statu_msg <span class="token operator">=</span> <span class="token punctuation">{<!-- --></span>
        <span class="token punctuation">{<!-- --></span><span class="token number">100</span><span class="token punctuation">,</span>  <span class="token string">"Continue"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">101</span><span class="token punctuation">,</span>  <span class="token string">"Switching Protocol"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">102</span><span class="token punctuation">,</span>  <span class="token string">"Processing"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">103</span><span class="token punctuation">,</span>  <span class="token string">"Early Hints"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">200</span><span class="token punctuation">,</span>  <span class="token string">"OK"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">201</span><span class="token punctuation">,</span>  <span class="token string">"Created"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">202</span><span class="token punctuation">,</span>  <span class="token string">"Accepted"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">203</span><span class="token punctuation">,</span>  <span class="token string">"Non-Authoritative Information"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">204</span><span class="token punctuation">,</span>  <span class="token string">"No Content"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">205</span><span class="token punctuation">,</span>  <span class="token string">"Reset Content"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">206</span><span class="token punctuation">,</span>  <span class="token string">"Partial Content"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">207</span><span class="token punctuation">,</span>  <span class="token string">"Multi-Status"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">208</span><span class="token punctuation">,</span>  <span class="token string">"Already Reported"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">226</span><span class="token punctuation">,</span>  <span class="token string">"IM Used"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">300</span><span class="token punctuation">,</span>  <span class="token string">"Multiple Choice"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">301</span><span class="token punctuation">,</span>  <span class="token string">"Moved Permanently"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">302</span><span class="token punctuation">,</span>  <span class="token string">"Found"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">303</span><span class="token punctuation">,</span>  <span class="token string">"See Other"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">304</span><span class="token punctuation">,</span>  <span class="token string">"Not Modified"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">305</span><span class="token punctuation">,</span>  <span class="token string">"Use Proxy"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">306</span><span class="token punctuation">,</span>  <span class="token string">"unused"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">307</span><span class="token punctuation">,</span>  <span class="token string">"Temporary Redirect"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">308</span><span class="token punctuation">,</span>  <span class="token string">"Permanent Redirect"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">400</span><span class="token punctuation">,</span>  <span class="token string">"Bad Request"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">401</span><span class="token punctuation">,</span>  <span class="token string">"Unauthorized"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">402</span><span class="token punctuation">,</span>  <span class="token string">"Payment Required"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">403</span><span class="token punctuation">,</span>  <span class="token string">"Forbidden"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">404</span><span class="token punctuation">,</span>  <span class="token string">"Not Found"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">405</span><span class="token punctuation">,</span>  <span class="token string">"Method Not Allowed"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">406</span><span class="token punctuation">,</span>  <span class="token string">"Not Acceptable"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">407</span><span class="token punctuation">,</span>  <span class="token string">"Proxy Authentication Required"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">408</span><span class="token punctuation">,</span>  <span class="token string">"Request Timeout"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">409</span><span class="token punctuation">,</span>  <span class="token string">"Conflict"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">410</span><span class="token punctuation">,</span>  <span class="token string">"Gone"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">411</span><span class="token punctuation">,</span>  <span class="token string">"Length Required"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">412</span><span class="token punctuation">,</span>  <span class="token string">"Precondition Failed"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">413</span><span class="token punctuation">,</span>  <span class="token string">"Payload Too Large"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">414</span><span class="token punctuation">,</span>  <span class="token string">"URI Too Long"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">415</span><span class="token punctuation">,</span>  <span class="token string">"Unsupported Media Type"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">416</span><span class="token punctuation">,</span>  <span class="token string">"Range Not Satisfiable"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">417</span><span class="token punctuation">,</span>  <span class="token string">"Expectation Failed"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">418</span><span class="token punctuation">,</span>  <span class="token string">"I'm a teapot"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">421</span><span class="token punctuation">,</span>  <span class="token string">"Misdirected Request"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">422</span><span class="token punctuation">,</span>  <span class="token string">"Unprocessable Entity"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">423</span><span class="token punctuation">,</span>  <span class="token string">"Locked"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">424</span><span class="token punctuation">,</span>  <span class="token string">"Failed Dependency"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">425</span><span class="token punctuation">,</span>  <span class="token string">"Too Early"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">426</span><span class="token punctuation">,</span>  <span class="token string">"Upgrade Required"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">428</span><span class="token punctuation">,</span>  <span class="token string">"Precondition Required"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">429</span><span class="token punctuation">,</span>  <span class="token string">"Too Many Requests"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">431</span><span class="token punctuation">,</span>  <span class="token string">"Request Header Fields Too Large"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">451</span><span class="token punctuation">,</span>  <span class="token string">"Unavailable For Legal Reasons"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">501</span><span class="token punctuation">,</span>  <span class="token string">"Not Implemented"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">502</span><span class="token punctuation">,</span>  <span class="token string">"Bad Gateway"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">503</span><span class="token punctuation">,</span>  <span class="token string">"Service Unavailable"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">504</span><span class="token punctuation">,</span>  <span class="token string">"Gateway Timeout"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">505</span><span class="token punctuation">,</span>  <span class="token string">"HTTP Version Not Supported"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">506</span><span class="token punctuation">,</span>  <span class="token string">"Variant Also Negotiates"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">507</span><span class="token punctuation">,</span>  <span class="token string">"Insufficient Storage"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">508</span><span class="token punctuation">,</span>  <span class="token string">"Loop Detected"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">510</span><span class="token punctuation">,</span>  <span class="token string">"Not Extended"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token number">511</span><span class="token punctuation">,</span>  <span class="token string">"Network Authentication Required"</span><span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    
    std<span class="token double-colon punctuation">::</span>unordered_map<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span> _mime_msg <span class="token operator">=</span> <span class="token punctuation">{<!-- --></span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".aac"</span><span class="token punctuation">,</span>        <span class="token string">"audio/aac"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".abw"</span><span class="token punctuation">,</span>        <span class="token string">"application/x-abiword"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".arc"</span><span class="token punctuation">,</span>        <span class="token string">"application/x-freearc"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".avi"</span><span class="token punctuation">,</span>        <span class="token string">"video/x-msvideo"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".azw"</span><span class="token punctuation">,</span>        <span class="token string">"application/vnd.amazon.ebook"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".bin"</span><span class="token punctuation">,</span>        <span class="token string">"application/octet-stream"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".bmp"</span><span class="token punctuation">,</span>        <span class="token string">"image/bmp"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".bz"</span><span class="token punctuation">,</span>         <span class="token string">"application/x-bzip"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".bz2"</span><span class="token punctuation">,</span>        <span class="token string">"application/x-bzip2"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".csh"</span><span class="token punctuation">,</span>        <span class="token string">"application/x-csh"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".css"</span><span class="token punctuation">,</span>        <span class="token string">"text/css"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".csv"</span><span class="token punctuation">,</span>        <span class="token string">"text/csv"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".doc"</span><span class="token punctuation">,</span>        <span class="token string">"application/msword"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".docx"</span><span class="token punctuation">,</span>       <span class="token string">"application/vnd.openxmlformats-officedocument.wordprocessingml.document"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".eot"</span><span class="token punctuation">,</span>        <span class="token string">"application/vnd.ms-fontobject"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".epub"</span><span class="token punctuation">,</span>       <span class="token string">"application/epub+zip"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".gif"</span><span class="token punctuation">,</span>        <span class="token string">"image/gif"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".htm"</span><span class="token punctuation">,</span>        <span class="token string">"text/html"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".html"</span><span class="token punctuation">,</span>       <span class="token string">"text/html"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".ico"</span><span class="token punctuation">,</span>        <span class="token string">"image/vnd.microsoft.icon"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".ics"</span><span class="token punctuation">,</span>        <span class="token string">"text/calendar"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".jar"</span><span class="token punctuation">,</span>        <span class="token string">"application/java-archive"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".jpeg"</span><span class="token punctuation">,</span>       <span class="token string">"image/jpeg"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".jpg"</span><span class="token punctuation">,</span>        <span class="token string">"image/jpeg"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".js"</span><span class="token punctuation">,</span>         <span class="token string">"text/javascript"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".json"</span><span class="token punctuation">,</span>       <span class="token string">"application/json"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".jsonld"</span><span class="token punctuation">,</span>     <span class="token string">"application/ld+json"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".mid"</span><span class="token punctuation">,</span>        <span class="token string">"audio/midi"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".midi"</span><span class="token punctuation">,</span>       <span class="token string">"audio/x-midi"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".mjs"</span><span class="token punctuation">,</span>        <span class="token string">"text/javascript"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".mp3"</span><span class="token punctuation">,</span>        <span class="token string">"audio/mpeg"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".mpeg"</span><span class="token punctuation">,</span>       <span class="token string">"video/mpeg"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".mpkg"</span><span class="token punctuation">,</span>       <span class="token string">"application/vnd.apple.installer+xml"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".odp"</span><span class="token punctuation">,</span>        <span class="token string">"application/vnd.oasis.opendocument.presentation"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".ods"</span><span class="token punctuation">,</span>        <span class="token string">"application/vnd.oasis.opendocument.spreadsheet"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".odt"</span><span class="token punctuation">,</span>        <span class="token string">"application/vnd.oasis.opendocument.text"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".oga"</span><span class="token punctuation">,</span>        <span class="token string">"audio/ogg"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".ogv"</span><span class="token punctuation">,</span>        <span class="token string">"video/ogg"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".ogx"</span><span class="token punctuation">,</span>        <span class="token string">"application/ogg"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".otf"</span><span class="token punctuation">,</span>        <span class="token string">"font/otf"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".png"</span><span class="token punctuation">,</span>        <span class="token string">"image/png"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".pdf"</span><span class="token punctuation">,</span>        <span class="token string">"application/pdf"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".ppt"</span><span class="token punctuation">,</span>        <span class="token string">"application/vnd.ms-powerpoint"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".pptx"</span><span class="token punctuation">,</span>       <span class="token string">"application/vnd.openxmlformats-officedocument.presentationml.presentation"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".rar"</span><span class="token punctuation">,</span>        <span class="token string">"application/x-rar-compressed"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".rtf"</span><span class="token punctuation">,</span>        <span class="token string">"application/rtf"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".sh"</span><span class="token punctuation">,</span>         <span class="token string">"application/x-sh"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".svg"</span><span class="token punctuation">,</span>        <span class="token string">"image/svg+xml"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".swf"</span><span class="token punctuation">,</span>        <span class="token string">"application/x-shockwave-flash"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".tar"</span><span class="token punctuation">,</span>        <span class="token string">"application/x-tar"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".tif"</span><span class="token punctuation">,</span>        <span class="token string">"image/tiff"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".tiff"</span><span class="token punctuation">,</span>       <span class="token string">"image/tiff"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".ttf"</span><span class="token punctuation">,</span>        <span class="token string">"font/ttf"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".txt"</span><span class="token punctuation">,</span>        <span class="token string">"text/plain"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".vsd"</span><span class="token punctuation">,</span>        <span class="token string">"application/vnd.visio"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".wav"</span><span class="token punctuation">,</span>        <span class="token string">"audio/wav"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".weba"</span><span class="token punctuation">,</span>       <span class="token string">"audio/webm"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".webm"</span><span class="token punctuation">,</span>       <span class="token string">"video/webm"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".webp"</span><span class="token punctuation">,</span>       <span class="token string">"image/webp"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".woff"</span><span class="token punctuation">,</span>       <span class="token string">"font/woff"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".woff2"</span><span class="token punctuation">,</span>      <span class="token string">"font/woff2"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".xhtml"</span><span class="token punctuation">,</span>      <span class="token string">"application/xhtml+xml"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".xls"</span><span class="token punctuation">,</span>        <span class="token string">"application/vnd.ms-excel"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".xlsx"</span><span class="token punctuation">,</span>       <span class="token string">"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".xml"</span><span class="token punctuation">,</span>        <span class="token string">"application/xml"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".xul"</span><span class="token punctuation">,</span>        <span class="token string">"application/vnd.mozilla.xul+xml"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".zip"</span><span class="token punctuation">,</span>        <span class="token string">"application/zip"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".3gp"</span><span class="token punctuation">,</span>        <span class="token string">"video/3gpp"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".3g2"</span><span class="token punctuation">,</span>        <span class="token string">"video/3gpp2"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">{<!-- --></span><span class="token string">".7z"</span><span class="token punctuation">,</span>         <span class="token string">"application/x-7z-compressed"</span><span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    
    <span class="token keyword">class</span> <span class="token class-name">Util</span> <span class="token punctuation">{<!-- --></span>
        <span class="token keyword">public</span><span class="token operator">:</span>
            <span class="token comment">//字符串分割函数,将src字符串按照sep字符进行分割,得到的各个字串放到arry中,最终返回字串的数量</span>
            <span class="token keyword">static</span> size_t <span class="token function">Split</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>src<span class="token punctuation">,</span> <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>sep<span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span> <span class="token operator">*</span>arry<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                size_t offset <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
                <span class="token comment">// 有10个字符,offset是查找的起始位置,范围应该是0~9,offset==10就代表已经越界了</span>
                <span class="token keyword">while</span><span class="token punctuation">(</span>offset <span class="token operator"><</span> src<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    size_t pos <span class="token operator">=</span> src<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>sep<span class="token punctuation">,</span> offset<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//在src字符串偏移量offset处,开始向后查找sep字符/字串,返回查找到的位置</span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>pos <span class="token operator">==</span> std<span class="token double-colon punctuation">::</span>string<span class="token double-colon punctuation">::</span>npos<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span><span class="token comment">//没有找到特定的字符</span>
                        <span class="token comment">//将剩余的部分当作一个字串,放入arry中</span>
                        <span class="token keyword">if</span><span class="token punctuation">(</span>pos <span class="token operator">==</span> src<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">break</span><span class="token punctuation">;</span>
                        arry<span class="token operator">-></span><span class="token function">push_back</span><span class="token punctuation">(</span>src<span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span>offset<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                        <span class="token keyword">return</span> arry<span class="token operator">-></span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>pos <span class="token operator">==</span> offset<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                        offset <span class="token operator">=</span> pos <span class="token operator">+</span> sep<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                        <span class="token keyword">continue</span><span class="token punctuation">;</span><span class="token comment">//当前字串是一个空的,没有内容</span>
                    <span class="token punctuation">}</span>
                    arry<span class="token operator">-></span><span class="token function">push_back</span><span class="token punctuation">(</span>src<span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span>offset<span class="token punctuation">,</span> pos <span class="token operator">-</span> offset<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    offset <span class="token operator">=</span> pos <span class="token operator">+</span> sep<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> arry<span class="token operator">-></span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//读取文件的所有内容,将读取的内容放到一个Buffer中</span>
            <span class="token keyword">static</span> <span class="token keyword">bool</span> <span class="token function">ReadFile</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>filename<span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">*</span>buf<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                std<span class="token double-colon punctuation">::</span>ifstream <span class="token function">ifs</span><span class="token punctuation">(</span>filename<span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>ios<span class="token double-colon punctuation">::</span>binary<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>ifs<span class="token punctuation">.</span><span class="token function">is_open</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"OPEN %s FILE FAILED!!"</span><span class="token punctuation">,</span> filename<span class="token punctuation">.</span><span class="token function">c_str</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                size_t fsize <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
                ifs<span class="token punctuation">.</span><span class="token function">seekg</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> ifs<span class="token punctuation">.</span>end<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//跳转读写位置到末尾</span>
                fsize <span class="token operator">=</span> ifs<span class="token punctuation">.</span><span class="token function">tellg</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">//获取当前读写位置相对于起始位置的偏移量,从末尾偏移刚好就是文件大小</span>
                ifs<span class="token punctuation">.</span><span class="token function">seekg</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> ifs<span class="token punctuation">.</span>beg<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//跳转到起始位置</span>
                buf<span class="token operator">-></span><span class="token function">resize</span><span class="token punctuation">(</span>fsize<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//开辟文件大小的空间</span>
                ifs<span class="token punctuation">.</span><span class="token function">read</span><span class="token punctuation">(</span><span class="token operator">&</span><span class="token punctuation">(</span><span class="token operator">*</span>buf<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> fsize<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>ifs<span class="token punctuation">.</span><span class="token function">good</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"READ %s FILE FAILED!!"</span><span class="token punctuation">,</span> filename<span class="token punctuation">.</span><span class="token function">c_str</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    ifs<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                ifs<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//向文件写入数据</span>
            <span class="token keyword">static</span> <span class="token keyword">bool</span> <span class="token function">WriteFile</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>filename<span class="token punctuation">,</span> <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>buf<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                std<span class="token double-colon punctuation">::</span>ofstream <span class="token function">ofs</span><span class="token punctuation">(</span>filename<span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>ios<span class="token double-colon punctuation">::</span>binary <span class="token operator">|</span> std<span class="token double-colon punctuation">::</span>ios<span class="token double-colon punctuation">::</span>trunc<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>ofs<span class="token punctuation">.</span><span class="token function">is_open</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"OPEN %s FILE FAILED!!"</span><span class="token punctuation">,</span> filename<span class="token punctuation">.</span><span class="token function">c_str</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                ofs<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span>buf<span class="token punctuation">.</span><span class="token function">c_str</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> buf<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>ofs<span class="token punctuation">.</span><span class="token function">good</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token function">ERR_LOG</span><span class="token punctuation">(</span><span class="token string">"WRITE %s FILE FAILED!"</span><span class="token punctuation">,</span> filename<span class="token punctuation">.</span><span class="token function">c_str</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    ofs<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    
                    <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                ofs<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//URL编码,避免URL中资源路径与查询字符串中的特殊字符与HTTP请求中特殊字符产生歧义</span>
            <span class="token comment">//编码格式:将特殊字符的ascii值,转换为两个16进制字符,前缀%   C++ -> C%2B%2B</span>
            <span class="token comment">//  不编码的特殊字符: RFC3986文档规定 . - _ ~ 字母,数字属于绝对不编码字符</span>
            <span class="token comment">//RFC3986文档规定,编码格式 %HH </span>
            <span class="token comment">//W3C标准中规定,查询字符串中的空格,需要编码为+, 解码则是+转空格</span>
            <span class="token keyword">static</span> std<span class="token double-colon punctuation">::</span>string <span class="token function">UrlEncode</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string url<span class="token punctuation">,</span> <span class="token keyword">bool</span> convert_space_to_plus<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                std<span class="token double-colon punctuation">::</span>string res<span class="token punctuation">;</span>
                <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">auto</span> <span class="token operator">&</span>c <span class="token operator">:</span> url<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>c <span class="token operator">==</span> <span class="token char">'.'</span> <span class="token operator">||</span> c <span class="token operator">==</span> <span class="token char">'-'</span> <span class="token operator">||</span> c <span class="token operator">==</span> <span class="token char">'_'</span> <span class="token operator">||</span> c <span class="token operator">==</span> <span class="token char">'~'</span> <span class="token operator">||</span> <span class="token function">isalnum</span><span class="token punctuation">(</span>c<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                        res <span class="token operator">+=</span> c<span class="token punctuation">;</span>
                        <span class="token keyword">continue</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>c <span class="token operator">==</span> <span class="token char">' '</span> <span class="token operator">&&</span> convert_space_to_plus <span class="token operator">==</span> <span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                        res <span class="token operator">+=</span> <span class="token char">'+'</span><span class="token punctuation">;</span>
                        <span class="token keyword">continue</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                    <span class="token comment">//剩下的字符都是需要编码成为 %HH 格式</span>
                    <span class="token keyword">char</span> tmp<span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">{<!-- --></span><span class="token number">0</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
                    <span class="token comment">//snprintf 与 printf比较类似,都是格式化字符串,只不过一个是打印,一个是放到一块空间中</span>
                    <span class="token function">snprintf</span><span class="token punctuation">(</span>tmp<span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token string">"%%%02X"</span><span class="token punctuation">,</span> c<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    res <span class="token operator">+=</span> tmp<span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> res<span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">static</span> <span class="token keyword">char</span> <span class="token function">HEXTOI</span><span class="token punctuation">(</span><span class="token keyword">char</span> c<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>c <span class="token operator">>=</span> <span class="token char">'0'</span> <span class="token operator">&&</span> c <span class="token operator"><=</span> <span class="token char">'9'</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> c <span class="token operator">-</span> <span class="token char">'0'</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span><span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>c <span class="token operator">>=</span> <span class="token char">'a'</span> <span class="token operator">&&</span> c <span class="token operator"><=</span> <span class="token char">'z'</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> c <span class="token operator">-</span> <span class="token char">'a'</span> <span class="token operator">+</span> <span class="token number">10</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span><span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>c <span class="token operator">>=</span> <span class="token char">'A'</span> <span class="token operator">&&</span> c <span class="token operator"><=</span> <span class="token char">'Z'</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> c <span class="token operator">-</span> <span class="token char">'A'</span> <span class="token operator">+</span> <span class="token number">10</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span> 
            <span class="token punctuation">}</span>
            <span class="token keyword">static</span> std<span class="token double-colon punctuation">::</span>string <span class="token function">UrlDecode</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string url<span class="token punctuation">,</span> <span class="token keyword">bool</span> convert_plus_to_space<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//遇到了%,则将紧随其后的2个字符,转换为数字,第一个数字左移4位,然后加上第二个数字  + -> 2b  %2b->2 << 4 + 11</span>
                std<span class="token double-colon punctuation">::</span>string res<span class="token punctuation">;</span>
                <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> url<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>url<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token char">'+'</span> <span class="token operator">&&</span> convert_plus_to_space <span class="token operator">==</span> <span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                        res <span class="token operator">+=</span> <span class="token char">' '</span><span class="token punctuation">;</span>
                        <span class="token keyword">continue</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>url<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token char">'%'</span> <span class="token operator">&&</span> <span class="token punctuation">(</span>i <span class="token operator">+</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token operator"><</span> url<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                        <span class="token keyword">char</span> v1 <span class="token operator">=</span> <span class="token function">HEXTOI</span><span class="token punctuation">(</span>url<span class="token punctuation">[</span>i <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                        <span class="token keyword">char</span> v2 <span class="token operator">=</span> <span class="token function">HEXTOI</span><span class="token punctuation">(</span>url<span class="token punctuation">[</span>i <span class="token operator">+</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                        <span class="token keyword">char</span> v <span class="token operator">=</span> v1 <span class="token operator">*</span> <span class="token number">16</span> <span class="token operator">+</span> v2<span class="token punctuation">;</span>
                        res <span class="token operator">+=</span> v<span class="token punctuation">;</span>
                        i <span class="token operator">+=</span> <span class="token number">2</span><span class="token punctuation">;</span>
                        <span class="token keyword">continue</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                    res <span class="token operator">+=</span> url<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> res<span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//响应状态码的描述信息获取</span>
            <span class="token keyword">static</span> std<span class="token double-colon punctuation">::</span>string <span class="token function">StatuDesc</span><span class="token punctuation">(</span><span class="token keyword">int</span> statu<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                
                <span class="token keyword">auto</span> it <span class="token operator">=</span> _statu_msg<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>statu<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>it <span class="token operator">!=</span> _statu_msg<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> it<span class="token operator">-></span>second<span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> <span class="token string">"Unknow"</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//根据文件后缀名获取文件mime</span>
            <span class="token keyword">static</span> std<span class="token double-colon punctuation">::</span>string <span class="token function">ExtMime</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>filename<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                
                <span class="token comment">// a.b.txt  先获取文件扩展名</span>
                size_t pos <span class="token operator">=</span> filename<span class="token punctuation">.</span><span class="token function">find_last_of</span><span class="token punctuation">(</span><span class="token char">'.'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>pos <span class="token operator">==</span> std<span class="token double-colon punctuation">::</span>string<span class="token double-colon punctuation">::</span>npos<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> <span class="token string">"application/octet-stream"</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token comment">//根据扩展名,获取mime</span>
                std<span class="token double-colon punctuation">::</span>string ext <span class="token operator">=</span> filename<span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span>pos<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">auto</span> it <span class="token operator">=</span> _mime_msg<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>ext<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>it <span class="token operator">==</span> _mime_msg<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> <span class="token string">"application/octet-stream"</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> it<span class="token operator">-></span>second<span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//判断一个文件是否是一个目录</span>
            <span class="token keyword">static</span> <span class="token keyword">bool</span> <span class="token function">IsDirectory</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>filename<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">struct</span> <span class="token class-name">stat</span> st<span class="token punctuation">;</span>
                <span class="token keyword">int</span> ret <span class="token operator">=</span> <span class="token function">stat</span><span class="token punctuation">(</span>filename<span class="token punctuation">.</span><span class="token function">c_str</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token operator">&</span>st<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> <span class="token function">S_ISDIR</span><span class="token punctuation">(</span>st<span class="token punctuation">.</span>st_mode<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//判断一个文件是否是一个普通文件</span>
            <span class="token keyword">static</span> <span class="token keyword">bool</span> <span class="token function">IsRegular</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>filename<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">struct</span> <span class="token class-name">stat</span> st<span class="token punctuation">;</span>
                <span class="token keyword">int</span> ret <span class="token operator">=</span> <span class="token function">stat</span><span class="token punctuation">(</span>filename<span class="token punctuation">.</span><span class="token function">c_str</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token operator">&</span>st<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> <span class="token function">S_ISREG</span><span class="token punctuation">(</span>st<span class="token punctuation">.</span>st_mode<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//http请求的资源路径有效性判断</span>
            <span class="token comment">// /index.html  --- 前边的/叫做相对根目录  映射的是某个服务器上的子目录</span>
            <span class="token comment">// 想表达的意思就是,客户端只能请求相对根目录中的资源,其他地方的资源都不予理会</span>
            <span class="token comment">// /../login, 这个路径中的..会让路径的查找跑到相对根目录之外,这是不合理的,不安全的</span>
            <span class="token keyword">static</span> <span class="token keyword">bool</span> <span class="token function">ValidPath</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>path<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//思想:按照/进行路径分割,根据有多少子目录,计算目录深度,有多少层,深度不能小于0</span>
                std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span> subdir<span class="token punctuation">;</span>
                <span class="token function">Split</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span> <span class="token string">"/"</span><span class="token punctuation">,</span> <span class="token operator">&</span>subdir<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">int</span> level <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
                <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">auto</span> <span class="token operator">&</span>dir <span class="token operator">:</span> subdir<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>dir <span class="token operator">==</span> <span class="token string">".."</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                        level<span class="token operator">--</span><span class="token punctuation">;</span> <span class="token comment">//任意一层走出相对根目录,就认为有问题</span>
                        <span class="token keyword">if</span> <span class="token punctuation">(</span>level <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                        <span class="token keyword">continue</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                    level<span class="token operator">++</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    
    <span class="token keyword">class</span> <span class="token class-name">HttpRequest</span> <span class="token punctuation">{<!-- --></span>
        <span class="token keyword">public</span><span class="token operator">:</span>
            std<span class="token double-colon punctuation">::</span>string _method<span class="token punctuation">;</span>      <span class="token comment">//请求方法</span>
            std<span class="token double-colon punctuation">::</span>string _path<span class="token punctuation">;</span>        <span class="token comment">//资源路径</span>
            std<span class="token double-colon punctuation">::</span>string _version<span class="token punctuation">;</span>     <span class="token comment">//协议版本</span>
            std<span class="token double-colon punctuation">::</span>string _body<span class="token punctuation">;</span>        <span class="token comment">//请求正文</span>
            std<span class="token double-colon punctuation">::</span>smatch _matches<span class="token punctuation">;</span>     <span class="token comment">//资源路径的正则提取数据</span>
            std<span class="token double-colon punctuation">::</span>unordered_map<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span> _headers<span class="token punctuation">;</span>  <span class="token comment">//头部字段</span>
            std<span class="token double-colon punctuation">::</span>unordered_map<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span> _params<span class="token punctuation">;</span>   <span class="token comment">//查询字符串</span>
        <span class="token keyword">public</span><span class="token operator">:</span>
            <span class="token function">HttpRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token function">_version</span><span class="token punctuation">(</span><span class="token string">"HTTP/1.1"</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">ReSet</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _method<span class="token punctuation">.</span><span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                _path<span class="token punctuation">.</span><span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                _version <span class="token operator">=</span> <span class="token string">"HTTP/1.1"</span><span class="token punctuation">;</span>
                _body<span class="token punctuation">.</span><span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                std<span class="token double-colon punctuation">::</span>smatch match<span class="token punctuation">;</span>
                _matches<span class="token punctuation">.</span><span class="token function">swap</span><span class="token punctuation">(</span>match<span class="token punctuation">)</span><span class="token punctuation">;</span>
                _headers<span class="token punctuation">.</span><span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                _params<span class="token punctuation">.</span><span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//插入头部字段</span>
            <span class="token keyword">void</span> <span class="token function">SetHeader</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>key<span class="token punctuation">,</span> <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>val<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _headers<span class="token punctuation">.</span><span class="token function">insert</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">make_pair</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> val<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//判断是否存在指定头部字段</span>
            <span class="token keyword">bool</span> <span class="token function">HasHeader</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>key<span class="token punctuation">)</span> <span class="token keyword">const</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">auto</span> it <span class="token operator">=</span> _headers<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>it <span class="token operator">==</span> _headers<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//获取指定头部字段的值</span>
            std<span class="token double-colon punctuation">::</span>string <span class="token function">GetHeader</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>key<span class="token punctuation">)</span> <span class="token keyword">const</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">auto</span> it <span class="token operator">=</span> _headers<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>it <span class="token operator">==</span> _headers<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> <span class="token string">""</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> it<span class="token operator">-></span>second<span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//插入查询字符串</span>
            <span class="token keyword">void</span> <span class="token function">SetParam</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>key<span class="token punctuation">,</span> <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>val<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _params<span class="token punctuation">.</span><span class="token function">insert</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">make_pair</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> val<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//判断是否有某个指定的查询字符串</span>
            <span class="token keyword">bool</span> <span class="token function">HasParam</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>key<span class="token punctuation">)</span> <span class="token keyword">const</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">auto</span> it <span class="token operator">=</span> _params<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>it <span class="token operator">==</span> _params<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//获取指定的查询字符串</span>
            std<span class="token double-colon punctuation">::</span>string <span class="token function">GetParam</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>key<span class="token punctuation">)</span> <span class="token keyword">const</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">auto</span> it <span class="token operator">=</span> _params<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>it <span class="token operator">==</span> _params<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> <span class="token string">""</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> it<span class="token operator">-></span>second<span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//获取正文长度</span>
            size_t <span class="token function">ContentLength</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">// Content-Length: 1234\r\n</span>
                <span class="token keyword">bool</span> ret <span class="token operator">=</span> <span class="token function">HasHeader</span><span class="token punctuation">(</span><span class="token string">"Content-Length"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator">==</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                std<span class="token double-colon punctuation">::</span>string clen <span class="token operator">=</span> <span class="token function">GetHeader</span><span class="token punctuation">(</span><span class="token string">"Content-Length"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">return</span> std<span class="token double-colon punctuation">::</span><span class="token function">stol</span><span class="token punctuation">(</span>clen<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//判断是否是短链接</span>
            <span class="token keyword">bool</span> <span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">// 没有Connection字段,或者有Connection但是值是close,则都是短链接,否则就是长连接</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">HasHeader</span><span class="token punctuation">(</span><span class="token string">"Connection"</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">true</span> <span class="token operator">&&</span> <span class="token function">GetHeader</span><span class="token punctuation">(</span><span class="token string">"Connection"</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token string">"keep-alive"</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    
    <span class="token keyword">class</span> <span class="token class-name">HttpResponse</span> <span class="token punctuation">{<!-- --></span>
        <span class="token keyword">public</span><span class="token operator">:</span>
            <span class="token keyword">int</span> _statu<span class="token punctuation">;</span>
            <span class="token keyword">bool</span> _redirect_flag<span class="token punctuation">;</span>
            std<span class="token double-colon punctuation">::</span>string _body<span class="token punctuation">;</span>
            std<span class="token double-colon punctuation">::</span>string _redirect_url<span class="token punctuation">;</span>
            std<span class="token double-colon punctuation">::</span>unordered_map<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span> _headers<span class="token punctuation">;</span>
        <span class="token keyword">public</span><span class="token operator">:</span>
            <span class="token function">HttpResponse</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token function">_redirect_flag</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">_statu</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span>
            <span class="token function">HttpResponse</span><span class="token punctuation">(</span><span class="token keyword">int</span> statu<span class="token punctuation">)</span><span class="token operator">:</span><span class="token function">_redirect_flag</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">_statu</span><span class="token punctuation">(</span>statu<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span> 
            <span class="token keyword">void</span> <span class="token function">ReSet</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _statu <span class="token operator">=</span> <span class="token number">200</span><span class="token punctuation">;</span>
                _redirect_flag <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                _body<span class="token punctuation">.</span><span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                _redirect_url<span class="token punctuation">.</span><span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                _headers<span class="token punctuation">.</span><span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//插入头部字段</span>
            <span class="token keyword">void</span> <span class="token function">SetHeader</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>key<span class="token punctuation">,</span> <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>val<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _headers<span class="token punctuation">.</span><span class="token function">insert</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">make_pair</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> val<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//判断是否存在指定头部字段</span>
            <span class="token keyword">bool</span> <span class="token function">HasHeader</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>key<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">auto</span> it <span class="token operator">=</span> _headers<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>it <span class="token operator">==</span> _headers<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//获取指定头部字段的值</span>
            std<span class="token double-colon punctuation">::</span>string <span class="token function">GetHeader</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>key<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">auto</span> it <span class="token operator">=</span> _headers<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>it <span class="token operator">==</span> _headers<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> <span class="token string">""</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> it<span class="token operator">-></span>second<span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">SetContent</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>body<span class="token punctuation">,</span>  <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>type <span class="token operator">=</span> <span class="token string">"text/html"</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _body <span class="token operator">=</span> body<span class="token punctuation">;</span>
                <span class="token function">SetHeader</span><span class="token punctuation">(</span><span class="token string">"Content-Type"</span><span class="token punctuation">,</span> type<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">SetRedirect</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>url<span class="token punctuation">,</span> <span class="token keyword">int</span> statu <span class="token operator">=</span> <span class="token number">302</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _statu <span class="token operator">=</span> statu<span class="token punctuation">;</span>
                _redirect_flag <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
                _redirect_url <span class="token operator">=</span> url<span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//判断是否是短链接</span>
            <span class="token keyword">bool</span> <span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">// 没有Connection字段,或者有Connection但是值是close,则都是短链接,否则就是长连接</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">HasHeader</span><span class="token punctuation">(</span><span class="token string">"Connection"</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">true</span> <span class="token operator">&&</span> <span class="token function">GetHeader</span><span class="token punctuation">(</span><span class="token string">"Connection"</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token string">"keep-alive"</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    
    <span class="token keyword">typedef</span> <span class="token keyword">enum</span> <span class="token punctuation">{<!-- --></span>
        RECV_HTTP_ERROR<span class="token punctuation">,</span>
        RECV_HTTP_LINE<span class="token punctuation">,</span>
        RECV_HTTP_HEAD<span class="token punctuation">,</span>
        RECV_HTTP_BODY<span class="token punctuation">,</span>
        RECV_HTTP_OVER
    <span class="token punctuation">}</span>HttpRecvStatu<span class="token punctuation">;</span>
    
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">MAX_LINE</span> <span class="token expression"><span class="token number">8192</span></span></span>
    <span class="token keyword">class</span> <span class="token class-name">HttpContext</span> <span class="token punctuation">{<!-- --></span>
        <span class="token keyword">private</span><span class="token operator">:</span>
            <span class="token keyword">int</span> _resp_statu<span class="token punctuation">;</span> <span class="token comment">//响应状态码</span>
            HttpRecvStatu _recv_statu<span class="token punctuation">;</span> <span class="token comment">//当前接收及解析的阶段状态</span>
            HttpRequest _request<span class="token punctuation">;</span>  <span class="token comment">//已经解析得到的请求信息</span>
        <span class="token keyword">private</span><span class="token operator">:</span>
            <span class="token keyword">bool</span> <span class="token function">ParseHttpLine</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>line<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                std<span class="token double-colon punctuation">::</span>smatch matches<span class="token punctuation">;</span>
                std<span class="token double-colon punctuation">::</span>regex <span class="token function">e</span><span class="token punctuation">(</span><span class="token string">"(GET|HEAD|POST|PUT|DELETE) ([^?]*)(?:\\?(.*))? (HTTP/1\\.[01])(?:\n|\r\n)?"</span><span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>regex<span class="token double-colon punctuation">::</span>icase<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">bool</span> ret <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span><span class="token function">regex_match</span><span class="token punctuation">(</span>line<span class="token punctuation">,</span> matches<span class="token punctuation">,</span> e<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator">==</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    _recv_statu <span class="token operator">=</span> RECV_HTTP_ERROR<span class="token punctuation">;</span>
                    _resp_statu <span class="token operator">=</span> <span class="token number">400</span><span class="token punctuation">;</span><span class="token comment">//BAD REQUEST</span>
                    <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token comment">//0 : GET /bitejiuyeke/login?user=xiaoming&pass=123123 HTTP/1.1</span>
                <span class="token comment">//1 : GET</span>
                <span class="token comment">//2 : /bitejiuyeke/login</span>
                <span class="token comment">//3 : user=xiaoming&pass=123123</span>
                <span class="token comment">//4 : HTTP/1.1</span>
                <span class="token comment">//请求方法的获取</span>
                _request<span class="token punctuation">.</span>_method <span class="token operator">=</span> matches<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
                std<span class="token double-colon punctuation">::</span><span class="token function">transform</span><span class="token punctuation">(</span>_request<span class="token punctuation">.</span>_method<span class="token punctuation">.</span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> _request<span class="token punctuation">.</span>_method<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> _request<span class="token punctuation">.</span>_method<span class="token punctuation">.</span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token double-colon punctuation">::</span>toupper<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token comment">//资源路径的获取,需要进行URL解码操作,但是不需要+转空格</span>
                _request<span class="token punctuation">.</span>_path <span class="token operator">=</span> <span class="token class-name">Util</span><span class="token double-colon punctuation">::</span><span class="token function">UrlDecode</span><span class="token punctuation">(</span>matches<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token comment">//协议版本的获取</span>
                _request<span class="token punctuation">.</span>_version <span class="token operator">=</span> matches<span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
                <span class="token comment">//查询字符串的获取与处理</span>
                std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span> query_string_arry<span class="token punctuation">;</span>
                std<span class="token double-colon punctuation">::</span>string query_string <span class="token operator">=</span> matches<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
                <span class="token comment">//查询字符串的格式 key=val&key=val....., 先以 & 符号进行分割,得到各个字串</span>
                <span class="token class-name">Util</span><span class="token double-colon punctuation">::</span><span class="token function">Split</span><span class="token punctuation">(</span>query_string<span class="token punctuation">,</span> <span class="token string">"&"</span><span class="token punctuation">,</span> <span class="token operator">&</span>query_string_arry<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token comment">//针对各个字串,以 = 符号进行分割,得到key 和val, 得到之后也需要进行URL解码</span>
                <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">auto</span> <span class="token operator">&</span>str <span class="token operator">:</span> query_string_arry<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    size_t pos <span class="token operator">=</span> str<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token string">"="</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>pos <span class="token operator">==</span> std<span class="token double-colon punctuation">::</span>string<span class="token double-colon punctuation">::</span>npos<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                        _recv_statu <span class="token operator">=</span> RECV_HTTP_ERROR<span class="token punctuation">;</span>
                        _resp_statu <span class="token operator">=</span> <span class="token number">400</span><span class="token punctuation">;</span><span class="token comment">//BAD REQUEST</span>
                        <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                    std<span class="token double-colon punctuation">::</span>string key <span class="token operator">=</span> <span class="token class-name">Util</span><span class="token double-colon punctuation">::</span><span class="token function">UrlDecode</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> pos<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  
                    std<span class="token double-colon punctuation">::</span>string val <span class="token operator">=</span> <span class="token class-name">Util</span><span class="token double-colon punctuation">::</span><span class="token function">UrlDecode</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span>pos <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    _request<span class="token punctuation">.</span><span class="token function">SetParam</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> val<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">bool</span> <span class="token function">RecvHttpLine</span><span class="token punctuation">(</span>Buffer <span class="token operator">*</span>buf<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_recv_statu <span class="token operator">!=</span> RECV_HTTP_LINE<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token comment">//1. 获取一行数据,带有末尾的换行 </span>
                std<span class="token double-colon punctuation">::</span>string line <span class="token operator">=</span> buf<span class="token operator">-></span><span class="token function">GetLineAndPop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token comment">//2. 需要考虑的一些要素:缓冲区中的数据不足一行, 获取的一行数据超大</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>line<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token comment">//缓冲区中的数据不足一行,则需要判断缓冲区的可读数据长度,如果很长了都不足一行,这是有问题的</span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>buf<span class="token operator">-></span><span class="token function">ReadAbleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">></span> MAX_LINE<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                        _recv_statu <span class="token operator">=</span> RECV_HTTP_ERROR<span class="token punctuation">;</span>
                        _resp_statu <span class="token operator">=</span> <span class="token number">414</span><span class="token punctuation">;</span><span class="token comment">//URI TOO LONG</span>
                        <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                    <span class="token comment">//缓冲区中数据不足一行,但是也不多,就等等新数据的到来</span>
                    <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>line<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">></span> MAX_LINE<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    _recv_statu <span class="token operator">=</span> RECV_HTTP_ERROR<span class="token punctuation">;</span>
                    _resp_statu <span class="token operator">=</span> <span class="token number">414</span><span class="token punctuation">;</span><span class="token comment">//URI TOO LONG</span>
                    <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">bool</span> ret <span class="token operator">=</span> <span class="token function">ParseHttpLine</span><span class="token punctuation">(</span>line<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator">==</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token comment">//首行处理完毕,进入头部获取阶段</span>
                _recv_statu <span class="token operator">=</span> RECV_HTTP_HEAD<span class="token punctuation">;</span>
                <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">bool</span> <span class="token function">RecvHttpHead</span><span class="token punctuation">(</span>Buffer <span class="token operator">*</span>buf<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_recv_statu <span class="token operator">!=</span> RECV_HTTP_HEAD<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token comment">//一行一行取出数据,直到遇到空行为止, 头部的格式 key: val\r\nkey: val\r\n....</span>
                <span class="token keyword">while</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
                    std<span class="token double-colon punctuation">::</span>string line <span class="token operator">=</span> buf<span class="token operator">-></span><span class="token function">GetLineAndPop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token comment">//2. 需要考虑的一些要素:缓冲区中的数据不足一行, 获取的一行数据超大</span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>line<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                        <span class="token comment">//缓冲区中的数据不足一行,则需要判断缓冲区的可读数据长度,如果很长了都不足一行,这是有问题的</span>
                        <span class="token keyword">if</span> <span class="token punctuation">(</span>buf<span class="token operator">-></span><span class="token function">ReadAbleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">></span> MAX_LINE<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                            _recv_statu <span class="token operator">=</span> RECV_HTTP_ERROR<span class="token punctuation">;</span>
                            _resp_statu <span class="token operator">=</span> <span class="token number">414</span><span class="token punctuation">;</span><span class="token comment">//URI TOO LONG</span>
                            <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                        <span class="token punctuation">}</span>
                        <span class="token comment">//缓冲区中数据不足一行,但是也不多,就等等新数据的到来</span>
                        <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>line<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">></span> MAX_LINE<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                        _recv_statu <span class="token operator">=</span> RECV_HTTP_ERROR<span class="token punctuation">;</span>
                        _resp_statu <span class="token operator">=</span> <span class="token number">414</span><span class="token punctuation">;</span><span class="token comment">//URI TOO LONG</span>
                        <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>line <span class="token operator">==</span> <span class="token string">"\n"</span> <span class="token operator">||</span> line <span class="token operator">==</span> <span class="token string">"\r\n"</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                        <span class="token keyword">break</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                    <span class="token keyword">bool</span> ret <span class="token operator">=</span> <span class="token function">ParseHttpHead</span><span class="token punctuation">(</span>line<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator">==</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                        <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                <span class="token punctuation">}</span>
                <span class="token comment">//头部处理完毕,进入正文获取阶段</span>
                _recv_statu <span class="token operator">=</span> RECV_HTTP_BODY<span class="token punctuation">;</span>
                <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">bool</span> <span class="token function">ParseHttpHead</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>line<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//key: val\r\nkey: val\r\n....</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>line<span class="token punctuation">.</span><span class="token function">back</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token char">'\n'</span><span class="token punctuation">)</span> line<span class="token punctuation">.</span><span class="token function">pop_back</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//末尾是换行则去掉换行字符</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>line<span class="token punctuation">.</span><span class="token function">back</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token char">'\r'</span><span class="token punctuation">)</span> line<span class="token punctuation">.</span><span class="token function">pop_back</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//末尾是回车则去掉回车字符</span>
                size_t pos <span class="token operator">=</span> line<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token string">": "</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>pos <span class="token operator">==</span> std<span class="token double-colon punctuation">::</span>string<span class="token double-colon punctuation">::</span>npos<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    _recv_statu <span class="token operator">=</span> RECV_HTTP_ERROR<span class="token punctuation">;</span>
                    _resp_statu <span class="token operator">=</span> <span class="token number">400</span><span class="token punctuation">;</span><span class="token comment">//</span>
                    <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                std<span class="token double-colon punctuation">::</span>string key <span class="token operator">=</span> line<span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> pos<span class="token punctuation">)</span><span class="token punctuation">;</span>  
                std<span class="token double-colon punctuation">::</span>string val <span class="token operator">=</span> line<span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span>pos <span class="token operator">+</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                _request<span class="token punctuation">.</span><span class="token function">SetHeader</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> val<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">bool</span> <span class="token function">RecvHttpBody</span><span class="token punctuation">(</span>Buffer <span class="token operator">*</span>buf<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_recv_statu <span class="token operator">!=</span> RECV_HTTP_BODY<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token comment">//1. 获取正文长度</span>
                size_t content_length <span class="token operator">=</span> _request<span class="token punctuation">.</span><span class="token function">ContentLength</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>content_length <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token comment">//没有正文,则请求接收解析完毕</span>
                    _recv_statu <span class="token operator">=</span> RECV_HTTP_OVER<span class="token punctuation">;</span>
                    <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token comment">//2. 当前已经接收了多少正文,其实就是往  _request._body 中放了多少数据了</span>
                size_t real_len <span class="token operator">=</span> content_length <span class="token operator">-</span> _request<span class="token punctuation">.</span>_body<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//实际还需要接收的正文长度</span>
                <span class="token comment">//3. 接收正文放到body中,但是也要考虑当前缓冲区中的数据,是否是全部的正文</span>
                <span class="token comment">//  3.1 缓冲区中数据,包含了当前请求的所有正文,则取出所需的数据</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>buf<span class="token operator">-></span><span class="token function">ReadAbleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">>=</span> real_len<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    _request<span class="token punctuation">.</span>_body<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span>buf<span class="token operator">-></span><span class="token function">ReadPosition</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> real_len<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    buf<span class="token operator">-></span><span class="token function">MoveReadOffset</span><span class="token punctuation">(</span>real_len<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    _recv_statu <span class="token operator">=</span> RECV_HTTP_OVER<span class="token punctuation">;</span>
                    <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token comment">//  3.2 缓冲区中数据,无法满足当前正文的需要,数据不足,取出数据,然后等待新数据到来</span>
                _request<span class="token punctuation">.</span>_body<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span>buf<span class="token operator">-></span><span class="token function">ReadPosition</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> buf<span class="token operator">-></span><span class="token function">ReadAbleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                buf<span class="token operator">-></span><span class="token function">MoveReadOffset</span><span class="token punctuation">(</span>buf<span class="token operator">-></span><span class="token function">ReadAbleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token keyword">public</span><span class="token operator">:</span>
            <span class="token function">HttpContext</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token function">_resp_statu</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">_recv_statu</span><span class="token punctuation">(</span>RECV_HTTP_LINE<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">ReSet</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _resp_statu <span class="token operator">=</span> <span class="token number">200</span><span class="token punctuation">;</span>
                _recv_statu <span class="token operator">=</span> RECV_HTTP_LINE<span class="token punctuation">;</span>
                _request<span class="token punctuation">.</span><span class="token function">ReSet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">int</span> <span class="token function">RespStatu</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> _resp_statu<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            HttpRecvStatu <span class="token function">RecvStatu</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> _recv_statu<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            HttpRequest <span class="token operator">&</span><span class="token function">Request</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> _request<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token comment">//接收并解析HTTP请求</span>
            <span class="token keyword">void</span> <span class="token function">RecvHttpRequest</span><span class="token punctuation">(</span>Buffer <span class="token operator">*</span>buf<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//不同的状态,做不同的事情,但是这里不要break, 因为处理完请求行后,应该立即处理头部,而不是退出等新数据</span>
                <span class="token keyword">switch</span><span class="token punctuation">(</span>_recv_statu<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">case</span> RECV_HTTP_LINE<span class="token operator">:</span> <span class="token function">RecvHttpLine</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token keyword">case</span> RECV_HTTP_HEAD<span class="token operator">:</span> <span class="token function">RecvHttpHead</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token keyword">case</span> RECV_HTTP_BODY<span class="token operator">:</span> <span class="token function">RecvHttpBody</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    
    
    <span class="token keyword">class</span> <span class="token class-name">HttpServer</span> <span class="token punctuation">{<!-- --></span>
        <span class="token keyword">private</span><span class="token operator">:</span>
            <span class="token keyword">using</span> Handler <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span>function<span class="token operator"><</span><span class="token keyword">void</span><span class="token punctuation">(</span><span class="token keyword">const</span> HttpRequest <span class="token operator">&</span><span class="token punctuation">,</span> HttpResponse <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">></span><span class="token punctuation">;</span>
            <span class="token keyword">using</span> Handlers <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>pair<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>regex<span class="token punctuation">,</span> Handler<span class="token operator">>></span><span class="token punctuation">;</span>
            Handlers _get_route<span class="token punctuation">;</span>
            Handlers _post_route<span class="token punctuation">;</span>
            Handlers _put_route<span class="token punctuation">;</span>
            Handlers _delete_route<span class="token punctuation">;</span>
            std<span class="token double-colon punctuation">::</span>string _basedir<span class="token punctuation">;</span> <span class="token comment">//静态资源根目录</span>
            TcpServer _server<span class="token punctuation">;</span>
        <span class="token keyword">private</span><span class="token operator">:</span>
            <span class="token keyword">void</span> <span class="token function">ErrorHandler</span><span class="token punctuation">(</span><span class="token keyword">const</span> HttpRequest <span class="token operator">&</span>req<span class="token punctuation">,</span> HttpResponse <span class="token operator">*</span>rsp<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//1. 组织一个错误展示页面</span>
                std<span class="token double-colon punctuation">::</span>string body<span class="token punctuation">;</span>
                body <span class="token operator">+=</span> <span class="token string">"<html>"</span><span class="token punctuation">;</span>
                body <span class="token operator">+=</span> <span class="token string">"<head>"</span><span class="token punctuation">;</span>
                body <span class="token operator">+=</span> <span class="token string">"<meta http-equiv='Content-Type' content='text/html;charset=utf-8'>"</span><span class="token punctuation">;</span>
                body <span class="token operator">+=</span> <span class="token string">"</head>"</span><span class="token punctuation">;</span>
                body <span class="token operator">+=</span> <span class="token string">"<body>"</span><span class="token punctuation">;</span>
                body <span class="token operator">+=</span> <span class="token string">"<h1>"</span><span class="token punctuation">;</span>
                body <span class="token operator">+=</span> std<span class="token double-colon punctuation">::</span><span class="token function">to_string</span><span class="token punctuation">(</span>rsp<span class="token operator">-></span>_statu<span class="token punctuation">)</span><span class="token punctuation">;</span>
                body <span class="token operator">+=</span> <span class="token string">" "</span><span class="token punctuation">;</span>
                body <span class="token operator">+=</span> <span class="token class-name">Util</span><span class="token double-colon punctuation">::</span><span class="token function">StatuDesc</span><span class="token punctuation">(</span>rsp<span class="token operator">-></span>_statu<span class="token punctuation">)</span><span class="token punctuation">;</span>
                body <span class="token operator">+=</span> <span class="token string">"</h1>"</span><span class="token punctuation">;</span>
                body <span class="token operator">+=</span> <span class="token string">"</body>"</span><span class="token punctuation">;</span>
                body <span class="token operator">+=</span> <span class="token string">"</html>"</span><span class="token punctuation">;</span>
                <span class="token comment">//2. 将页面数据,当作响应正文,放入rsp中</span>
                rsp<span class="token operator">-></span><span class="token function">SetContent</span><span class="token punctuation">(</span>body<span class="token punctuation">,</span> <span class="token string">"text/html"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//将HttpResponse中的要素按照http协议格式进行组织,发送</span>
            <span class="token keyword">void</span> <span class="token function">WriteReponse</span><span class="token punctuation">(</span><span class="token keyword">const</span> PtrConnection <span class="token operator">&</span>conn<span class="token punctuation">,</span> <span class="token keyword">const</span> HttpRequest <span class="token operator">&</span>req<span class="token punctuation">,</span> HttpResponse <span class="token operator">&</span>rsp<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//1. 先完善头部字段</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>req<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    rsp<span class="token punctuation">.</span><span class="token function">SetHeader</span><span class="token punctuation">(</span><span class="token string">"Connection"</span><span class="token punctuation">,</span> <span class="token string">"close"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span><span class="token keyword">else</span> <span class="token punctuation">{<!-- --></span>
                    rsp<span class="token punctuation">.</span><span class="token function">SetHeader</span><span class="token punctuation">(</span><span class="token string">"Connection"</span><span class="token punctuation">,</span> <span class="token string">"keep-alive"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>rsp<span class="token punctuation">.</span>_body<span class="token punctuation">.</span><span class="token function">empty</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">false</span> <span class="token operator">&&</span> rsp<span class="token punctuation">.</span><span class="token function">HasHeader</span><span class="token punctuation">(</span><span class="token string">"Content-Length"</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    rsp<span class="token punctuation">.</span><span class="token function">SetHeader</span><span class="token punctuation">(</span><span class="token string">"Content-Length"</span><span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span><span class="token function">to_string</span><span class="token punctuation">(</span>rsp<span class="token punctuation">.</span>_body<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>rsp<span class="token punctuation">.</span>_body<span class="token punctuation">.</span><span class="token function">empty</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">false</span> <span class="token operator">&&</span> rsp<span class="token punctuation">.</span><span class="token function">HasHeader</span><span class="token punctuation">(</span><span class="token string">"Content-Type"</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    rsp<span class="token punctuation">.</span><span class="token function">SetHeader</span><span class="token punctuation">(</span><span class="token string">"Content-Type"</span><span class="token punctuation">,</span> <span class="token string">"application/octet-stream"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>rsp<span class="token punctuation">.</span>_redirect_flag <span class="token operator">==</span> <span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    rsp<span class="token punctuation">.</span><span class="token function">SetHeader</span><span class="token punctuation">(</span><span class="token string">"Location"</span><span class="token punctuation">,</span> rsp<span class="token punctuation">.</span>_redirect_url<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token comment">//2. 将rsp中的要素,按照http协议格式进行组织</span>
                std<span class="token double-colon punctuation">::</span>stringstream rsp_str<span class="token punctuation">;</span>
                rsp_str <span class="token operator"><<</span> req<span class="token punctuation">.</span>_version <span class="token operator"><<</span> <span class="token string">" "</span> <span class="token operator"><<</span> std<span class="token double-colon punctuation">::</span><span class="token function">to_string</span><span class="token punctuation">(</span>rsp<span class="token punctuation">.</span>_statu<span class="token punctuation">)</span> <span class="token operator"><<</span> <span class="token string">" "</span> <span class="token operator"><<</span> <span class="token class-name">Util</span><span class="token double-colon punctuation">::</span><span class="token function">StatuDesc</span><span class="token punctuation">(</span>rsp<span class="token punctuation">.</span>_statu<span class="token punctuation">)</span> <span class="token operator"><<</span> <span class="token string">"\r\n"</span><span class="token punctuation">;</span>
                <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">auto</span> <span class="token operator">&</span>head <span class="token operator">:</span> rsp<span class="token punctuation">.</span>_headers<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    rsp_str <span class="token operator"><<</span> head<span class="token punctuation">.</span>first <span class="token operator"><<</span> <span class="token string">": "</span> <span class="token operator"><<</span> head<span class="token punctuation">.</span>second <span class="token operator"><<</span> <span class="token string">"\r\n"</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                rsp_str <span class="token operator"><<</span> <span class="token string">"\r\n"</span><span class="token punctuation">;</span>
                rsp_str <span class="token operator"><<</span> rsp<span class="token punctuation">.</span>_body<span class="token punctuation">;</span>
                <span class="token comment">//3. 发送数据</span>
                conn<span class="token operator">-></span><span class="token function">Send</span><span class="token punctuation">(</span>rsp_str<span class="token punctuation">.</span><span class="token function">str</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">c_str</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> rsp_str<span class="token punctuation">.</span><span class="token function">str</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">bool</span> <span class="token function">IsFileHandler</span><span class="token punctuation">(</span><span class="token keyword">const</span> HttpRequest <span class="token operator">&</span>req<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">// 1. 必须设置了静态资源根目录</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_basedir<span class="token punctuation">.</span><span class="token function">empty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token comment">// 2. 请求方法,必须是GET / HEAD请求方法</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>req<span class="token punctuation">.</span>_method <span class="token operator">!=</span> <span class="token string">"GET"</span> <span class="token operator">&&</span> req<span class="token punctuation">.</span>_method <span class="token operator">!=</span> <span class="token string">"HEAD"</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token comment">// 3. 请求的资源路径必须是一个合法路径</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token class-name">Util</span><span class="token double-colon punctuation">::</span><span class="token function">ValidPath</span><span class="token punctuation">(</span>req<span class="token punctuation">.</span>_path<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token comment">// 4. 请求的资源必须存在,且是一个普通文件</span>
                <span class="token comment">//    有一种请求比较特殊 -- 目录:/, /image/, 这种情况给后边默认追加一个 index.html</span>
                <span class="token comment">// index.html    /image/a.png</span>
                <span class="token comment">// 不要忘了前缀的相对根目录,也就是将请求路径转换为实际存在的路径  /image/a.png  ->   ./wwwroot/image/a.png</span>
                std<span class="token double-colon punctuation">::</span>string req_path <span class="token operator">=</span> _basedir <span class="token operator">+</span> req<span class="token punctuation">.</span>_path<span class="token punctuation">;</span><span class="token comment">//为了避免直接修改请求的资源路径,因此定义一个临时对象</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>req<span class="token punctuation">.</span>_path<span class="token punctuation">.</span><span class="token function">back</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token char">'/'</span><span class="token punctuation">)</span>  <span class="token punctuation">{<!-- --></span>
                    req_path <span class="token operator">+=</span> <span class="token string">"index.html"</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token class-name">Util</span><span class="token double-colon punctuation">::</span><span class="token function">IsRegular</span><span class="token punctuation">(</span>req_path<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//静态资源的请求处理 --- 将静态资源文件的数据读取出来,放到rsp的_body中, 并设置mime</span>
            <span class="token keyword">void</span> <span class="token function">FileHandler</span><span class="token punctuation">(</span><span class="token keyword">const</span> HttpRequest <span class="token operator">&</span>req<span class="token punctuation">,</span> HttpResponse <span class="token operator">*</span>rsp<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                std<span class="token double-colon punctuation">::</span>string req_path <span class="token operator">=</span> _basedir <span class="token operator">+</span> req<span class="token punctuation">.</span>_path<span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>req<span class="token punctuation">.</span>_path<span class="token punctuation">.</span><span class="token function">back</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token char">'/'</span><span class="token punctuation">)</span>  <span class="token punctuation">{<!-- --></span>
                    req_path <span class="token operator">+=</span> <span class="token string">"index.html"</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">bool</span> ret <span class="token operator">=</span> <span class="token class-name">Util</span><span class="token double-colon punctuation">::</span><span class="token function">ReadFile</span><span class="token punctuation">(</span>req_path<span class="token punctuation">,</span> <span class="token operator">&</span>rsp<span class="token operator">-></span>_body<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator">==</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                std<span class="token double-colon punctuation">::</span>string mime <span class="token operator">=</span> <span class="token class-name">Util</span><span class="token double-colon punctuation">::</span><span class="token function">ExtMime</span><span class="token punctuation">(</span>req_path<span class="token punctuation">)</span><span class="token punctuation">;</span>
                rsp<span class="token operator">-></span><span class="token function">SetHeader</span><span class="token punctuation">(</span><span class="token string">"Content-Type"</span><span class="token punctuation">,</span> mime<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">return</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//功能性请求的分类处理</span>
            <span class="token keyword">void</span> <span class="token function">Dispatcher</span><span class="token punctuation">(</span>HttpRequest <span class="token operator">&</span>req<span class="token punctuation">,</span> HttpResponse <span class="token operator">*</span>rsp<span class="token punctuation">,</span> Handlers <span class="token operator">&</span>handlers<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//在对应请求方法的路由表中,查找是否含有对应资源请求的处理函数,有则调用,没有则发挥404</span>
                <span class="token comment">//思想:路由表存储的时键值对 -- 正则表达式 & 处理函数</span>
                <span class="token comment">//使用正则表达式,对请求的资源路径进行正则匹配,匹配成功就使用对应函数进行处理</span>
                <span class="token comment">//  /numbers/(\d+)       /numbers/12345</span>
                <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">auto</span> <span class="token operator">&</span>handler <span class="token operator">:</span> handlers<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>regex <span class="token operator">&</span>re <span class="token operator">=</span> handler<span class="token punctuation">.</span>first<span class="token punctuation">;</span>
                    <span class="token keyword">const</span> Handler <span class="token operator">&</span>functor <span class="token operator">=</span> handler<span class="token punctuation">.</span>second<span class="token punctuation">;</span>
                    <span class="token keyword">bool</span> ret <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span><span class="token function">regex_match</span><span class="token punctuation">(</span>req<span class="token punctuation">.</span>_path<span class="token punctuation">,</span> req<span class="token punctuation">.</span>_matches<span class="token punctuation">,</span> re<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator">==</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                        <span class="token keyword">continue</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                    <span class="token keyword">return</span> <span class="token function">functor</span><span class="token punctuation">(</span>req<span class="token punctuation">,</span> rsp<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//传入请求信息,和空的rsp,执行处理函数</span>
                <span class="token punctuation">}</span>
                rsp<span class="token operator">-></span>_statu <span class="token operator">=</span> <span class="token number">404</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">Route</span><span class="token punctuation">(</span>HttpRequest <span class="token operator">&</span>req<span class="token punctuation">,</span> HttpResponse <span class="token operator">*</span>rsp<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//1. 对请求进行分辨,是一个静态资源请求,还是一个功能性请求</span>
                <span class="token comment">//   静态资源请求,则进行静态资源的处理</span>
                <span class="token comment">//   功能性请求,则需要通过几个请求路由表来确定是否有处理函数</span>
                <span class="token comment">//   既不是静态资源请求,也没有设置对应的功能性请求处理函数,就返回405</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">IsFileHandler</span><span class="token punctuation">(</span>req<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token comment">//是一个静态资源请求, 则进行静态资源请求的处理</span>
                    <span class="token keyword">return</span> <span class="token function">FileHandler</span><span class="token punctuation">(</span>req<span class="token punctuation">,</span> rsp<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>req<span class="token punctuation">.</span>_method <span class="token operator">==</span> <span class="token string">"GET"</span> <span class="token operator">||</span> req<span class="token punctuation">.</span>_method <span class="token operator">==</span> <span class="token string">"HEAD"</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> <span class="token function">Dispatcher</span><span class="token punctuation">(</span>req<span class="token punctuation">,</span> rsp<span class="token punctuation">,</span> _get_route<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span><span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>req<span class="token punctuation">.</span>_method <span class="token operator">==</span> <span class="token string">"POST"</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> <span class="token function">Dispatcher</span><span class="token punctuation">(</span>req<span class="token punctuation">,</span> rsp<span class="token punctuation">,</span> _post_route<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span><span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>req<span class="token punctuation">.</span>_method <span class="token operator">==</span> <span class="token string">"PUT"</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> <span class="token function">Dispatcher</span><span class="token punctuation">(</span>req<span class="token punctuation">,</span> rsp<span class="token punctuation">,</span> _put_route<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span><span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>req<span class="token punctuation">.</span>_method <span class="token operator">==</span> <span class="token string">"DELETE"</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> <span class="token function">Dispatcher</span><span class="token punctuation">(</span>req<span class="token punctuation">,</span> rsp<span class="token punctuation">,</span> _delete_route<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                rsp<span class="token operator">-></span>_statu <span class="token operator">=</span> <span class="token number">405</span><span class="token punctuation">;</span><span class="token comment">// Method Not Allowed</span>
                <span class="token keyword">return</span> <span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//设置上下文</span>
            <span class="token keyword">void</span> <span class="token function">OnConnected</span><span class="token punctuation">(</span><span class="token keyword">const</span> PtrConnection <span class="token operator">&</span>conn<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                conn<span class="token operator">-></span><span class="token function">SetContext</span><span class="token punctuation">(</span><span class="token function">HttpContext</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token function">DBG_LOG</span><span class="token punctuation">(</span><span class="token string">"NEW CONNECTION %p"</span><span class="token punctuation">,</span> conn<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//缓冲区数据解析+处理</span>
            <span class="token keyword">void</span> <span class="token function">OnMessage</span><span class="token punctuation">(</span><span class="token keyword">const</span> PtrConnection <span class="token operator">&</span>conn<span class="token punctuation">,</span> Buffer <span class="token operator">*</span>buffer<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">while</span><span class="token punctuation">(</span>buffer<span class="token operator">-></span><span class="token function">ReadAbleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
                    <span class="token comment">//1. 获取上下文</span>
                    HttpContext <span class="token operator">*</span>context <span class="token operator">=</span> conn<span class="token operator">-></span><span class="token function">GetContext</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token generic-function"><span class="token function">get</span><span class="token generic class-name"><span class="token operator"><</span>HttpContext<span class="token operator">></span></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token comment">//2. 通过上下文对缓冲区数据进行解析,得到HttpRequest对象</span>
                    <span class="token comment">//  1. 如果缓冲区的数据解析出错,就直接回复出错响应</span>
                    <span class="token comment">//  2. 如果解析正常,且请求已经获取完毕,才开始去进行处理</span>
                    context<span class="token operator">-></span><span class="token function">RecvHttpRequest</span><span class="token punctuation">(</span>buffer<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    HttpRequest <span class="token operator">&</span>req <span class="token operator">=</span> context<span class="token operator">-></span><span class="token function">Request</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    HttpResponse <span class="token function">rsp</span><span class="token punctuation">(</span>context<span class="token operator">-></span><span class="token function">RespStatu</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>context<span class="token operator">-></span><span class="token function">RespStatu</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">>=</span> <span class="token number">400</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                        <span class="token comment">//进行错误响应,关闭连接</span>
                        <span class="token function">ErrorHandler</span><span class="token punctuation">(</span>req<span class="token punctuation">,</span> <span class="token operator">&</span>rsp<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//填充一个错误显示页面数据到rsp中</span>
                        <span class="token function">WriteReponse</span><span class="token punctuation">(</span>conn<span class="token punctuation">,</span> req<span class="token punctuation">,</span> rsp<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//组织响应发送给客户端</span>
                        context<span class="token operator">-></span><span class="token function">ReSet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                        buffer<span class="token operator">-></span><span class="token function">MoveReadOffset</span><span class="token punctuation">(</span>buffer<span class="token operator">-></span><span class="token function">ReadAbleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//出错了就把缓冲区数据清空</span>
                        conn<span class="token operator">-></span><span class="token function">Shutdown</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//关闭连接</span>
                        <span class="token keyword">return</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>context<span class="token operator">-></span><span class="token function">RecvStatu</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">!=</span> RECV_HTTP_OVER<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                        <span class="token comment">//当前请求还没有接收完整,则退出,等新数据到来再重新继续处理</span>
                        <span class="token keyword">return</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                    <span class="token comment">//3. 请求路由 + 业务处理</span>
                    <span class="token function">Route</span><span class="token punctuation">(</span>req<span class="token punctuation">,</span> <span class="token operator">&</span>rsp<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token comment">//4. 对HttpResponse进行组织发送</span>
                    <span class="token function">WriteReponse</span><span class="token punctuation">(</span>conn<span class="token punctuation">,</span> req<span class="token punctuation">,</span> rsp<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token comment">//5. 重置上下文</span>
                    context<span class="token operator">-></span><span class="token function">ReSet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token comment">//6. 根据长短连接判断是否关闭连接或者继续处理</span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>rsp<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">true</span><span class="token punctuation">)</span> conn<span class="token operator">-></span><span class="token function">Shutdown</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//短链接则直接关闭</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token keyword">public</span><span class="token operator">:</span>
            <span class="token function">HttpServer</span><span class="token punctuation">(</span><span class="token keyword">int</span> port<span class="token punctuation">,</span> <span class="token keyword">int</span> timeout <span class="token operator">=</span> DEFALT_TIMEOUT<span class="token punctuation">)</span><span class="token operator">:</span><span class="token function">_server</span><span class="token punctuation">(</span>port<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _server<span class="token punctuation">.</span><span class="token function">EnableInactiveRelease</span><span class="token punctuation">(</span>timeout<span class="token punctuation">)</span><span class="token punctuation">;</span>
                _server<span class="token punctuation">.</span><span class="token function">SetConnectedCallback</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token operator">&</span>HttpServer<span class="token double-colon punctuation">::</span>OnConnected<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>placeholders<span class="token double-colon punctuation">::</span>_1<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                _server<span class="token punctuation">.</span><span class="token function">SetMessageCallback</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token operator">&</span>HttpServer<span class="token double-colon punctuation">::</span>OnMessage<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>placeholders<span class="token double-colon punctuation">::</span>_1<span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>placeholders<span class="token double-colon punctuation">::</span>_2<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">SetBaseDir</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>path<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token function">assert</span><span class="token punctuation">(</span><span class="token class-name">Util</span><span class="token double-colon punctuation">::</span><span class="token function">IsDirectory</span><span class="token punctuation">(</span>path<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                _basedir <span class="token operator">=</span> path<span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">/*设置/添加,请求(请求的正则表达)与处理函数的映射关系*/</span>
            <span class="token keyword">void</span> <span class="token function">Get</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>pattern<span class="token punctuation">,</span> <span class="token keyword">const</span> Handler <span class="token operator">&</span>handler<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _get_route<span class="token punctuation">.</span><span class="token function">push_back</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">make_pair</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">regex</span><span class="token punctuation">(</span>pattern<span class="token punctuation">)</span><span class="token punctuation">,</span> handler<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">Post</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>pattern<span class="token punctuation">,</span> <span class="token keyword">const</span> Handler <span class="token operator">&</span>handler<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _post_route<span class="token punctuation">.</span><span class="token function">push_back</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">make_pair</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">regex</span><span class="token punctuation">(</span>pattern<span class="token punctuation">)</span><span class="token punctuation">,</span> handler<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">Put</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>pattern<span class="token punctuation">,</span> <span class="token keyword">const</span> Handler <span class="token operator">&</span>handler<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _put_route<span class="token punctuation">.</span><span class="token function">push_back</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">make_pair</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">regex</span><span class="token punctuation">(</span>pattern<span class="token punctuation">)</span><span class="token punctuation">,</span> handler<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">Delete</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>pattern<span class="token punctuation">,</span> <span class="token keyword">const</span> Handler <span class="token operator">&</span>handler<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _delete_route<span class="token punctuation">.</span><span class="token function">push_back</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">make_pair</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">regex</span><span class="token punctuation">(</span>pattern<span class="token punctuation">)</span><span class="token punctuation">,</span> handler<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">SetThreadCount</span><span class="token punctuation">(</span><span class="token keyword">int</span> count<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _server<span class="token punctuation">.</span><span class="token function">SetThreadCount</span><span class="token punctuation">(</span>count<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">Listen</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _server<span class="token punctuation">.</span><span class="token function">Start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li><li style="color: rgb(153, 153, 153);">39</li><li style="color: rgb(153, 153, 153);">40</li><li style="color: rgb(153, 153, 153);">41</li><li style="color: rgb(153, 153, 153);">42</li><li style="color: rgb(153, 153, 153);">43</li><li style="color: rgb(153, 153, 153);">44</li><li style="color: rgb(153, 153, 153);">45</li><li style="color: rgb(153, 153, 153);">46</li><li style="color: rgb(153, 153, 153);">47</li><li style="color: rgb(153, 153, 153);">48</li><li style="color: rgb(153, 153, 153);">49</li><li style="color: rgb(153, 153, 153);">50</li><li style="color: rgb(153, 153, 153);">51</li><li style="color: rgb(153, 153, 153);">52</li><li style="color: rgb(153, 153, 153);">53</li><li style="color: rgb(153, 153, 153);">54</li><li style="color: rgb(153, 153, 153);">55</li><li style="color: rgb(153, 153, 153);">56</li><li style="color: rgb(153, 153, 153);">57</li><li style="color: rgb(153, 153, 153);">58</li><li style="color: rgb(153, 153, 153);">59</li><li style="color: rgb(153, 153, 153);">60</li><li style="color: rgb(153, 153, 153);">61</li><li style="color: rgb(153, 153, 153);">62</li><li style="color: rgb(153, 153, 153);">63</li><li style="color: rgb(153, 153, 153);">64</li><li style="color: rgb(153, 153, 153);">65</li><li style="color: rgb(153, 153, 153);">66</li><li style="color: rgb(153, 153, 153);">67</li><li style="color: rgb(153, 153, 153);">68</li><li style="color: rgb(153, 153, 153);">69</li><li style="color: rgb(153, 153, 153);">70</li><li style="color: rgb(153, 153, 153);">71</li><li style="color: rgb(153, 153, 153);">72</li><li style="color: rgb(153, 153, 153);">73</li><li style="color: rgb(153, 153, 153);">74</li><li style="color: rgb(153, 153, 153);">75</li><li style="color: rgb(153, 153, 153);">76</li><li style="color: rgb(153, 153, 153);">77</li><li style="color: rgb(153, 153, 153);">78</li><li style="color: rgb(153, 153, 153);">79</li><li style="color: rgb(153, 153, 153);">80</li><li style="color: rgb(153, 153, 153);">81</li><li style="color: rgb(153, 153, 153);">82</li><li style="color: rgb(153, 153, 153);">83</li><li style="color: rgb(153, 153, 153);">84</li><li style="color: rgb(153, 153, 153);">85</li><li style="color: rgb(153, 153, 153);">86</li><li style="color: rgb(153, 153, 153);">87</li><li style="color: rgb(153, 153, 153);">88</li><li style="color: rgb(153, 153, 153);">89</li><li style="color: rgb(153, 153, 153);">90</li><li style="color: rgb(153, 153, 153);">91</li><li style="color: rgb(153, 153, 153);">92</li><li style="color: rgb(153, 153, 153);">93</li><li style="color: rgb(153, 153, 153);">94</li><li style="color: rgb(153, 153, 153);">95</li><li style="color: rgb(153, 153, 153);">96</li><li style="color: rgb(153, 153, 153);">97</li><li style="color: rgb(153, 153, 153);">98</li><li style="color: rgb(153, 153, 153);">99</li><li style="color: rgb(153, 153, 153);">100</li><li style="color: rgb(153, 153, 153);">101</li><li style="color: rgb(153, 153, 153);">102</li><li style="color: rgb(153, 153, 153);">103</li><li style="color: rgb(153, 153, 153);">104</li><li style="color: rgb(153, 153, 153);">105</li><li style="color: rgb(153, 153, 153);">106</li><li style="color: rgb(153, 153, 153);">107</li><li style="color: rgb(153, 153, 153);">108</li><li style="color: rgb(153, 153, 153);">109</li><li style="color: rgb(153, 153, 153);">110</li><li style="color: rgb(153, 153, 153);">111</li><li style="color: rgb(153, 153, 153);">112</li><li style="color: rgb(153, 153, 153);">113</li><li style="color: rgb(153, 153, 153);">114</li><li style="color: rgb(153, 153, 153);">115</li><li style="color: rgb(153, 153, 153);">116</li><li style="color: rgb(153, 153, 153);">117</li><li style="color: rgb(153, 153, 153);">118</li><li style="color: rgb(153, 153, 153);">119</li><li style="color: rgb(153, 153, 153);">120</li><li style="color: rgb(153, 153, 153);">121</li><li style="color: rgb(153, 153, 153);">122</li><li style="color: rgb(153, 153, 153);">123</li><li style="color: rgb(153, 153, 153);">124</li><li style="color: rgb(153, 153, 153);">125</li><li style="color: rgb(153, 153, 153);">126</li><li style="color: rgb(153, 153, 153);">127</li><li style="color: rgb(153, 153, 153);">128</li><li style="color: rgb(153, 153, 153);">129</li><li style="color: rgb(153, 153, 153);">130</li><li style="color: rgb(153, 153, 153);">131</li><li style="color: rgb(153, 153, 153);">132</li><li style="color: rgb(153, 153, 153);">133</li><li style="color: rgb(153, 153, 153);">134</li><li style="color: rgb(153, 153, 153);">135</li><li style="color: rgb(153, 153, 153);">136</li><li style="color: rgb(153, 153, 153);">137</li><li style="color: rgb(153, 153, 153);">138</li><li style="color: rgb(153, 153, 153);">139</li><li style="color: rgb(153, 153, 153);">140</li><li style="color: rgb(153, 153, 153);">141</li><li style="color: rgb(153, 153, 153);">142</li><li style="color: rgb(153, 153, 153);">143</li><li style="color: rgb(153, 153, 153);">144</li><li style="color: rgb(153, 153, 153);">145</li><li style="color: rgb(153, 153, 153);">146</li><li style="color: rgb(153, 153, 153);">147</li><li style="color: rgb(153, 153, 153);">148</li><li style="color: rgb(153, 153, 153);">149</li><li style="color: rgb(153, 153, 153);">150</li><li style="color: rgb(153, 153, 153);">151</li><li style="color: rgb(153, 153, 153);">152</li><li style="color: rgb(153, 153, 153);">153</li><li style="color: rgb(153, 153, 153);">154</li><li style="color: rgb(153, 153, 153);">155</li><li style="color: rgb(153, 153, 153);">156</li><li style="color: rgb(153, 153, 153);">157</li><li style="color: rgb(153, 153, 153);">158</li><li style="color: rgb(153, 153, 153);">159</li><li style="color: rgb(153, 153, 153);">160</li><li style="color: rgb(153, 153, 153);">161</li><li style="color: rgb(153, 153, 153);">162</li><li style="color: rgb(153, 153, 153);">163</li><li style="color: rgb(153, 153, 153);">164</li><li style="color: rgb(153, 153, 153);">165</li><li style="color: rgb(153, 153, 153);">166</li><li style="color: rgb(153, 153, 153);">167</li><li style="color: rgb(153, 153, 153);">168</li><li style="color: rgb(153, 153, 153);">169</li><li style="color: rgb(153, 153, 153);">170</li><li style="color: rgb(153, 153, 153);">171</li><li style="color: rgb(153, 153, 153);">172</li><li style="color: rgb(153, 153, 153);">173</li><li style="color: rgb(153, 153, 153);">174</li><li style="color: rgb(153, 153, 153);">175</li><li style="color: rgb(153, 153, 153);">176</li><li style="color: rgb(153, 153, 153);">177</li><li style="color: rgb(153, 153, 153);">178</li><li style="color: rgb(153, 153, 153);">179</li><li style="color: rgb(153, 153, 153);">180</li><li style="color: rgb(153, 153, 153);">181</li><li style="color: rgb(153, 153, 153);">182</li><li style="color: rgb(153, 153, 153);">183</li><li style="color: rgb(153, 153, 153);">184</li><li style="color: rgb(153, 153, 153);">185</li><li style="color: rgb(153, 153, 153);">186</li><li style="color: rgb(153, 153, 153);">187</li><li style="color: rgb(153, 153, 153);">188</li><li style="color: rgb(153, 153, 153);">189</li><li style="color: rgb(153, 153, 153);">190</li><li style="color: rgb(153, 153, 153);">191</li><li style="color: rgb(153, 153, 153);">192</li><li style="color: rgb(153, 153, 153);">193</li><li style="color: rgb(153, 153, 153);">194</li><li style="color: rgb(153, 153, 153);">195</li><li style="color: rgb(153, 153, 153);">196</li><li style="color: rgb(153, 153, 153);">197</li><li style="color: rgb(153, 153, 153);">198</li><li style="color: rgb(153, 153, 153);">199</li><li style="color: rgb(153, 153, 153);">200</li><li style="color: rgb(153, 153, 153);">201</li><li style="color: rgb(153, 153, 153);">202</li><li style="color: rgb(153, 153, 153);">203</li><li style="color: rgb(153, 153, 153);">204</li><li style="color: rgb(153, 153, 153);">205</li><li style="color: rgb(153, 153, 153);">206</li><li style="color: rgb(153, 153, 153);">207</li><li style="color: rgb(153, 153, 153);">208</li><li style="color: rgb(153, 153, 153);">209</li><li style="color: rgb(153, 153, 153);">210</li><li style="color: rgb(153, 153, 153);">211</li><li style="color: rgb(153, 153, 153);">212</li><li style="color: rgb(153, 153, 153);">213</li><li style="color: rgb(153, 153, 153);">214</li><li style="color: rgb(153, 153, 153);">215</li><li style="color: rgb(153, 153, 153);">216</li><li style="color: rgb(153, 153, 153);">217</li><li style="color: rgb(153, 153, 153);">218</li><li style="color: rgb(153, 153, 153);">219</li><li style="color: rgb(153, 153, 153);">220</li><li style="color: rgb(153, 153, 153);">221</li><li style="color: rgb(153, 153, 153);">222</li><li style="color: rgb(153, 153, 153);">223</li><li style="color: rgb(153, 153, 153);">224</li><li style="color: rgb(153, 153, 153);">225</li><li style="color: rgb(153, 153, 153);">226</li><li style="color: rgb(153, 153, 153);">227</li><li style="color: rgb(153, 153, 153);">228</li><li style="color: rgb(153, 153, 153);">229</li><li style="color: rgb(153, 153, 153);">230</li><li style="color: rgb(153, 153, 153);">231</li><li style="color: rgb(153, 153, 153);">232</li><li style="color: rgb(153, 153, 153);">233</li><li style="color: rgb(153, 153, 153);">234</li><li style="color: rgb(153, 153, 153);">235</li><li style="color: rgb(153, 153, 153);">236</li><li style="color: rgb(153, 153, 153);">237</li><li style="color: rgb(153, 153, 153);">238</li><li style="color: rgb(153, 153, 153);">239</li><li style="color: rgb(153, 153, 153);">240</li><li style="color: rgb(153, 153, 153);">241</li><li style="color: rgb(153, 153, 153);">242</li><li style="color: rgb(153, 153, 153);">243</li><li style="color: rgb(153, 153, 153);">244</li><li style="color: rgb(153, 153, 153);">245</li><li style="color: rgb(153, 153, 153);">246</li><li style="color: rgb(153, 153, 153);">247</li><li style="color: rgb(153, 153, 153);">248</li><li style="color: rgb(153, 153, 153);">249</li><li style="color: rgb(153, 153, 153);">250</li><li style="color: rgb(153, 153, 153);">251</li><li style="color: rgb(153, 153, 153);">252</li><li style="color: rgb(153, 153, 153);">253</li><li style="color: rgb(153, 153, 153);">254</li><li style="color: rgb(153, 153, 153);">255</li><li style="color: rgb(153, 153, 153);">256</li><li style="color: rgb(153, 153, 153);">257</li><li style="color: rgb(153, 153, 153);">258</li><li style="color: rgb(153, 153, 153);">259</li><li style="color: rgb(153, 153, 153);">260</li><li style="color: rgb(153, 153, 153);">261</li><li style="color: rgb(153, 153, 153);">262</li><li style="color: rgb(153, 153, 153);">263</li><li style="color: rgb(153, 153, 153);">264</li><li style="color: rgb(153, 153, 153);">265</li><li style="color: rgb(153, 153, 153);">266</li><li style="color: rgb(153, 153, 153);">267</li><li style="color: rgb(153, 153, 153);">268</li><li style="color: rgb(153, 153, 153);">269</li><li style="color: rgb(153, 153, 153);">270</li><li style="color: rgb(153, 153, 153);">271</li><li style="color: rgb(153, 153, 153);">272</li><li style="color: rgb(153, 153, 153);">273</li><li style="color: rgb(153, 153, 153);">274</li><li style="color: rgb(153, 153, 153);">275</li><li style="color: rgb(153, 153, 153);">276</li><li style="color: rgb(153, 153, 153);">277</li><li style="color: rgb(153, 153, 153);">278</li><li style="color: rgb(153, 153, 153);">279</li><li style="color: rgb(153, 153, 153);">280</li><li style="color: rgb(153, 153, 153);">281</li><li style="color: rgb(153, 153, 153);">282</li><li style="color: rgb(153, 153, 153);">283</li><li style="color: rgb(153, 153, 153);">284</li><li style="color: rgb(153, 153, 153);">285</li><li style="color: rgb(153, 153, 153);">286</li><li style="color: rgb(153, 153, 153);">287</li><li style="color: rgb(153, 153, 153);">288</li><li style="color: rgb(153, 153, 153);">289</li><li style="color: rgb(153, 153, 153);">290</li><li style="color: rgb(153, 153, 153);">291</li><li style="color: rgb(153, 153, 153);">292</li><li style="color: rgb(153, 153, 153);">293</li><li style="color: rgb(153, 153, 153);">294</li><li style="color: rgb(153, 153, 153);">295</li><li style="color: rgb(153, 153, 153);">296</li><li style="color: rgb(153, 153, 153);">297</li><li style="color: rgb(153, 153, 153);">298</li><li style="color: rgb(153, 153, 153);">299</li><li style="color: rgb(153, 153, 153);">300</li><li style="color: rgb(153, 153, 153);">301</li><li style="color: rgb(153, 153, 153);">302</li><li style="color: rgb(153, 153, 153);">303</li><li style="color: rgb(153, 153, 153);">304</li><li style="color: rgb(153, 153, 153);">305</li><li style="color: rgb(153, 153, 153);">306</li><li style="color: rgb(153, 153, 153);">307</li><li style="color: rgb(153, 153, 153);">308</li><li style="color: rgb(153, 153, 153);">309</li><li style="color: rgb(153, 153, 153);">310</li><li style="color: rgb(153, 153, 153);">311</li><li style="color: rgb(153, 153, 153);">312</li><li style="color: rgb(153, 153, 153);">313</li><li style="color: rgb(153, 153, 153);">314</li><li style="color: rgb(153, 153, 153);">315</li><li style="color: rgb(153, 153, 153);">316</li><li style="color: rgb(153, 153, 153);">317</li><li style="color: rgb(153, 153, 153);">318</li><li style="color: rgb(153, 153, 153);">319</li><li style="color: rgb(153, 153, 153);">320</li><li style="color: rgb(153, 153, 153);">321</li><li style="color: rgb(153, 153, 153);">322</li><li style="color: rgb(153, 153, 153);">323</li><li style="color: rgb(153, 153, 153);">324</li><li style="color: rgb(153, 153, 153);">325</li><li style="color: rgb(153, 153, 153);">326</li><li style="color: rgb(153, 153, 153);">327</li><li style="color: rgb(153, 153, 153);">328</li><li style="color: rgb(153, 153, 153);">329</li><li style="color: rgb(153, 153, 153);">330</li><li style="color: rgb(153, 153, 153);">331</li><li style="color: rgb(153, 153, 153);">332</li><li style="color: rgb(153, 153, 153);">333</li><li style="color: rgb(153, 153, 153);">334</li><li style="color: rgb(153, 153, 153);">335</li><li style="color: rgb(153, 153, 153);">336</li><li style="color: rgb(153, 153, 153);">337</li><li style="color: rgb(153, 153, 153);">338</li><li style="color: rgb(153, 153, 153);">339</li><li style="color: rgb(153, 153, 153);">340</li><li style="color: rgb(153, 153, 153);">341</li><li style="color: rgb(153, 153, 153);">342</li><li style="color: rgb(153, 153, 153);">343</li><li style="color: rgb(153, 153, 153);">344</li><li style="color: rgb(153, 153, 153);">345</li><li style="color: rgb(153, 153, 153);">346</li><li style="color: rgb(153, 153, 153);">347</li><li style="color: rgb(153, 153, 153);">348</li><li style="color: rgb(153, 153, 153);">349</li><li style="color: rgb(153, 153, 153);">350</li><li style="color: rgb(153, 153, 153);">351</li><li style="color: rgb(153, 153, 153);">352</li><li style="color: rgb(153, 153, 153);">353</li><li style="color: rgb(153, 153, 153);">354</li><li style="color: rgb(153, 153, 153);">355</li><li style="color: rgb(153, 153, 153);">356</li><li style="color: rgb(153, 153, 153);">357</li><li style="color: rgb(153, 153, 153);">358</li><li style="color: rgb(153, 153, 153);">359</li><li style="color: rgb(153, 153, 153);">360</li><li style="color: rgb(153, 153, 153);">361</li><li style="color: rgb(153, 153, 153);">362</li><li style="color: rgb(153, 153, 153);">363</li><li style="color: rgb(153, 153, 153);">364</li><li style="color: rgb(153, 153, 153);">365</li><li style="color: rgb(153, 153, 153);">366</li><li style="color: rgb(153, 153, 153);">367</li><li style="color: rgb(153, 153, 153);">368</li><li style="color: rgb(153, 153, 153);">369</li><li style="color: rgb(153, 153, 153);">370</li><li style="color: rgb(153, 153, 153);">371</li><li style="color: rgb(153, 153, 153);">372</li><li style="color: rgb(153, 153, 153);">373</li><li style="color: rgb(153, 153, 153);">374</li><li style="color: rgb(153, 153, 153);">375</li><li style="color: rgb(153, 153, 153);">376</li><li style="color: rgb(153, 153, 153);">377</li><li style="color: rgb(153, 153, 153);">378</li><li style="color: rgb(153, 153, 153);">379</li><li style="color: rgb(153, 153, 153);">380</li><li style="color: rgb(153, 153, 153);">381</li><li style="color: rgb(153, 153, 153);">382</li><li style="color: rgb(153, 153, 153);">383</li><li style="color: rgb(153, 153, 153);">384</li><li style="color: rgb(153, 153, 153);">385</li><li style="color: rgb(153, 153, 153);">386</li><li style="color: rgb(153, 153, 153);">387</li><li style="color: rgb(153, 153, 153);">388</li><li style="color: rgb(153, 153, 153);">389</li><li style="color: rgb(153, 153, 153);">390</li><li style="color: rgb(153, 153, 153);">391</li><li style="color: rgb(153, 153, 153);">392</li><li style="color: rgb(153, 153, 153);">393</li><li style="color: rgb(153, 153, 153);">394</li><li style="color: rgb(153, 153, 153);">395</li><li style="color: rgb(153, 153, 153);">396</li><li style="color: rgb(153, 153, 153);">397</li><li style="color: rgb(153, 153, 153);">398</li><li style="color: rgb(153, 153, 153);">399</li><li style="color: rgb(153, 153, 153);">400</li><li style="color: rgb(153, 153, 153);">401</li><li style="color: rgb(153, 153, 153);">402</li><li style="color: rgb(153, 153, 153);">403</li><li style="color: rgb(153, 153, 153);">404</li><li style="color: rgb(153, 153, 153);">405</li><li style="color: rgb(153, 153, 153);">406</li><li style="color: rgb(153, 153, 153);">407</li><li style="color: rgb(153, 153, 153);">408</li><li style="color: rgb(153, 153, 153);">409</li><li style="color: rgb(153, 153, 153);">410</li><li style="color: rgb(153, 153, 153);">411</li><li style="color: rgb(153, 153, 153);">412</li><li style="color: rgb(153, 153, 153);">413</li><li style="color: rgb(153, 153, 153);">414</li><li style="color: rgb(153, 153, 153);">415</li><li style="color: rgb(153, 153, 153);">416</li><li style="color: rgb(153, 153, 153);">417</li><li style="color: rgb(153, 153, 153);">418</li><li style="color: rgb(153, 153, 153);">419</li><li style="color: rgb(153, 153, 153);">420</li><li style="color: rgb(153, 153, 153);">421</li><li style="color: rgb(153, 153, 153);">422</li><li style="color: rgb(153, 153, 153);">423</li><li style="color: rgb(153, 153, 153);">424</li><li style="color: rgb(153, 153, 153);">425</li><li style="color: rgb(153, 153, 153);">426</li><li style="color: rgb(153, 153, 153);">427</li><li style="color: rgb(153, 153, 153);">428</li><li style="color: rgb(153, 153, 153);">429</li><li style="color: rgb(153, 153, 153);">430</li><li style="color: rgb(153, 153, 153);">431</li><li style="color: rgb(153, 153, 153);">432</li><li style="color: rgb(153, 153, 153);">433</li><li style="color: rgb(153, 153, 153);">434</li><li style="color: rgb(153, 153, 153);">435</li><li style="color: rgb(153, 153, 153);">436</li><li style="color: rgb(153, 153, 153);">437</li><li style="color: rgb(153, 153, 153);">438</li><li style="color: rgb(153, 153, 153);">439</li><li style="color: rgb(153, 153, 153);">440</li><li style="color: rgb(153, 153, 153);">441</li><li style="color: rgb(153, 153, 153);">442</li><li style="color: rgb(153, 153, 153);">443</li><li style="color: rgb(153, 153, 153);">444</li><li style="color: rgb(153, 153, 153);">445</li><li style="color: rgb(153, 153, 153);">446</li><li style="color: rgb(153, 153, 153);">447</li><li style="color: rgb(153, 153, 153);">448</li><li style="color: rgb(153, 153, 153);">449</li><li style="color: rgb(153, 153, 153);">450</li><li style="color: rgb(153, 153, 153);">451</li><li style="color: rgb(153, 153, 153);">452</li><li style="color: rgb(153, 153, 153);">453</li><li style="color: rgb(153, 153, 153);">454</li><li style="color: rgb(153, 153, 153);">455</li><li style="color: rgb(153, 153, 153);">456</li><li style="color: rgb(153, 153, 153);">457</li><li style="color: rgb(153, 153, 153);">458</li><li style="color: rgb(153, 153, 153);">459</li><li style="color: rgb(153, 153, 153);">460</li><li style="color: rgb(153, 153, 153);">461</li><li style="color: rgb(153, 153, 153);">462</li><li style="color: rgb(153, 153, 153);">463</li><li style="color: rgb(153, 153, 153);">464</li><li style="color: rgb(153, 153, 153);">465</li><li style="color: rgb(153, 153, 153);">466</li><li style="color: rgb(153, 153, 153);">467</li><li style="color: rgb(153, 153, 153);">468</li><li style="color: rgb(153, 153, 153);">469</li><li style="color: rgb(153, 153, 153);">470</li><li style="color: rgb(153, 153, 153);">471</li><li style="color: rgb(153, 153, 153);">472</li><li style="color: rgb(153, 153, 153);">473</li><li style="color: rgb(153, 153, 153);">474</li><li style="color: rgb(153, 153, 153);">475</li><li style="color: rgb(153, 153, 153);">476</li><li style="color: rgb(153, 153, 153);">477</li><li style="color: rgb(153, 153, 153);">478</li><li style="color: rgb(153, 153, 153);">479</li><li style="color: rgb(153, 153, 153);">480</li><li style="color: rgb(153, 153, 153);">481</li><li style="color: rgb(153, 153, 153);">482</li><li style="color: rgb(153, 153, 153);">483</li><li style="color: rgb(153, 153, 153);">484</li><li style="color: rgb(153, 153, 153);">485</li><li style="color: rgb(153, 153, 153);">486</li><li style="color: rgb(153, 153, 153);">487</li><li style="color: rgb(153, 153, 153);">488</li><li style="color: rgb(153, 153, 153);">489</li><li style="color: rgb(153, 153, 153);">490</li><li style="color: rgb(153, 153, 153);">491</li><li style="color: rgb(153, 153, 153);">492</li><li style="color: rgb(153, 153, 153);">493</li><li style="color: rgb(153, 153, 153);">494</li><li style="color: rgb(153, 153, 153);">495</li><li style="color: rgb(153, 153, 153);">496</li><li style="color: rgb(153, 153, 153);">497</li><li style="color: rgb(153, 153, 153);">498</li><li style="color: rgb(153, 153, 153);">499</li><li style="color: rgb(153, 153, 153);">500</li><li style="color: rgb(153, 153, 153);">501</li><li style="color: rgb(153, 153, 153);">502</li><li style="color: rgb(153, 153, 153);">503</li><li style="color: rgb(153, 153, 153);">504</li><li style="color: rgb(153, 153, 153);">505</li><li style="color: rgb(153, 153, 153);">506</li><li style="color: rgb(153, 153, 153);">507</li><li style="color: rgb(153, 153, 153);">508</li><li style="color: rgb(153, 153, 153);">509</li><li style="color: rgb(153, 153, 153);">510</li><li style="color: rgb(153, 153, 153);">511</li><li style="color: rgb(153, 153, 153);">512</li><li style="color: rgb(153, 153, 153);">513</li><li style="color: rgb(153, 153, 153);">514</li><li style="color: rgb(153, 153, 153);">515</li><li style="color: rgb(153, 153, 153);">516</li><li style="color: rgb(153, 153, 153);">517</li><li style="color: rgb(153, 153, 153);">518</li><li style="color: rgb(153, 153, 153);">519</li><li style="color: rgb(153, 153, 153);">520</li><li style="color: rgb(153, 153, 153);">521</li><li style="color: rgb(153, 153, 153);">522</li><li style="color: rgb(153, 153, 153);">523</li><li style="color: rgb(153, 153, 153);">524</li><li style="color: rgb(153, 153, 153);">525</li><li style="color: rgb(153, 153, 153);">526</li><li style="color: rgb(153, 153, 153);">527</li><li style="color: rgb(153, 153, 153);">528</li><li style="color: rgb(153, 153, 153);">529</li><li style="color: rgb(153, 153, 153);">530</li><li style="color: rgb(153, 153, 153);">531</li><li style="color: rgb(153, 153, 153);">532</li><li style="color: rgb(153, 153, 153);">533</li><li style="color: rgb(153, 153, 153);">534</li><li style="color: rgb(153, 153, 153);">535</li><li style="color: rgb(153, 153, 153);">536</li><li style="color: rgb(153, 153, 153);">537</li><li style="color: rgb(153, 153, 153);">538</li><li style="color: rgb(153, 153, 153);">539</li><li style="color: rgb(153, 153, 153);">540</li><li style="color: rgb(153, 153, 153);">541</li><li style="color: rgb(153, 153, 153);">542</li><li style="color: rgb(153, 153, 153);">543</li><li style="color: rgb(153, 153, 153);">544</li><li style="color: rgb(153, 153, 153);">545</li><li style="color: rgb(153, 153, 153);">546</li><li style="color: rgb(153, 153, 153);">547</li><li style="color: rgb(153, 153, 153);">548</li><li style="color: rgb(153, 153, 153);">549</li><li style="color: rgb(153, 153, 153);">550</li><li style="color: rgb(153, 153, 153);">551</li><li style="color: rgb(153, 153, 153);">552</li><li style="color: rgb(153, 153, 153);">553</li><li style="color: rgb(153, 153, 153);">554</li><li style="color: rgb(153, 153, 153);">555</li><li style="color: rgb(153, 153, 153);">556</li><li style="color: rgb(153, 153, 153);">557</li><li style="color: rgb(153, 153, 153);">558</li><li style="color: rgb(153, 153, 153);">559</li><li style="color: rgb(153, 153, 153);">560</li><li style="color: rgb(153, 153, 153);">561</li><li style="color: rgb(153, 153, 153);">562</li><li style="color: rgb(153, 153, 153);">563</li><li style="color: rgb(153, 153, 153);">564</li><li style="color: rgb(153, 153, 153);">565</li><li style="color: rgb(153, 153, 153);">566</li><li style="color: rgb(153, 153, 153);">567</li><li style="color: rgb(153, 153, 153);">568</li><li style="color: rgb(153, 153, 153);">569</li><li style="color: rgb(153, 153, 153);">570</li><li style="color: rgb(153, 153, 153);">571</li><li style="color: rgb(153, 153, 153);">572</li><li style="color: rgb(153, 153, 153);">573</li><li style="color: rgb(153, 153, 153);">574</li><li style="color: rgb(153, 153, 153);">575</li><li style="color: rgb(153, 153, 153);">576</li><li style="color: rgb(153, 153, 153);">577</li><li style="color: rgb(153, 153, 153);">578</li><li style="color: rgb(153, 153, 153);">579</li><li style="color: rgb(153, 153, 153);">580</li><li style="color: rgb(153, 153, 153);">581</li><li style="color: rgb(153, 153, 153);">582</li><li style="color: rgb(153, 153, 153);">583</li><li style="color: rgb(153, 153, 153);">584</li><li style="color: rgb(153, 153, 153);">585</li><li style="color: rgb(153, 153, 153);">586</li><li style="color: rgb(153, 153, 153);">587</li><li style="color: rgb(153, 153, 153);">588</li><li style="color: rgb(153, 153, 153);">589</li><li style="color: rgb(153, 153, 153);">590</li><li style="color: rgb(153, 153, 153);">591</li><li style="color: rgb(153, 153, 153);">592</li><li style="color: rgb(153, 153, 153);">593</li><li style="color: rgb(153, 153, 153);">594</li><li style="color: rgb(153, 153, 153);">595</li><li style="color: rgb(153, 153, 153);">596</li><li style="color: rgb(153, 153, 153);">597</li><li style="color: rgb(153, 153, 153);">598</li><li style="color: rgb(153, 153, 153);">599</li><li style="color: rgb(153, 153, 153);">600</li><li style="color: rgb(153, 153, 153);">601</li><li style="color: rgb(153, 153, 153);">602</li><li style="color: rgb(153, 153, 153);">603</li><li style="color: rgb(153, 153, 153);">604</li><li style="color: rgb(153, 153, 153);">605</li><li style="color: rgb(153, 153, 153);">606</li><li style="color: rgb(153, 153, 153);">607</li><li style="color: rgb(153, 153, 153);">608</li><li style="color: rgb(153, 153, 153);">609</li><li style="color: rgb(153, 153, 153);">610</li><li style="color: rgb(153, 153, 153);">611</li><li style="color: rgb(153, 153, 153);">612</li><li style="color: rgb(153, 153, 153);">613</li><li style="color: rgb(153, 153, 153);">614</li><li style="color: rgb(153, 153, 153);">615</li><li style="color: rgb(153, 153, 153);">616</li><li style="color: rgb(153, 153, 153);">617</li><li style="color: rgb(153, 153, 153);">618</li><li style="color: rgb(153, 153, 153);">619</li><li style="color: rgb(153, 153, 153);">620</li><li style="color: rgb(153, 153, 153);">621</li><li style="color: rgb(153, 153, 153);">622</li><li style="color: rgb(153, 153, 153);">623</li><li style="color: rgb(153, 153, 153);">624</li><li style="color: rgb(153, 153, 153);">625</li><li style="color: rgb(153, 153, 153);">626</li><li style="color: rgb(153, 153, 153);">627</li><li style="color: rgb(153, 153, 153);">628</li><li style="color: rgb(153, 153, 153);">629</li><li style="color: rgb(153, 153, 153);">630</li><li style="color: rgb(153, 153, 153);">631</li><li style="color: rgb(153, 153, 153);">632</li><li style="color: rgb(153, 153, 153);">633</li><li style="color: rgb(153, 153, 153);">634</li><li style="color: rgb(153, 153, 153);">635</li><li style="color: rgb(153, 153, 153);">636</li><li style="color: rgb(153, 153, 153);">637</li><li style="color: rgb(153, 153, 153);">638</li><li style="color: rgb(153, 153, 153);">639</li><li style="color: rgb(153, 153, 153);">640</li><li style="color: rgb(153, 153, 153);">641</li><li style="color: rgb(153, 153, 153);">642</li><li style="color: rgb(153, 153, 153);">643</li><li style="color: rgb(153, 153, 153);">644</li><li style="color: rgb(153, 153, 153);">645</li><li style="color: rgb(153, 153, 153);">646</li><li style="color: rgb(153, 153, 153);">647</li><li style="color: rgb(153, 153, 153);">648</li><li style="color: rgb(153, 153, 153);">649</li><li style="color: rgb(153, 153, 153);">650</li><li style="color: rgb(153, 153, 153);">651</li><li style="color: rgb(153, 153, 153);">652</li><li style="color: rgb(153, 153, 153);">653</li><li style="color: rgb(153, 153, 153);">654</li><li style="color: rgb(153, 153, 153);">655</li><li style="color: rgb(153, 153, 153);">656</li><li style="color: rgb(153, 153, 153);">657</li><li style="color: rgb(153, 153, 153);">658</li><li style="color: rgb(153, 153, 153);">659</li><li style="color: rgb(153, 153, 153);">660</li><li style="color: rgb(153, 153, 153);">661</li><li style="color: rgb(153, 153, 153);">662</li><li style="color: rgb(153, 153, 153);">663</li><li style="color: rgb(153, 153, 153);">664</li><li style="color: rgb(153, 153, 153);">665</li><li style="color: rgb(153, 153, 153);">666</li><li style="color: rgb(153, 153, 153);">667</li><li style="color: rgb(153, 153, 153);">668</li><li style="color: rgb(153, 153, 153);">669</li><li style="color: rgb(153, 153, 153);">670</li><li style="color: rgb(153, 153, 153);">671</li><li style="color: rgb(153, 153, 153);">672</li><li style="color: rgb(153, 153, 153);">673</li><li style="color: rgb(153, 153, 153);">674</li><li style="color: rgb(153, 153, 153);">675</li><li style="color: rgb(153, 153, 153);">676</li><li style="color: rgb(153, 153, 153);">677</li><li style="color: rgb(153, 153, 153);">678</li><li style="color: rgb(153, 153, 153);">679</li><li style="color: rgb(153, 153, 153);">680</li><li style="color: rgb(153, 153, 153);">681</li><li style="color: rgb(153, 153, 153);">682</li><li style="color: rgb(153, 153, 153);">683</li><li style="color: rgb(153, 153, 153);">684</li><li style="color: rgb(153, 153, 153);">685</li><li style="color: rgb(153, 153, 153);">686</li><li style="color: rgb(153, 153, 153);">687</li><li style="color: rgb(153, 153, 153);">688</li><li style="color: rgb(153, 153, 153);">689</li><li style="color: rgb(153, 153, 153);">690</li><li style="color: rgb(153, 153, 153);">691</li><li style="color: rgb(153, 153, 153);">692</li><li style="color: rgb(153, 153, 153);">693</li><li style="color: rgb(153, 153, 153);">694</li><li style="color: rgb(153, 153, 153);">695</li><li style="color: rgb(153, 153, 153);">696</li><li style="color: rgb(153, 153, 153);">697</li><li style="color: rgb(153, 153, 153);">698</li><li style="color: rgb(153, 153, 153);">699</li><li style="color: rgb(153, 153, 153);">700</li><li style="color: rgb(153, 153, 153);">701</li><li style="color: rgb(153, 153, 153);">702</li><li style="color: rgb(153, 153, 153);">703</li><li style="color: rgb(153, 153, 153);">704</li><li style="color: rgb(153, 153, 153);">705</li><li style="color: rgb(153, 153, 153);">706</li><li style="color: rgb(153, 153, 153);">707</li><li style="color: rgb(153, 153, 153);">708</li><li style="color: rgb(153, 153, 153);">709</li><li style="color: rgb(153, 153, 153);">710</li><li style="color: rgb(153, 153, 153);">711</li><li style="color: rgb(153, 153, 153);">712</li><li style="color: rgb(153, 153, 153);">713</li><li style="color: rgb(153, 153, 153);">714</li><li style="color: rgb(153, 153, 153);">715</li><li style="color: rgb(153, 153, 153);">716</li><li style="color: rgb(153, 153, 153);">717</li><li style="color: rgb(153, 153, 153);">718</li><li style="color: rgb(153, 153, 153);">719</li><li style="color: rgb(153, 153, 153);">720</li><li style="color: rgb(153, 153, 153);">721</li><li style="color: rgb(153, 153, 153);">722</li><li style="color: rgb(153, 153, 153);">723</li><li style="color: rgb(153, 153, 153);">724</li><li style="color: rgb(153, 153, 153);">725</li><li style="color: rgb(153, 153, 153);">726</li><li style="color: rgb(153, 153, 153);">727</li><li style="color: rgb(153, 153, 153);">728</li><li style="color: rgb(153, 153, 153);">729</li><li style="color: rgb(153, 153, 153);">730</li><li style="color: rgb(153, 153, 153);">731</li><li style="color: rgb(153, 153, 153);">732</li><li style="color: rgb(153, 153, 153);">733</li><li style="color: rgb(153, 153, 153);">734</li><li style="color: rgb(153, 153, 153);">735</li><li style="color: rgb(153, 153, 153);">736</li><li style="color: rgb(153, 153, 153);">737</li><li style="color: rgb(153, 153, 153);">738</li><li style="color: rgb(153, 153, 153);">739</li><li style="color: rgb(153, 153, 153);">740</li><li style="color: rgb(153, 153, 153);">741</li><li style="color: rgb(153, 153, 153);">742</li><li style="color: rgb(153, 153, 153);">743</li><li style="color: rgb(153, 153, 153);">744</li><li style="color: rgb(153, 153, 153);">745</li><li style="color: rgb(153, 153, 153);">746</li><li style="color: rgb(153, 153, 153);">747</li><li style="color: rgb(153, 153, 153);">748</li><li style="color: rgb(153, 153, 153);">749</li><li style="color: rgb(153, 153, 153);">750</li><li style="color: rgb(153, 153, 153);">751</li><li style="color: rgb(153, 153, 153);">752</li><li style="color: rgb(153, 153, 153);">753</li><li style="color: rgb(153, 153, 153);">754</li><li style="color: rgb(153, 153, 153);">755</li><li style="color: rgb(153, 153, 153);">756</li><li style="color: rgb(153, 153, 153);">757</li><li style="color: rgb(153, 153, 153);">758</li><li style="color: rgb(153, 153, 153);">759</li><li style="color: rgb(153, 153, 153);">760</li><li style="color: rgb(153, 153, 153);">761</li><li style="color: rgb(153, 153, 153);">762</li><li style="color: rgb(153, 153, 153);">763</li><li style="color: rgb(153, 153, 153);">764</li><li style="color: rgb(153, 153, 153);">765</li><li style="color: rgb(153, 153, 153);">766</li><li style="color: rgb(153, 153, 153);">767</li><li style="color: rgb(153, 153, 153);">768</li><li style="color: rgb(153, 153, 153);">769</li><li style="color: rgb(153, 153, 153);">770</li><li style="color: rgb(153, 153, 153);">771</li><li style="color: rgb(153, 153, 153);">772</li><li style="color: rgb(153, 153, 153);">773</li><li style="color: rgb(153, 153, 153);">774</li><li style="color: rgb(153, 153, 153);">775</li><li style="color: rgb(153, 153, 153);">776</li><li style="color: rgb(153, 153, 153);">777</li><li style="color: rgb(153, 153, 153);">778</li><li style="color: rgb(153, 153, 153);">779</li><li style="color: rgb(153, 153, 153);">780</li><li style="color: rgb(153, 153, 153);">781</li><li style="color: rgb(153, 153, 153);">782</li><li style="color: rgb(153, 153, 153);">783</li><li style="color: rgb(153, 153, 153);">784</li><li style="color: rgb(153, 153, 153);">785</li><li style="color: rgb(153, 153, 153);">786</li><li style="color: rgb(153, 153, 153);">787</li><li style="color: rgb(153, 153, 153);">788</li><li style="color: rgb(153, 153, 153);">789</li><li style="color: rgb(153, 153, 153);">790</li><li style="color: rgb(153, 153, 153);">791</li><li style="color: rgb(153, 153, 153);">792</li><li style="color: rgb(153, 153, 153);">793</li><li style="color: rgb(153, 153, 153);">794</li><li style="color: rgb(153, 153, 153);">795</li><li style="color: rgb(153, 153, 153);">796</li><li style="color: rgb(153, 153, 153);">797</li><li style="color: rgb(153, 153, 153);">798</li><li style="color: rgb(153, 153, 153);">799</li><li style="color: rgb(153, 153, 153);">800</li><li style="color: rgb(153, 153, 153);">801</li><li style="color: rgb(153, 153, 153);">802</li><li style="color: rgb(153, 153, 153);">803</li><li style="color: rgb(153, 153, 153);">804</li><li style="color: rgb(153, 153, 153);">805</li><li style="color: rgb(153, 153, 153);">806</li><li style="color: rgb(153, 153, 153);">807</li><li style="color: rgb(153, 153, 153);">808</li><li style="color: rgb(153, 153, 153);">809</li><li style="color: rgb(153, 153, 153);">810</li><li style="color: rgb(153, 153, 153);">811</li><li style="color: rgb(153, 153, 153);">812</li><li style="color: rgb(153, 153, 153);">813</li><li style="color: rgb(153, 153, 153);">814</li><li style="color: rgb(153, 153, 153);">815</li><li style="color: rgb(153, 153, 153);">816</li><li style="color: rgb(153, 153, 153);">817</li><li style="color: rgb(153, 153, 153);">818</li><li style="color: rgb(153, 153, 153);">819</li><li style="color: rgb(153, 153, 153);">820</li><li style="color: rgb(153, 153, 153);">821</li><li style="color: rgb(153, 153, 153);">822</li><li style="color: rgb(153, 153, 153);">823</li><li style="color: rgb(153, 153, 153);">824</li><li style="color: rgb(153, 153, 153);">825</li><li style="color: rgb(153, 153, 153);">826</li><li style="color: rgb(153, 153, 153);">827</li><li style="color: rgb(153, 153, 153);">828</li><li style="color: rgb(153, 153, 153);">829</li><li style="color: rgb(153, 153, 153);">830</li><li style="color: rgb(153, 153, 153);">831</li><li style="color: rgb(153, 153, 153);">832</li><li style="color: rgb(153, 153, 153);">833</li><li style="color: rgb(153, 153, 153);">834</li><li style="color: rgb(153, 153, 153);">835</li><li style="color: rgb(153, 153, 153);">836</li><li style="color: rgb(153, 153, 153);">837</li><li style="color: rgb(153, 153, 153);">838</li><li style="color: rgb(153, 153, 153);">839</li><li style="color: rgb(153, 153, 153);">840</li><li style="color: rgb(153, 153, 153);">841</li><li style="color: rgb(153, 153, 153);">842</li><li style="color: rgb(153, 153, 153);">843</li><li style="color: rgb(153, 153, 153);">844</li><li style="color: rgb(153, 153, 153);">845</li><li style="color: rgb(153, 153, 153);">846</li><li style="color: rgb(153, 153, 153);">847</li></ul></pre> 
    <h4><a name="t12"></a><a id="serverhpp_1894"></a>server.hpp</h4> 
    <pre data-index="8" class="set-code-hide prettyprint"><code class="prism language-cpp has-numbering" onclick="mdcp.signin(event)" style="position: unset;">
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">ifndef</span> <span class="token expression">__M_SERVER_H__</span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">__M_SERVER_H__</span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><iostream></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><vector></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><string></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><cassert></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><cstring></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><ctime></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><functional></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><unordered_map></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><thread></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><mutex></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><condition_variable></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><memory></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><typeinfo></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><fcntl.h></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><signal.h></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><unistd.h></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><netinet/in.h></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><arpa/inet.h></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><sys/socket.h></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><sys/epoll.h></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><sys/eventfd.h></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><sys/timerfd.h></span></span>
    
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">INF</span> <span class="token expression"><span class="token number">0</span></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">DBG</span> <span class="token expression"><span class="token number">1</span></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">ERR</span> <span class="token expression"><span class="token number">2</span></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">LOG_LEVEL</span> <span class="token expression">DBG</span></span>
    
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name function">LOG</span><span class="token expression"><span class="token punctuation">(</span>level<span class="token punctuation">,</span> format<span class="token punctuation">,</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span> <span class="token keyword">do</span><span class="token punctuation">{<!-- --></span></span><span class="token punctuation">\</span>
            <span class="token expression"><span class="token keyword">if</span> <span class="token punctuation">(</span>level <span class="token operator"><</span> LOG_LEVEL<span class="token punctuation">)</span> <span class="token keyword">break</span><span class="token punctuation">;</span></span><span class="token punctuation">\</span>
            <span class="token expression">time_t t <span class="token operator">=</span> <span class="token function">time</span><span class="token punctuation">(</span><span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="token punctuation">\</span>
            <span class="token expression"><span class="token keyword">struct</span> <span class="token class-name">tm</span> <span class="token operator">*</span>ltm <span class="token operator">=</span> <span class="token function">localtime</span><span class="token punctuation">(</span><span class="token operator">&</span>t<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="token punctuation">\</span>
            <span class="token expression"><span class="token keyword">char</span> tmp<span class="token punctuation">[</span><span class="token number">32</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">{<!-- --></span><span class="token number">0</span><span class="token punctuation">}</span><span class="token punctuation">;</span></span><span class="token punctuation">\</span>
            <span class="token expression"><span class="token function">strftime</span><span class="token punctuation">(</span>tmp<span class="token punctuation">,</span> <span class="token number">31</span><span class="token punctuation">,</span> </span><span class="token string">"%H:%M:%S"</span><span class="token expression"><span class="token punctuation">,</span> ltm<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="token punctuation">\</span>
            <span class="token expression"><span class="token function">fprintf</span><span class="token punctuation">(</span><span class="token constant">stdout</span><span class="token punctuation">,</span> </span><span class="token string">"[%p %s %s:%d] "</span> <span class="token expression">format </span><span class="token string">"\n"</span><span class="token expression"><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">void</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token function">pthread_self</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> tmp<span class="token punctuation">,</span> <span class="token constant">__FILE__</span><span class="token punctuation">,</span> <span class="token constant">__LINE__</span><span class="token punctuation">,</span> </span><span class="token punctuation">##</span><span class="token expression">__VA_ARGS__<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="token punctuation">\</span>
        <span class="token expression"><span class="token punctuation">}</span><span class="token keyword">while</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span></span></span>
    
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name function">INF_LOG</span><span class="token expression"><span class="token punctuation">(</span>format<span class="token punctuation">,</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span> <span class="token function">LOG</span><span class="token punctuation">(</span>INF<span class="token punctuation">,</span> format<span class="token punctuation">,</span> </span><span class="token punctuation">##</span><span class="token expression">__VA_ARGS__<span class="token punctuation">)</span></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name function">DBG_LOG</span><span class="token expression"><span class="token punctuation">(</span>format<span class="token punctuation">,</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span> <span class="token function">LOG</span><span class="token punctuation">(</span>DBG<span class="token punctuation">,</span> format<span class="token punctuation">,</span> </span><span class="token punctuation">##</span><span class="token expression">__VA_ARGS__<span class="token punctuation">)</span></span></span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name function">ERR_LOG</span><span class="token expression"><span class="token punctuation">(</span>format<span class="token punctuation">,</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span> <span class="token function">LOG</span><span class="token punctuation">(</span>ERR<span class="token punctuation">,</span> format<span class="token punctuation">,</span> </span><span class="token punctuation">##</span><span class="token expression">__VA_ARGS__<span class="token punctuation">)</span></span></span>
    
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">BUFFER_DEFAULT_SIZE</span> <span class="token expression"><span class="token number">1024</span></span></span>
    <span class="token keyword">class</span> <span class="token class-name">Buffer</span> <span class="token punctuation">{<!-- --></span>
        <span class="token keyword">private</span><span class="token operator">:</span>
            std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span><span class="token keyword">char</span><span class="token operator">></span> _buffer<span class="token punctuation">;</span> <span class="token comment">//使用vector进行内存空间管理</span>
            <span class="token keyword">uint64_t</span> _reader_idx<span class="token punctuation">;</span> <span class="token comment">//读偏移</span>
            <span class="token keyword">uint64_t</span> _writer_idx<span class="token punctuation">;</span> <span class="token comment">//写偏移</span>
        <span class="token keyword">public</span><span class="token operator">:</span>
            <span class="token function">Buffer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token function">_reader_idx</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">_writer_idx</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">_buffer</span><span class="token punctuation">(</span>BUFFER_DEFAULT_SIZE<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span>
            <span class="token keyword">char</span> <span class="token operator">*</span><span class="token function">Begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> <span class="token operator">&</span><span class="token operator">*</span>_buffer<span class="token punctuation">.</span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token comment">//获取当前写入起始地址, _buffer的空间起始地址,加上写偏移量</span>
            <span class="token keyword">char</span> <span class="token operator">*</span><span class="token function">WritePosition</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> <span class="token function">Begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> _writer_idx<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token comment">//获取当前读取起始地址</span>
            <span class="token keyword">char</span> <span class="token operator">*</span><span class="token function">ReadPosition</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> <span class="token function">Begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> _reader_idx<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token comment">//获取缓冲区末尾空闲空间大小--写偏移之后的空闲空间, 总体空间大小减去写偏移</span>
            <span class="token keyword">uint64_t</span> <span class="token function">TailIdleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> _buffer<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> _writer_idx<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token comment">//获取缓冲区起始空闲空间大小--读偏移之前的空闲空间</span>
            <span class="token keyword">uint64_t</span> <span class="token function">HeadIdleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> _reader_idx<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token comment">//获取可读数据大小 = 写偏移 - 读偏移</span>
            <span class="token keyword">uint64_t</span> <span class="token function">ReadAbleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> _writer_idx <span class="token operator">-</span> _reader_idx<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token comment">//将读偏移向后移动</span>
            <span class="token keyword">void</span> <span class="token function">MoveReadOffset</span><span class="token punctuation">(</span><span class="token keyword">uint64_t</span> len<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> 
                <span class="token keyword">if</span> <span class="token punctuation">(</span>len <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">return</span><span class="token punctuation">;</span> 
                <span class="token comment">//向后移动的大小,必须小于可读数据大小</span>
                <span class="token function">assert</span><span class="token punctuation">(</span>len <span class="token operator"><=</span> <span class="token function">ReadAbleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                _reader_idx <span class="token operator">+=</span> len<span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//将写偏移向后移动 </span>
            <span class="token keyword">void</span> <span class="token function">MoveWriteOffset</span><span class="token punctuation">(</span><span class="token keyword">uint64_t</span> len<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//向后移动的大小,必须小于当前后边的空闲空间大小</span>
                <span class="token function">assert</span><span class="token punctuation">(</span>len <span class="token operator"><=</span> <span class="token function">TailIdleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                _writer_idx <span class="token operator">+=</span> len<span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//确保可写空间足够(整体空闲空间够了就移动数据,否则就扩容)</span>
            <span class="token keyword">void</span> <span class="token function">EnsureWriteSpace</span><span class="token punctuation">(</span><span class="token keyword">uint64_t</span> len<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//如果末尾空闲空间大小足够,直接返回</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">TailIdleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">>=</span> len<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
                <span class="token comment">//末尾空闲空间不够,则判断加上起始位置的空闲空间大小是否足够, 够了就将数据移动到起始位置</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>len <span class="token operator"><=</span> <span class="token function">TailIdleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token function">HeadIdleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token comment">//将数据移动到起始位置</span>
                    <span class="token keyword">uint64_t</span> rsz <span class="token operator">=</span> <span class="token function">ReadAbleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//把当前数据大小先保存起来</span>
                    std<span class="token double-colon punctuation">::</span><span class="token function">copy</span><span class="token punctuation">(</span><span class="token function">ReadPosition</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">ReadPosition</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> rsz<span class="token punctuation">,</span> <span class="token function">Begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//把可读数据拷贝到起始位置</span>
                    _reader_idx <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>    <span class="token comment">//将读偏移归0</span>
                    _writer_idx <span class="token operator">=</span> rsz<span class="token punctuation">;</span>  <span class="token comment">//将写位置置为可读数据大小, 因为当前的可读数据大小就是写偏移量</span>
                <span class="token punctuation">}</span><span class="token keyword">else</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token comment">//总体空间不够,则需要扩容,不移动数据,直接给写偏移之后扩容足够空间即可</span>
                    <span class="token function">DBG_LOG</span><span class="token punctuation">(</span><span class="token string">"RESIZE %ld"</span><span class="token punctuation">,</span> _writer_idx <span class="token operator">+</span> len<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    _buffer<span class="token punctuation">.</span><span class="token function">resize</span><span class="token punctuation">(</span>_writer_idx <span class="token operator">+</span> len<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
            <span class="token punctuation">}</span> 
            <span class="token comment">//写入数据</span>
            <span class="token keyword">void</span> <span class="token function">Write</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">void</span> <span class="token operator">*</span>data<span class="token punctuation">,</span> <span class="token keyword">uint64_t</span> len<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//1. 保证有足够空间,2. 拷贝数据进去</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>len <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">return</span><span class="token punctuation">;</span>
                <span class="token function">EnsureWriteSpace</span><span class="token punctuation">(</span>len<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>d <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span><span class="token punctuation">)</span>data<span class="token punctuation">;</span>
                std<span class="token double-colon punctuation">::</span><span class="token function">copy</span><span class="token punctuation">(</span>d<span class="token punctuation">,</span> d <span class="token operator">+</span> len<span class="token punctuation">,</span> <span class="token function">WritePosition</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">WriteAndPush</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">void</span> <span class="token operator">*</span>data<span class="token punctuation">,</span> <span class="token keyword">uint64_t</span> len<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token function">Write</span><span class="token punctuation">(</span>data<span class="token punctuation">,</span> len<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token function">MoveWriteOffset</span><span class="token punctuation">(</span>len<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">WriteString</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>data<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">return</span> <span class="token function">Write</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span><span class="token function">c_str</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> data<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">WriteStringAndPush</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>data<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token function">WriteString</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token function">MoveWriteOffset</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">WriteBuffer</span><span class="token punctuation">(</span>Buffer <span class="token operator">&</span>data<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">return</span> <span class="token function">Write</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span><span class="token function">ReadPosition</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> data<span class="token punctuation">.</span><span class="token function">ReadAbleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">WriteBufferAndPush</span><span class="token punctuation">(</span>Buffer <span class="token operator">&</span>data<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> 
                <span class="token function">WriteBuffer</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token function">MoveWriteOffset</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span><span class="token function">ReadAbleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//读取数据</span>
            <span class="token keyword">void</span> <span class="token function">Read</span><span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span>buf<span class="token punctuation">,</span> <span class="token keyword">uint64_t</span> len<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//要求要获取的数据大小必须小于可读数据大小</span>
                <span class="token function">assert</span><span class="token punctuation">(</span>len <span class="token operator"><=</span> <span class="token function">ReadAbleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                std<span class="token double-colon punctuation">::</span><span class="token function">copy</span><span class="token punctuation">(</span><span class="token function">ReadPosition</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">ReadPosition</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> len<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">char</span><span class="token operator">*</span><span class="token punctuation">)</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">ReadAndPop</span><span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span>buf<span class="token punctuation">,</span> <span class="token keyword">uint64_t</span> len<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token function">Read</span><span class="token punctuation">(</span>buf<span class="token punctuation">,</span> len<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token function">MoveReadOffset</span><span class="token punctuation">(</span>len<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            std<span class="token double-colon punctuation">::</span>string <span class="token function">ReadAsString</span><span class="token punctuation">(</span><span class="token keyword">uint64_t</span> len<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//要求要获取的数据大小必须小于可读数据大小</span>
                <span class="token function">assert</span><span class="token punctuation">(</span>len <span class="token operator"><=</span> <span class="token function">ReadAbleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                std<span class="token double-colon punctuation">::</span>string str<span class="token punctuation">;</span>
                str<span class="token punctuation">.</span><span class="token function">resize</span><span class="token punctuation">(</span>len<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token function">Read</span><span class="token punctuation">(</span><span class="token operator">&</span>str<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> len<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">return</span> str<span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            std<span class="token double-colon punctuation">::</span>string <span class="token function">ReadAsStringAndPop</span><span class="token punctuation">(</span><span class="token keyword">uint64_t</span> len<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token function">assert</span><span class="token punctuation">(</span>len <span class="token operator"><=</span> <span class="token function">ReadAbleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                std<span class="token double-colon punctuation">::</span>string str <span class="token operator">=</span> <span class="token function">ReadAsString</span><span class="token punctuation">(</span>len<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token function">MoveReadOffset</span><span class="token punctuation">(</span>len<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">return</span> str<span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">char</span> <span class="token operator">*</span><span class="token function">FindCRLF</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">char</span> <span class="token operator">*</span>res <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">char</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token function">memchr</span><span class="token punctuation">(</span><span class="token function">ReadPosition</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token char">'\n'</span><span class="token punctuation">,</span> <span class="token function">ReadAbleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">return</span> res<span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">/*通常获取一行数据,这种情况针对是*/</span>
            std<span class="token double-colon punctuation">::</span>string <span class="token function">GetLine</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">char</span> <span class="token operator">*</span>pos <span class="token operator">=</span> <span class="token function">FindCRLF</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>pos <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> <span class="token string">""</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token comment">// +1是为了把换行字符也取出来。</span>
                <span class="token keyword">return</span> <span class="token function">ReadAsString</span><span class="token punctuation">(</span>pos <span class="token operator">-</span> <span class="token function">ReadPosition</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            std<span class="token double-colon punctuation">::</span>string <span class="token function">GetLineAndPop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                std<span class="token double-colon punctuation">::</span>string str <span class="token operator">=</span> <span class="token function">GetLine</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token function">MoveReadOffset</span><span class="token punctuation">(</span>str<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">return</span> str<span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//清空缓冲区</span>
            <span class="token keyword">void</span> <span class="token function">Clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//只需要将偏移量归0即可</span>
                _reader_idx <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
                _writer_idx <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">MAX_LISTEN</span> <span class="token expression"><span class="token number">1024</span></span></span>
    <span class="token keyword">class</span> <span class="token class-name">Socket</span> <span class="token punctuation">{<!-- --></span>
        <span class="token keyword">private</span><span class="token operator">:</span>
            <span class="token keyword">int</span> _sockfd<span class="token punctuation">;</span>
        <span class="token keyword">public</span><span class="token operator">:</span>
            <span class="token function">Socket</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token function">_sockfd</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span>
            <span class="token function">Socket</span><span class="token punctuation">(</span><span class="token keyword">int</span> fd<span class="token punctuation">)</span><span class="token operator">:</span> <span class="token function">_sockfd</span><span class="token punctuation">(</span>fd<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span>
            <span class="token operator">~</span><span class="token function">Socket</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token keyword">int</span> <span class="token function">Fd</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> _sockfd<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token comment">//创建套接字</span>
            <span class="token keyword">bool</span> <span class="token function">Create</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">// int socket(int domain, int type, int protocol)</span>
                _sockfd <span class="token operator">=</span> <span class="token function">socket</span><span class="token punctuation">(</span>AF_INET<span class="token punctuation">,</span> SOCK_STREAM<span class="token punctuation">,</span> IPPROTO_TCP<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_sockfd <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token function">ERR_LOG</span><span class="token punctuation">(</span><span class="token string">"CREATE SOCKET FAILED!!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//绑定地址信息</span>
            <span class="token keyword">bool</span> <span class="token function">Bind</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>ip<span class="token punctuation">,</span> <span class="token keyword">uint16_t</span> port<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">struct</span> <span class="token class-name">sockaddr_in</span> addr<span class="token punctuation">;</span>
                addr<span class="token punctuation">.</span>sin_family <span class="token operator">=</span> AF_INET<span class="token punctuation">;</span>
                addr<span class="token punctuation">.</span>sin_port <span class="token operator">=</span> <span class="token function">htons</span><span class="token punctuation">(</span>port<span class="token punctuation">)</span><span class="token punctuation">;</span>
                addr<span class="token punctuation">.</span>sin_addr<span class="token punctuation">.</span>s_addr <span class="token operator">=</span> <span class="token function">inet_addr</span><span class="token punctuation">(</span>ip<span class="token punctuation">.</span><span class="token function">c_str</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                socklen_t len <span class="token operator">=</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">sockaddr_in</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token comment">// int bind(int sockfd, struct sockaddr*addr, socklen_t len);</span>
                <span class="token keyword">int</span> ret <span class="token operator">=</span> <span class="token function">bind</span><span class="token punctuation">(</span>_sockfd<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">sockaddr</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&</span>addr<span class="token punctuation">,</span> len<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token function">ERR_LOG</span><span class="token punctuation">(</span><span class="token string">"BIND ADDRESS FAILED!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//开始监听</span>
            <span class="token keyword">bool</span> <span class="token function">Listen</span><span class="token punctuation">(</span><span class="token keyword">int</span> backlog <span class="token operator">=</span> MAX_LISTEN<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">// int listen(int backlog)</span>
                <span class="token keyword">int</span> ret <span class="token operator">=</span> <span class="token function">listen</span><span class="token punctuation">(</span>_sockfd<span class="token punctuation">,</span> backlog<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token function">ERR_LOG</span><span class="token punctuation">(</span><span class="token string">"SOCKET LISTEN FAILED!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//向服务器发起连接</span>
            <span class="token keyword">bool</span> <span class="token function">Connect</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>ip<span class="token punctuation">,</span> <span class="token keyword">uint16_t</span> port<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">struct</span> <span class="token class-name">sockaddr_in</span> addr<span class="token punctuation">;</span>
                addr<span class="token punctuation">.</span>sin_family <span class="token operator">=</span> AF_INET<span class="token punctuation">;</span>
                addr<span class="token punctuation">.</span>sin_port <span class="token operator">=</span> <span class="token function">htons</span><span class="token punctuation">(</span>port<span class="token punctuation">)</span><span class="token punctuation">;</span>
                addr<span class="token punctuation">.</span>sin_addr<span class="token punctuation">.</span>s_addr <span class="token operator">=</span> <span class="token function">inet_addr</span><span class="token punctuation">(</span>ip<span class="token punctuation">.</span><span class="token function">c_str</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                socklen_t len <span class="token operator">=</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">sockaddr_in</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token comment">// int connect(int sockfd, struct sockaddr*addr, socklen_t len);</span>
                <span class="token keyword">int</span> ret <span class="token operator">=</span> <span class="token function">connect</span><span class="token punctuation">(</span>_sockfd<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">sockaddr</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&</span>addr<span class="token punctuation">,</span> len<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token function">ERR_LOG</span><span class="token punctuation">(</span><span class="token string">"CONNECT SERVER FAILED!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//获取新连接</span>
            <span class="token keyword">int</span> <span class="token function">Accept</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">// int accept(int sockfd, struct sockaddr *addr, socklen_t *len);</span>
                <span class="token keyword">int</span> newfd <span class="token operator">=</span> <span class="token function">accept</span><span class="token punctuation">(</span>_sockfd<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>newfd <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token function">ERR_LOG</span><span class="token punctuation">(</span><span class="token string">"SOCKET ACCEPT FAILED!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> newfd<span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//接收数据</span>
            ssize_t <span class="token function">Recv</span><span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span>buf<span class="token punctuation">,</span> size_t len<span class="token punctuation">,</span> <span class="token keyword">int</span> flag <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">// ssize_t recv(int sockfd, void *buf, size_t len, int flag);</span>
                ssize_t ret <span class="token operator">=</span> <span class="token function">recv</span><span class="token punctuation">(</span>_sockfd<span class="token punctuation">,</span> buf<span class="token punctuation">,</span> len<span class="token punctuation">,</span> flag<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator"><=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token comment">//EAGAIN 当前socket的接收缓冲区中没有数据了,在非阻塞的情况下才会有这个错误</span>
                    <span class="token comment">//EINTR  表示当前socket的阻塞等待,被信号打断了,</span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>errno <span class="token operator">==</span> EAGAIN <span class="token operator">||</span> errno <span class="token operator">==</span> EINTR<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                        <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token comment">//表示这次接收没有接收到数据</span>
                    <span class="token punctuation">}</span>
                    <span class="token function">ERR_LOG</span><span class="token punctuation">(</span><span class="token string">"SOCKET RECV FAILED!!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> ret<span class="token punctuation">;</span> <span class="token comment">//实际接收的数据长度</span>
            <span class="token punctuation">}</span>
            ssize_t <span class="token function">NonBlockRecv</span><span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span>buf<span class="token punctuation">,</span> size_t len<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">return</span> <span class="token function">Recv</span><span class="token punctuation">(</span>buf<span class="token punctuation">,</span> len<span class="token punctuation">,</span> MSG_DONTWAIT<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// MSG_DONTWAIT 表示当前接收为非阻塞。</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//发送数据</span>
            ssize_t <span class="token function">Send</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">void</span> <span class="token operator">*</span>buf<span class="token punctuation">,</span> size_t len<span class="token punctuation">,</span> <span class="token keyword">int</span> flag <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">// ssize_t send(int sockfd, void *data, size_t len, int flag);</span>
                ssize_t ret <span class="token operator">=</span> <span class="token function">send</span><span class="token punctuation">(</span>_sockfd<span class="token punctuation">,</span> buf<span class="token punctuation">,</span> len<span class="token punctuation">,</span> flag<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>errno <span class="token operator">==</span> EAGAIN <span class="token operator">||</span> errno <span class="token operator">==</span> EINTR<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                        <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                    <span class="token function">ERR_LOG</span><span class="token punctuation">(</span><span class="token string">"SOCKET SEND FAILED!!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> ret<span class="token punctuation">;</span><span class="token comment">//实际发送的数据长度</span>
            <span class="token punctuation">}</span>
            ssize_t <span class="token function">NonBlockSend</span><span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span>buf<span class="token punctuation">,</span> size_t len<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>len <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
                <span class="token keyword">return</span> <span class="token function">Send</span><span class="token punctuation">(</span>buf<span class="token punctuation">,</span> len<span class="token punctuation">,</span> MSG_DONTWAIT<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// MSG_DONTWAIT 表示当前发送为非阻塞。</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//关闭套接字</span>
            <span class="token keyword">void</span> <span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_sockfd <span class="token operator">!=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token function">close</span><span class="token punctuation">(</span>_sockfd<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    _sockfd <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//创建一个服务端连接</span>
            <span class="token keyword">bool</span> <span class="token function">CreateServer</span><span class="token punctuation">(</span><span class="token keyword">uint16_t</span> port<span class="token punctuation">,</span> <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>ip <span class="token operator">=</span> <span class="token string">"0.0.0.0"</span><span class="token punctuation">,</span> <span class="token keyword">bool</span> block_flag <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//1. 创建套接字,2. 绑定地址,3. 开始监听,4. 设置非阻塞, 5. 启动地址重用</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">Create</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>block_flag<span class="token punctuation">)</span> <span class="token function">NonBlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">Bind</span><span class="token punctuation">(</span>ip<span class="token punctuation">,</span> port<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">Listen</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token function">ReuseAddress</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//创建一个客户端连接</span>
            <span class="token keyword">bool</span> <span class="token function">CreateClient</span><span class="token punctuation">(</span><span class="token keyword">uint16_t</span> port<span class="token punctuation">,</span> <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>ip<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//1. 创建套接字,2.指向连接服务器</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">Create</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">Connect</span><span class="token punctuation">(</span>ip<span class="token punctuation">,</span> port<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//设置套接字选项---开启地址端口重用</span>
            <span class="token keyword">void</span> <span class="token function">ReuseAddress</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">// int setsockopt(int fd, int leve, int optname, void *val, int vallen)</span>
                <span class="token keyword">int</span> val <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
                <span class="token function">setsockopt</span><span class="token punctuation">(</span>_sockfd<span class="token punctuation">,</span> SOL_SOCKET<span class="token punctuation">,</span> SO_REUSEADDR<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">void</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&</span>val<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                val <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
                <span class="token function">setsockopt</span><span class="token punctuation">(</span>_sockfd<span class="token punctuation">,</span> SOL_SOCKET<span class="token punctuation">,</span> SO_REUSEPORT<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">void</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&</span>val<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//设置套接字阻塞属性-- 设置为非阻塞</span>
            <span class="token keyword">void</span> <span class="token function">NonBlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//int fcntl(int fd, int cmd, ... /* arg */ );</span>
                <span class="token keyword">int</span> flag <span class="token operator">=</span> <span class="token function">fcntl</span><span class="token punctuation">(</span>_sockfd<span class="token punctuation">,</span> F_GETFL<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token function">fcntl</span><span class="token punctuation">(</span>_sockfd<span class="token punctuation">,</span> F_SETFL<span class="token punctuation">,</span> flag <span class="token operator">|</span> O_NONBLOCK<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    
    <span class="token keyword">class</span> <span class="token class-name">Poller</span><span class="token punctuation">;</span>
    <span class="token keyword">class</span> <span class="token class-name">EventLoop</span><span class="token punctuation">;</span>
    <span class="token keyword">class</span> <span class="token class-name">Channel</span> <span class="token punctuation">{<!-- --></span>
        <span class="token keyword">private</span><span class="token operator">:</span>
            <span class="token keyword">int</span> _fd<span class="token punctuation">;</span>
            EventLoop <span class="token operator">*</span>_loop<span class="token punctuation">;</span>
            <span class="token keyword">uint32_t</span> _events<span class="token punctuation">;</span>  <span class="token comment">// 当前需要监控的事件</span>
            <span class="token keyword">uint32_t</span> _revents<span class="token punctuation">;</span> <span class="token comment">// 当前连接触发的事件</span>
            <span class="token keyword">using</span> EventCallback <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span>function<span class="token operator"><</span><span class="token keyword">void</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">></span><span class="token punctuation">;</span>
            EventCallback _read_callback<span class="token punctuation">;</span>   <span class="token comment">//可读事件被触发的回调函数</span>
            EventCallback _write_callback<span class="token punctuation">;</span>  <span class="token comment">//可写事件被触发的回调函数</span>
            EventCallback _error_callback<span class="token punctuation">;</span>  <span class="token comment">//错误事件被触发的回调函数</span>
            EventCallback _close_callback<span class="token punctuation">;</span>  <span class="token comment">//连接断开事件被触发的回调函数</span>
            EventCallback _event_callback<span class="token punctuation">;</span>  <span class="token comment">//任意事件被触发的回调函数</span>
        <span class="token keyword">public</span><span class="token operator">:</span>
            <span class="token function">Channel</span><span class="token punctuation">(</span>EventLoop <span class="token operator">*</span>loop<span class="token punctuation">,</span> <span class="token keyword">int</span> fd<span class="token punctuation">)</span><span class="token operator">:</span><span class="token function">_fd</span><span class="token punctuation">(</span>fd<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">_events</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">_revents</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">_loop</span><span class="token punctuation">(</span>loop<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span>
            <span class="token keyword">int</span> <span class="token function">Fd</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> _fd<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token keyword">uint32_t</span> <span class="token function">Events</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> _events<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token comment">//获取想要监控的事件</span>
            <span class="token keyword">void</span> <span class="token function">SetREvents</span><span class="token punctuation">(</span><span class="token keyword">uint32_t</span> events<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> _revents <span class="token operator">=</span> events<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token comment">//设置实际就绪的事件</span>
            <span class="token keyword">void</span> <span class="token function">SetReadCallback</span><span class="token punctuation">(</span><span class="token keyword">const</span> EventCallback <span class="token operator">&</span>cb<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> _read_callback <span class="token operator">=</span> cb<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">SetWriteCallback</span><span class="token punctuation">(</span><span class="token keyword">const</span> EventCallback <span class="token operator">&</span>cb<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> _write_callback <span class="token operator">=</span> cb<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">SetErrorCallback</span><span class="token punctuation">(</span><span class="token keyword">const</span> EventCallback <span class="token operator">&</span>cb<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> _error_callback <span class="token operator">=</span> cb<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">SetCloseCallback</span><span class="token punctuation">(</span><span class="token keyword">const</span> EventCallback <span class="token operator">&</span>cb<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> _close_callback <span class="token operator">=</span> cb<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">SetEventCallback</span><span class="token punctuation">(</span><span class="token keyword">const</span> EventCallback <span class="token operator">&</span>cb<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> _event_callback <span class="token operator">=</span> cb<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token comment">//当前是否监控了可读</span>
            <span class="token keyword">bool</span> <span class="token function">ReadAble</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> <span class="token punctuation">(</span>_events <span class="token operator">&</span> EPOLLIN<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> 
            <span class="token comment">//当前是否监控了可写</span>
            <span class="token keyword">bool</span> <span class="token function">WriteAble</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> <span class="token punctuation">(</span>_events <span class="token operator">&</span> EPOLLOUT<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token comment">//启动读事件监控</span>
            <span class="token keyword">void</span> <span class="token function">EnableRead</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> _events <span class="token operator">|=</span> EPOLLIN<span class="token punctuation">;</span> <span class="token function">Update</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token comment">//启动写事件监控</span>
            <span class="token keyword">void</span> <span class="token function">EnableWrite</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> _events <span class="token operator">|=</span> EPOLLOUT<span class="token punctuation">;</span> <span class="token function">Update</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token comment">//关闭读事件监控</span>
            <span class="token keyword">void</span> <span class="token function">DisableRead</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> _events <span class="token operator">&=</span> <span class="token operator">~</span>EPOLLIN<span class="token punctuation">;</span> <span class="token function">Update</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token comment">//关闭写事件监控</span>
            <span class="token keyword">void</span> <span class="token function">DisableWrite</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> _events <span class="token operator">&=</span> <span class="token operator">~</span>EPOLLOUT<span class="token punctuation">;</span> <span class="token function">Update</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token comment">//关闭所有事件监控</span>
            <span class="token keyword">void</span> <span class="token function">DisableAll</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> _events <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token function">Update</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token comment">//移除监控</span>
            <span class="token keyword">void</span> <span class="token function">Remove</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">void</span> <span class="token function">Update</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token comment">//事件处理,一旦连接触发了事件,就调用这个函数,自己触发了什么事件如何处理自己决定</span>
            <span class="token keyword">void</span> <span class="token function">HandleEvent</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>_revents <span class="token operator">&</span> EPOLLIN<span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token punctuation">(</span>_revents <span class="token operator">&</span> EPOLLRDHUP<span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token punctuation">(</span>_revents <span class="token operator">&</span> EPOLLPRI<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token comment">/*不管任何事件,都调用的回调函数*/</span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>_read_callback<span class="token punctuation">)</span> <span class="token function">_read_callback</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token comment">/*有可能会释放连接的操作事件,一次只处理一个*/</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_revents <span class="token operator">&</span> EPOLLOUT<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>_write_callback<span class="token punctuation">)</span> <span class="token function">_write_callback</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span><span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>_revents <span class="token operator">&</span> EPOLLERR<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>_error_callback<span class="token punctuation">)</span> <span class="token function">_error_callback</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//一旦出错,就会释放连接,因此要放到前边调用任意回调</span>
                <span class="token punctuation">}</span><span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>_revents <span class="token operator">&</span> EPOLLHUP<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>_close_callback<span class="token punctuation">)</span> <span class="token function">_close_callback</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_event_callback<span class="token punctuation">)</span> <span class="token function">_event_callback</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">MAX_EPOLLEVENTS</span> <span class="token expression"><span class="token number">1024</span></span></span>
    <span class="token keyword">class</span> <span class="token class-name">Poller</span> <span class="token punctuation">{<!-- --></span>
        <span class="token keyword">private</span><span class="token operator">:</span>
            <span class="token keyword">int</span> _epfd<span class="token punctuation">;</span>
            <span class="token keyword">struct</span> <span class="token class-name">epoll_event</span> _evs<span class="token punctuation">[</span>MAX_EPOLLEVENTS<span class="token punctuation">]</span><span class="token punctuation">;</span>
            std<span class="token double-colon punctuation">::</span>unordered_map<span class="token operator"><</span><span class="token keyword">int</span><span class="token punctuation">,</span> Channel <span class="token operator">*</span><span class="token operator">></span> _channels<span class="token punctuation">;</span>
        <span class="token keyword">private</span><span class="token operator">:</span>
            <span class="token comment">//对epoll的直接操作</span>
            <span class="token keyword">void</span> <span class="token function">Update</span><span class="token punctuation">(</span>Channel <span class="token operator">*</span>channel<span class="token punctuation">,</span> <span class="token keyword">int</span> op<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">// int epoll_ctl(int epfd, int op,  int fd,  struct epoll_event *ev);</span>
                <span class="token keyword">int</span> fd <span class="token operator">=</span> channel<span class="token operator">-></span><span class="token function">Fd</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">struct</span> <span class="token class-name">epoll_event</span> ev<span class="token punctuation">;</span>
                ev<span class="token punctuation">.</span>data<span class="token punctuation">.</span>fd <span class="token operator">=</span> fd<span class="token punctuation">;</span>
                ev<span class="token punctuation">.</span>events <span class="token operator">=</span> channel<span class="token operator">-></span><span class="token function">Events</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">int</span> ret <span class="token operator">=</span> <span class="token function">epoll_ctl</span><span class="token punctuation">(</span>_epfd<span class="token punctuation">,</span> op<span class="token punctuation">,</span> fd<span class="token punctuation">,</span> <span class="token operator">&</span>ev<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token function">ERR_LOG</span><span class="token punctuation">(</span><span class="token string">"EPOLLCTL FAILED!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//判断一个Channel是否已经添加了事件监控</span>
            <span class="token keyword">bool</span> <span class="token function">HasChannel</span><span class="token punctuation">(</span>Channel <span class="token operator">*</span>channel<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">auto</span> it <span class="token operator">=</span> _channels<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>channel<span class="token operator">-></span><span class="token function">Fd</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>it <span class="token operator">==</span> _channels<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token keyword">public</span><span class="token operator">:</span>
            <span class="token function">Poller</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _epfd <span class="token operator">=</span> <span class="token function">epoll_create</span><span class="token punctuation">(</span>MAX_EPOLLEVENTS<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_epfd <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token function">ERR_LOG</span><span class="token punctuation">(</span><span class="token string">"EPOLL CREATE FAILED!!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token function">abort</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//退出程序</span>
                <span class="token punctuation">}</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//添加或修改监控事件</span>
            <span class="token keyword">void</span> <span class="token function">UpdateEvent</span><span class="token punctuation">(</span>Channel <span class="token operator">*</span>channel<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">bool</span> ret <span class="token operator">=</span> <span class="token function">HasChannel</span><span class="token punctuation">(</span>channel<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator">==</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token comment">//不存在则添加</span>
                    _channels<span class="token punctuation">.</span><span class="token function">insert</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">make_pair</span><span class="token punctuation">(</span>channel<span class="token operator">-></span><span class="token function">Fd</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> channel<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token keyword">return</span> <span class="token function">Update</span><span class="token punctuation">(</span>channel<span class="token punctuation">,</span> EPOLL_CTL_ADD<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> <span class="token function">Update</span><span class="token punctuation">(</span>channel<span class="token punctuation">,</span> EPOLL_CTL_MOD<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//移除监控</span>
            <span class="token keyword">void</span> <span class="token function">RemoveEvent</span><span class="token punctuation">(</span>Channel <span class="token operator">*</span>channel<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">auto</span> it <span class="token operator">=</span> _channels<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>channel<span class="token operator">-></span><span class="token function">Fd</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>it <span class="token operator">!=</span> _channels<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    _channels<span class="token punctuation">.</span><span class="token function">erase</span><span class="token punctuation">(</span>it<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token function">Update</span><span class="token punctuation">(</span>channel<span class="token punctuation">,</span> EPOLL_CTL_DEL<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//开始监控,返回活跃连接</span>
            <span class="token keyword">void</span> <span class="token function">Poll</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>Channel<span class="token operator">*</span><span class="token operator">></span> <span class="token operator">*</span>active<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">// int epoll_wait(int epfd, struct epoll_event *evs, int maxevents, int timeout)</span>
                <span class="token keyword">int</span> nfds <span class="token operator">=</span> <span class="token function">epoll_wait</span><span class="token punctuation">(</span>_epfd<span class="token punctuation">,</span> _evs<span class="token punctuation">,</span> MAX_EPOLLEVENTS<span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>nfds <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>errno <span class="token operator">==</span> EINTR<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                        <span class="token keyword">return</span> <span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                    <span class="token function">ERR_LOG</span><span class="token punctuation">(</span><span class="token string">"EPOLL WAIT ERROR:%s\n"</span><span class="token punctuation">,</span> <span class="token function">strerror</span><span class="token punctuation">(</span>errno<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token function">abort</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//退出程序</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> nfds<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">auto</span> it <span class="token operator">=</span> _channels<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>_evs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>data<span class="token punctuation">.</span>fd<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token function">assert</span><span class="token punctuation">(</span>it <span class="token operator">!=</span> _channels<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    it<span class="token operator">-></span>second<span class="token operator">-></span><span class="token function">SetREvents</span><span class="token punctuation">(</span>_evs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>events<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//设置实际就绪的事件</span>
                    active<span class="token operator">-></span><span class="token function">push_back</span><span class="token punctuation">(</span>it<span class="token operator">-></span>second<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    
    
    <span class="token keyword">using</span> TaskFunc <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span>function<span class="token operator"><</span><span class="token keyword">void</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">></span><span class="token punctuation">;</span>
    <span class="token keyword">using</span> ReleaseFunc <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span>function<span class="token operator"><</span><span class="token keyword">void</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">></span><span class="token punctuation">;</span>
    <span class="token keyword">class</span> <span class="token class-name">TimerTask</span><span class="token punctuation">{<!-- --></span>
        <span class="token keyword">private</span><span class="token operator">:</span>
            <span class="token keyword">uint64_t</span> _id<span class="token punctuation">;</span>       <span class="token comment">// 定时器任务对象ID</span>
            <span class="token keyword">uint32_t</span> _timeout<span class="token punctuation">;</span>  <span class="token comment">//定时任务的超时时间</span>
            <span class="token keyword">bool</span> _canceled<span class="token punctuation">;</span>     <span class="token comment">// false-表示没有被取消, true-表示被取消</span>
            TaskFunc _task_cb<span class="token punctuation">;</span>  <span class="token comment">//定时器对象要执行的定时任务</span>
            ReleaseFunc _release<span class="token punctuation">;</span> <span class="token comment">//用于删除TimerWheel中保存的定时器对象信息</span>
        <span class="token keyword">public</span><span class="token operator">:</span>
            <span class="token function">TimerTask</span><span class="token punctuation">(</span><span class="token keyword">uint64_t</span> id<span class="token punctuation">,</span> <span class="token keyword">uint32_t</span> delay<span class="token punctuation">,</span> <span class="token keyword">const</span> TaskFunc <span class="token operator">&</span>cb<span class="token punctuation">)</span><span class="token operator">:</span> 
                <span class="token function">_id</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">_timeout</span><span class="token punctuation">(</span>delay<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">_task_cb</span><span class="token punctuation">(</span>cb<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">_canceled</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span>
            <span class="token operator">~</span><span class="token function">TimerTask</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> 
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_canceled <span class="token operator">==</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token function">_task_cb</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> 
                <span class="token function">_release</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> 
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">Cancel</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> _canceled <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">SetRelease</span><span class="token punctuation">(</span><span class="token keyword">const</span> ReleaseFunc <span class="token operator">&</span>cb<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> _release <span class="token operator">=</span> cb<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token keyword">uint32_t</span> <span class="token function">DelayTime</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> _timeout<span class="token punctuation">;</span> <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    
    <span class="token keyword">class</span> <span class="token class-name">TimerWheel</span> <span class="token punctuation">{<!-- --></span>
        <span class="token keyword">private</span><span class="token operator">:</span>
            <span class="token keyword">using</span> WeakTask <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span>weak_ptr<span class="token operator"><</span>TimerTask<span class="token operator">></span><span class="token punctuation">;</span>
            <span class="token keyword">using</span> PtrTask <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span>shared_ptr<span class="token operator"><</span>TimerTask<span class="token operator">></span><span class="token punctuation">;</span>
            <span class="token keyword">int</span> _tick<span class="token punctuation">;</span>      <span class="token comment">//当前的秒针,走到哪里释放哪里,释放哪里,就相当于执行哪里的任务</span>
            <span class="token keyword">int</span> _capacity<span class="token punctuation">;</span>  <span class="token comment">//表盘最大数量---其实就是最大延迟时间</span>
            std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>PtrTask<span class="token operator">>></span> _wheel<span class="token punctuation">;</span>
            std<span class="token double-colon punctuation">::</span>unordered_map<span class="token operator"><</span><span class="token keyword">uint64_t</span><span class="token punctuation">,</span> WeakTask<span class="token operator">></span> _timers<span class="token punctuation">;</span>
    
            EventLoop <span class="token operator">*</span>_loop<span class="token punctuation">;</span>
            <span class="token keyword">int</span> _timerfd<span class="token punctuation">;</span><span class="token comment">//定时器描述符--可读事件回调就是读取计数器,执行定时任务</span>
            std<span class="token double-colon punctuation">::</span>unique_ptr<span class="token operator"><</span>Channel<span class="token operator">></span> _timer_channel<span class="token punctuation">;</span>
        <span class="token keyword">private</span><span class="token operator">:</span>
            <span class="token keyword">void</span> <span class="token function">RemoveTimer</span><span class="token punctuation">(</span><span class="token keyword">uint64_t</span> id<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">auto</span> it <span class="token operator">=</span> _timers<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>it <span class="token operator">!=</span> _timers<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    _timers<span class="token punctuation">.</span><span class="token function">erase</span><span class="token punctuation">(</span>it<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">static</span> <span class="token keyword">int</span> <span class="token function">CreateTimerfd</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">int</span> timerfd <span class="token operator">=</span> <span class="token function">timerfd_create</span><span class="token punctuation">(</span>CLOCK_MONOTONIC<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>timerfd <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token function">ERR_LOG</span><span class="token punctuation">(</span><span class="token string">"TIMERFD CREATE FAILED!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token function">abort</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token comment">//int timerfd_settime(int fd, int flags, struct itimerspec *new, struct itimerspec *old);</span>
                <span class="token keyword">struct</span> <span class="token class-name">itimerspec</span> itime<span class="token punctuation">;</span>
                itime<span class="token punctuation">.</span>it_value<span class="token punctuation">.</span>tv_sec <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
                itime<span class="token punctuation">.</span>it_value<span class="token punctuation">.</span>tv_nsec <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token comment">//第一次超时时间为1s后</span>
                itime<span class="token punctuation">.</span>it_interval<span class="token punctuation">.</span>tv_sec <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> 
                itime<span class="token punctuation">.</span>it_interval<span class="token punctuation">.</span>tv_nsec <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">//第一次超时后,每次超时的间隔时</span>
                <span class="token function">timerfd_settime</span><span class="token punctuation">(</span>timerfd<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token operator">&</span>itime<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">return</span> timerfd<span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">int</span> <span class="token function">ReadTimefd</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">uint64_t</span> times<span class="token punctuation">;</span>
                <span class="token comment">//有可能因为其他描述符的事件处理花费事件比较长,然后在处理定时器描述符事件的时候,有可能就已经超时了很多次</span>
                <span class="token comment">//read读取到的数据times就是从上一次read之后超时的次数</span>
                <span class="token keyword">int</span> ret <span class="token operator">=</span> <span class="token function">read</span><span class="token punctuation">(</span>_timerfd<span class="token punctuation">,</span> <span class="token operator">&</span>times<span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token function">ERR_LOG</span><span class="token punctuation">(</span><span class="token string">"READ TIMEFD FAILED!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token function">abort</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> times<span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//这个函数应该每秒钟被执行一次,相当于秒针向后走了一步</span>
            <span class="token keyword">void</span> <span class="token function">RunTimerTask</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _tick <span class="token operator">=</span> <span class="token punctuation">(</span>_tick <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">%</span> _capacity<span class="token punctuation">;</span>
                _wheel<span class="token punctuation">[</span>_tick<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//清空指定位置的数组,就会把数组中保存的所有管理定时器对象的shared_ptr释放掉</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">OnTime</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//根据实际超时的次数,执行对应的超时任务</span>
                <span class="token keyword">int</span> times <span class="token operator">=</span> <span class="token function">ReadTimefd</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> times<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token function">RunTimerTask</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">TimerAddInLoop</span><span class="token punctuation">(</span><span class="token keyword">uint64_t</span> id<span class="token punctuation">,</span> <span class="token keyword">uint32_t</span> delay<span class="token punctuation">,</span> <span class="token keyword">const</span> TaskFunc <span class="token operator">&</span>cb<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                PtrTask <span class="token function">pt</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token function">TimerTask</span><span class="token punctuation">(</span>id<span class="token punctuation">,</span> delay<span class="token punctuation">,</span> cb<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                pt<span class="token operator">-></span><span class="token function">SetRelease</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token operator">&</span>TimerWheel<span class="token double-colon punctuation">::</span>RemoveTimer<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">,</span> id<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">int</span> pos <span class="token operator">=</span> <span class="token punctuation">(</span>_tick <span class="token operator">+</span> delay<span class="token punctuation">)</span> <span class="token operator">%</span> _capacity<span class="token punctuation">;</span>
                _wheel<span class="token punctuation">[</span>pos<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">push_back</span><span class="token punctuation">(</span>pt<span class="token punctuation">)</span><span class="token punctuation">;</span>
                _timers<span class="token punctuation">[</span>id<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">WeakTask</span><span class="token punctuation">(</span>pt<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">TimerRefreshInLoop</span><span class="token punctuation">(</span><span class="token keyword">uint64_t</span> id<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//通过保存的定时器对象的weak_ptr构造一个shared_ptr出来,添加到轮子中</span>
                <span class="token keyword">auto</span> it <span class="token operator">=</span> _timers<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>it <span class="token operator">==</span> _timers<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span><span class="token punctuation">;</span><span class="token comment">//没找着定时任务,没法刷新,没法延迟</span>
                <span class="token punctuation">}</span>
                PtrTask pt <span class="token operator">=</span> it<span class="token operator">-></span>second<span class="token punctuation">.</span><span class="token function">lock</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//lock获取weak_ptr管理的对象对应的shared_ptr</span>
                <span class="token keyword">int</span> delay <span class="token operator">=</span> pt<span class="token operator">-></span><span class="token function">DelayTime</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">int</span> pos <span class="token operator">=</span> <span class="token punctuation">(</span>_tick <span class="token operator">+</span> delay<span class="token punctuation">)</span> <span class="token operator">%</span> _capacity<span class="token punctuation">;</span>
                _wheel<span class="token punctuation">[</span>pos<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">push_back</span><span class="token punctuation">(</span>pt<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">TimerCancelInLoop</span><span class="token punctuation">(</span><span class="token keyword">uint64_t</span> id<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">auto</span> it <span class="token operator">=</span> _timers<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>it <span class="token operator">==</span> _timers<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span><span class="token punctuation">;</span><span class="token comment">//没找着定时任务,没法刷新,没法延迟</span>
                <span class="token punctuation">}</span>
                PtrTask pt <span class="token operator">=</span> it<span class="token operator">-></span>second<span class="token punctuation">.</span><span class="token function">lock</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>pt<span class="token punctuation">)</span> pt<span class="token operator">-></span><span class="token function">Cancel</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token keyword">public</span><span class="token operator">:</span>
            <span class="token function">TimerWheel</span><span class="token punctuation">(</span>EventLoop <span class="token operator">*</span>loop<span class="token punctuation">)</span><span class="token operator">:</span><span class="token function">_capacity</span><span class="token punctuation">(</span><span class="token number">60</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">_tick</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">_wheel</span><span class="token punctuation">(</span>_capacity<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">_loop</span><span class="token punctuation">(</span>loop<span class="token punctuation">)</span><span class="token punctuation">,</span> 
                <span class="token function">_timerfd</span><span class="token punctuation">(</span><span class="token function">CreateTimerfd</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">_timer_channel</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token function">Channel</span><span class="token punctuation">(</span>_loop<span class="token punctuation">,</span> _timerfd<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _timer_channel<span class="token operator">-></span><span class="token function">SetReadCallback</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token operator">&</span>TimerWheel<span class="token double-colon punctuation">::</span>OnTime<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                _timer_channel<span class="token operator">-></span><span class="token function">EnableRead</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//启动读事件监控</span>
            <span class="token punctuation">}</span>
            <span class="token comment">/*定时器中有个_timers成员,定时器信息的操作有可能在多线程中进行,因此需要考虑线程安全问题*/</span>
            <span class="token comment">/*如果不想加锁,那就把对定期的所有操作,都放到一个线程中进行*/</span>
            <span class="token keyword">void</span> <span class="token function">TimerAdd</span><span class="token punctuation">(</span><span class="token keyword">uint64_t</span> id<span class="token punctuation">,</span> <span class="token keyword">uint32_t</span> delay<span class="token punctuation">,</span> <span class="token keyword">const</span> TaskFunc <span class="token operator">&</span>cb<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token comment">//刷新/延迟定时任务</span>
            <span class="token keyword">void</span> <span class="token function">TimerRefresh</span><span class="token punctuation">(</span><span class="token keyword">uint64_t</span> id<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">void</span> <span class="token function">TimerCancel</span><span class="token punctuation">(</span><span class="token keyword">uint64_t</span> id<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token comment">/*这个接口存在线程安全问题--这个接口实际上不能被外界使用者调用,只能在模块内,在对应的EventLoop线程内执行*/</span>
            <span class="token keyword">bool</span> <span class="token function">HasTimer</span><span class="token punctuation">(</span><span class="token keyword">uint64_t</span> id<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">auto</span> it <span class="token operator">=</span> _timers<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>it <span class="token operator">==</span> _timers<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    
    <span class="token keyword">class</span> <span class="token class-name">EventLoop</span> <span class="token punctuation">{<!-- --></span>
        <span class="token keyword">private</span><span class="token operator">:</span>
            <span class="token keyword">using</span> Functor <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span>function<span class="token operator"><</span><span class="token keyword">void</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">></span><span class="token punctuation">;</span>
            std<span class="token double-colon punctuation">::</span>thread<span class="token double-colon punctuation">::</span>id _thread_id<span class="token punctuation">;</span><span class="token comment">//线程ID</span>
            <span class="token keyword">int</span> _event_fd<span class="token punctuation">;</span><span class="token comment">//eventfd唤醒IO事件监控有可能导致的阻塞</span>
            std<span class="token double-colon punctuation">::</span>unique_ptr<span class="token operator"><</span>Channel<span class="token operator">></span> _event_channel<span class="token punctuation">;</span>
            Poller _poller<span class="token punctuation">;</span><span class="token comment">//进行所有描述符的事件监控</span>
            std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>Functor<span class="token operator">></span> _tasks<span class="token punctuation">;</span><span class="token comment">//任务池</span>
            std<span class="token double-colon punctuation">::</span>mutex _mutex<span class="token punctuation">;</span><span class="token comment">//实现任务池操作的线程安全</span>
            TimerWheel _timer_wheel<span class="token punctuation">;</span><span class="token comment">//定时器模块</span>
        <span class="token keyword">public</span><span class="token operator">:</span>
            <span class="token comment">//执行任务池中的所有任务</span>
            <span class="token keyword">void</span> <span class="token function">RunAllTask</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>Functor<span class="token operator">></span> functor<span class="token punctuation">;</span>
                <span class="token punctuation">{<!-- --></span>
                    std<span class="token double-colon punctuation">::</span>unique_lock<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>mutex<span class="token operator">></span> <span class="token function">_lock</span><span class="token punctuation">(</span>_mutex<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    _tasks<span class="token punctuation">.</span><span class="token function">swap</span><span class="token punctuation">(</span>functor<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">auto</span> <span class="token operator">&</span>f <span class="token operator">:</span> functor<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> <span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">static</span> <span class="token keyword">int</span> <span class="token function">CreateEventFd</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">int</span> efd <span class="token operator">=</span> <span class="token function">eventfd</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> EFD_CLOEXEC <span class="token operator">|</span> EFD_NONBLOCK<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>efd <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token function">ERR_LOG</span><span class="token punctuation">(</span><span class="token string">"CREATE EVENTFD FAILED!!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token function">abort</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//让程序异常退出</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> efd<span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">ReadEventfd</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">uint64_t</span> res <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
                <span class="token keyword">int</span> ret <span class="token operator">=</span> <span class="token function">read</span><span class="token punctuation">(</span>_event_fd<span class="token punctuation">,</span> <span class="token operator">&</span>res<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token comment">//EINTR -- 被信号打断;   EAGAIN -- 表示无数据可读</span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>errno <span class="token operator">==</span> EINTR <span class="token operator">||</span> errno <span class="token operator">==</span> EAGAIN<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                        <span class="token keyword">return</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                    <span class="token function">ERR_LOG</span><span class="token punctuation">(</span><span class="token string">"READ EVENTFD FAILED!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token function">abort</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> <span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">WeakUpEventFd</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">uint64_t</span> val <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
                <span class="token keyword">int</span> ret <span class="token operator">=</span> <span class="token function">write</span><span class="token punctuation">(</span>_event_fd<span class="token punctuation">,</span> <span class="token operator">&</span>val<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>errno <span class="token operator">==</span> EINTR<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                        <span class="token keyword">return</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                    <span class="token function">ERR_LOG</span><span class="token punctuation">(</span><span class="token string">"READ EVENTFD FAILED!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token function">abort</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> <span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token keyword">public</span><span class="token operator">:</span>
            <span class="token function">EventLoop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token function">_thread_id</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span>this_thread<span class="token double-colon punctuation">::</span><span class="token function">get_id</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> 
                        <span class="token function">_event_fd</span><span class="token punctuation">(</span><span class="token function">CreateEventFd</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> 
                        <span class="token function">_event_channel</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token function">Channel</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> _event_fd<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
                        <span class="token function">_timer_wheel</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//给eventfd添加可读事件回调函数,读取eventfd事件通知次数</span>
                _event_channel<span class="token operator">-></span><span class="token function">SetReadCallback</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token operator">&</span>EventLoop<span class="token double-colon punctuation">::</span>ReadEventfd<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token comment">//启动eventfd的读事件监控</span>
                _event_channel<span class="token operator">-></span><span class="token function">EnableRead</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//三步走--事件监控-》就绪事件处理-》执行任务</span>
            <span class="token keyword">void</span> <span class="token function">Start</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">while</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token comment">//1. 事件监控, </span>
                    std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>Channel <span class="token operator">*</span><span class="token operator">></span> actives<span class="token punctuation">;</span>
                    _poller<span class="token punctuation">.</span><span class="token function">Poll</span><span class="token punctuation">(</span><span class="token operator">&</span>actives<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token comment">//2. 事件处理。 </span>
                    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">auto</span> <span class="token operator">&</span>channel <span class="token operator">:</span> actives<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                        channel<span class="token operator">-></span><span class="token function">HandleEvent</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                    <span class="token comment">//3. 执行任务</span>
                    <span class="token function">RunAllTask</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//用于判断当前线程是否是EventLoop对应的线程;</span>
            <span class="token keyword">bool</span> <span class="token function">IsInLoop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">return</span> <span class="token punctuation">(</span>_thread_id <span class="token operator">==</span> std<span class="token double-colon punctuation">::</span>this_thread<span class="token double-colon punctuation">::</span><span class="token function">get_id</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">AssertInLoop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token function">assert</span><span class="token punctuation">(</span>_thread_id <span class="token operator">==</span> std<span class="token double-colon punctuation">::</span>this_thread<span class="token double-colon punctuation">::</span><span class="token function">get_id</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//判断将要执行的任务是否处于当前线程中,如果是则执行,不是则压入队列。</span>
            <span class="token keyword">void</span> <span class="token function">RunInLoop</span><span class="token punctuation">(</span><span class="token keyword">const</span> Functor <span class="token operator">&</span>cb<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">IsInLoop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> <span class="token function">cb</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> <span class="token function">QueueInLoop</span><span class="token punctuation">(</span>cb<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//将操作压入任务池</span>
            <span class="token keyword">void</span> <span class="token function">QueueInLoop</span><span class="token punctuation">(</span><span class="token keyword">const</span> Functor <span class="token operator">&</span>cb<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token punctuation">{<!-- --></span>
                    std<span class="token double-colon punctuation">::</span>unique_lock<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>mutex<span class="token operator">></span> <span class="token function">_lock</span><span class="token punctuation">(</span>_mutex<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    _tasks<span class="token punctuation">.</span><span class="token function">push_back</span><span class="token punctuation">(</span>cb<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token comment">//唤醒有可能因为没有事件就绪,而导致的epoll阻塞;</span>
                <span class="token comment">//其实就是给eventfd写入一个数据,eventfd就会触发可读事件</span>
                <span class="token function">WeakUpEventFd</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//添加/修改描述符的事件监控</span>
            <span class="token keyword">void</span> <span class="token function">UpdateEvent</span><span class="token punctuation">(</span>Channel <span class="token operator">*</span>channel<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> _poller<span class="token punctuation">.</span><span class="token function">UpdateEvent</span><span class="token punctuation">(</span>channel<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token comment">//移除描述符的监控</span>
            <span class="token keyword">void</span> <span class="token function">RemoveEvent</span><span class="token punctuation">(</span>Channel <span class="token operator">*</span>channel<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> _poller<span class="token punctuation">.</span><span class="token function">RemoveEvent</span><span class="token punctuation">(</span>channel<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">TimerAdd</span><span class="token punctuation">(</span><span class="token keyword">uint64_t</span> id<span class="token punctuation">,</span> <span class="token keyword">uint32_t</span> delay<span class="token punctuation">,</span> <span class="token keyword">const</span> TaskFunc <span class="token operator">&</span>cb<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> _timer_wheel<span class="token punctuation">.</span><span class="token function">TimerAdd</span><span class="token punctuation">(</span>id<span class="token punctuation">,</span> delay<span class="token punctuation">,</span> cb<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">TimerRefresh</span><span class="token punctuation">(</span><span class="token keyword">uint64_t</span> id<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> _timer_wheel<span class="token punctuation">.</span><span class="token function">TimerRefresh</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">TimerCancel</span><span class="token punctuation">(</span><span class="token keyword">uint64_t</span> id<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> _timer_wheel<span class="token punctuation">.</span><span class="token function">TimerCancel</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token keyword">bool</span> <span class="token function">HasTimer</span><span class="token punctuation">(</span><span class="token keyword">uint64_t</span> id<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> _timer_wheel<span class="token punctuation">.</span><span class="token function">HasTimer</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token keyword">class</span> <span class="token class-name">LoopThread</span> <span class="token punctuation">{<!-- --></span>
        <span class="token keyword">private</span><span class="token operator">:</span>
            <span class="token comment">/*用于实现_loop获取的同步关系,避免线程创建了,但是_loop还没有实例化之前去获取_loop*/</span>
            std<span class="token double-colon punctuation">::</span>mutex _mutex<span class="token punctuation">;</span>          <span class="token comment">// 互斥锁</span>
            std<span class="token double-colon punctuation">::</span>condition_variable _cond<span class="token punctuation">;</span>   <span class="token comment">// 条件变量</span>
            EventLoop <span class="token operator">*</span>_loop<span class="token punctuation">;</span>       <span class="token comment">// EventLoop指针变量,这个对象需要在线程内实例化</span>
            std<span class="token double-colon punctuation">::</span>thread _thread<span class="token punctuation">;</span>    <span class="token comment">// EventLoop对应的线程</span>
        <span class="token keyword">private</span><span class="token operator">:</span>
            <span class="token comment">/*实例化 EventLoop 对象,唤醒_cond上有可能阻塞的线程,并且开始运行EventLoop模块的功能*/</span>
            <span class="token keyword">void</span> <span class="token function">ThreadEntry</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                EventLoop loop<span class="token punctuation">;</span>
                <span class="token punctuation">{<!-- --></span>
                    std<span class="token double-colon punctuation">::</span>unique_lock<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>mutex<span class="token operator">></span> <span class="token function">lock</span><span class="token punctuation">(</span>_mutex<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//加锁</span>
                    _loop <span class="token operator">=</span> <span class="token operator">&</span>loop<span class="token punctuation">;</span>
                    _cond<span class="token punctuation">.</span><span class="token function">notify_all</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                loop<span class="token punctuation">.</span><span class="token function">Start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token keyword">public</span><span class="token operator">:</span>
            <span class="token comment">/*创建线程,设定线程入口函数*/</span>
            <span class="token function">LoopThread</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token function">_loop</span><span class="token punctuation">(</span><span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">_thread</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">thread</span><span class="token punctuation">(</span><span class="token operator">&</span>LoopThread<span class="token double-colon punctuation">::</span>ThreadEntry<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span>
            <span class="token comment">/*返回当前线程关联的EventLoop对象指针*/</span>
            EventLoop <span class="token operator">*</span><span class="token function">GetLoop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                EventLoop <span class="token operator">*</span>loop <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
                <span class="token punctuation">{<!-- --></span>
                    std<span class="token double-colon punctuation">::</span>unique_lock<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>mutex<span class="token operator">></span> <span class="token function">lock</span><span class="token punctuation">(</span>_mutex<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//加锁</span>
                    _cond<span class="token punctuation">.</span><span class="token function">wait</span><span class="token punctuation">(</span>lock<span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token operator">&</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> _loop <span class="token operator">!=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//loop为NULL就一直阻塞</span>
                    loop <span class="token operator">=</span> _loop<span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> loop<span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    
    <span class="token keyword">class</span> <span class="token class-name">LoopThreadPool</span> <span class="token punctuation">{<!-- --></span>
        <span class="token keyword">private</span><span class="token operator">:</span>
            <span class="token keyword">int</span> _thread_count<span class="token punctuation">;</span>
            <span class="token keyword">int</span> _next_idx<span class="token punctuation">;</span>
            EventLoop <span class="token operator">*</span>_baseloop<span class="token punctuation">;</span>
            std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>LoopThread<span class="token operator">*</span><span class="token operator">></span> _threads<span class="token punctuation">;</span>
            std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>EventLoop <span class="token operator">*</span><span class="token operator">></span> _loops<span class="token punctuation">;</span>
        <span class="token keyword">public</span><span class="token operator">:</span>
            <span class="token function">LoopThreadPool</span><span class="token punctuation">(</span>EventLoop <span class="token operator">*</span>baseloop<span class="token punctuation">)</span><span class="token operator">:</span><span class="token function">_thread_count</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">_next_idx</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">_baseloop</span><span class="token punctuation">(</span>baseloop<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">SetThreadCount</span><span class="token punctuation">(</span><span class="token keyword">int</span> count<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> _thread_count <span class="token operator">=</span> count<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">Create</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_thread_count <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    _threads<span class="token punctuation">.</span><span class="token function">resize</span><span class="token punctuation">(</span>_thread_count<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    _loops<span class="token punctuation">.</span><span class="token function">resize</span><span class="token punctuation">(</span>_thread_count<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> _thread_count<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                        _threads<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token function">LoopThread</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                        _loops<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> _threads<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span><span class="token function">GetLoop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> <span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            EventLoop <span class="token operator">*</span><span class="token function">NextLoop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_thread_count <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> _baseloop<span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                _next_idx <span class="token operator">=</span> <span class="token punctuation">(</span>_next_idx <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">%</span> _thread_count<span class="token punctuation">;</span>
                <span class="token keyword">return</span> _loops<span class="token punctuation">[</span>_next_idx<span class="token punctuation">]</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    
    
    <span class="token keyword">class</span> <span class="token class-name">Any</span><span class="token punctuation">{<!-- --></span>
        <span class="token keyword">private</span><span class="token operator">:</span>
            <span class="token keyword">class</span> <span class="token class-name">holder</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">public</span><span class="token operator">:</span>
                    <span class="token keyword">virtual</span> <span class="token operator">~</span><span class="token function">holder</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span>
                    <span class="token keyword">virtual</span> <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>type_info<span class="token operator">&</span> <span class="token function">type</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
                    <span class="token keyword">virtual</span> holder <span class="token operator">*</span><span class="token function">clone</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span><span class="token punctuation">;</span>
            <span class="token keyword">template</span><span class="token operator"><</span><span class="token keyword">class</span> <span class="token class-name">T</span><span class="token operator">></span>
            <span class="token keyword">class</span> <span class="token class-name">placeholder</span><span class="token operator">:</span> <span class="token base-clause"><span class="token keyword">public</span> <span class="token class-name">holder</span></span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">public</span><span class="token operator">:</span>
                    <span class="token function">placeholder</span><span class="token punctuation">(</span><span class="token keyword">const</span> T <span class="token operator">&</span>val<span class="token punctuation">)</span><span class="token operator">:</span> <span class="token function">_val</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span>
                    <span class="token comment">// 获取子类对象保存的数据类型</span>
                    <span class="token keyword">virtual</span> <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>type_info<span class="token operator">&</span> <span class="token function">type</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> <span class="token keyword">typeid</span><span class="token punctuation">(</span>T<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
                    <span class="token comment">// 针对当前的对象自身,克隆出一个新的子类对象</span>
                    <span class="token keyword">virtual</span> holder <span class="token operator">*</span><span class="token function">clone</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token function">placeholder</span><span class="token punctuation">(</span>_val<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
                <span class="token keyword">public</span><span class="token operator">:</span>
                    T _val<span class="token punctuation">;</span>
            <span class="token punctuation">}</span><span class="token punctuation">;</span>
            holder <span class="token operator">*</span>_content<span class="token punctuation">;</span>
        <span class="token keyword">public</span><span class="token operator">:</span>
            <span class="token function">Any</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token function">_content</span><span class="token punctuation">(</span><span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span>
            <span class="token keyword">template</span><span class="token operator"><</span><span class="token keyword">class</span> <span class="token class-name">T</span><span class="token operator">></span>
            <span class="token function">Any</span><span class="token punctuation">(</span><span class="token keyword">const</span> T <span class="token operator">&</span>val<span class="token punctuation">)</span><span class="token operator">:</span><span class="token function">_content</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token generic-function"><span class="token function">placeholder</span><span class="token generic class-name"><span class="token operator"><</span>T<span class="token operator">></span></span></span><span class="token punctuation">(</span>val<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span>
            <span class="token function">Any</span><span class="token punctuation">(</span><span class="token keyword">const</span> Any <span class="token operator">&</span>other<span class="token punctuation">)</span><span class="token operator">:</span><span class="token function">_content</span><span class="token punctuation">(</span>other<span class="token punctuation">.</span>_content <span class="token operator">?</span> other<span class="token punctuation">.</span>_content<span class="token operator">-></span><span class="token function">clone</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span>
            <span class="token operator">~</span><span class="token function">Any</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">delete</span> _content<span class="token punctuation">;</span> <span class="token punctuation">}</span>
    
            Any <span class="token operator">&</span><span class="token function">swap</span><span class="token punctuation">(</span>Any <span class="token operator">&</span>other<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                std<span class="token double-colon punctuation">::</span><span class="token function">swap</span><span class="token punctuation">(</span>_content<span class="token punctuation">,</span> other<span class="token punctuation">.</span>_content<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">return</span> <span class="token operator">*</span><span class="token keyword">this</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
    
            <span class="token comment">// 返回子类对象保存的数据的指针</span>
            <span class="token keyword">template</span><span class="token operator"><</span><span class="token keyword">class</span> <span class="token class-name">T</span><span class="token operator">></span>
            T <span class="token operator">*</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//想要获取的数据类型,必须和保存的数据类型一致</span>
                <span class="token function">assert</span><span class="token punctuation">(</span><span class="token keyword">typeid</span><span class="token punctuation">(</span>T<span class="token punctuation">)</span> <span class="token operator">==</span> _content<span class="token operator">-></span><span class="token function">type</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">return</span> <span class="token operator">&</span><span class="token punctuation">(</span><span class="token punctuation">(</span>placeholder<span class="token operator"><</span>T<span class="token operator">></span><span class="token operator">*</span><span class="token punctuation">)</span>_content<span class="token punctuation">)</span><span class="token operator">-></span>_val<span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//赋值运算符的重载函数</span>
            <span class="token keyword">template</span><span class="token operator"><</span><span class="token keyword">class</span> <span class="token class-name">T</span><span class="token operator">></span>
            Any<span class="token operator">&</span> <span class="token keyword">operator</span><span class="token operator">=</span><span class="token punctuation">(</span><span class="token keyword">const</span> T <span class="token operator">&</span>val<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//为val构造一个临时的通用容器,然后与当前容器自身进行指针交换,临时对象释放的时候,原先保存的数据也就被释放</span>
                <span class="token function">Any</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">swap</span><span class="token punctuation">(</span><span class="token operator">*</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">return</span> <span class="token operator">*</span><span class="token keyword">this</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            Any<span class="token operator">&</span> <span class="token keyword">operator</span><span class="token operator">=</span><span class="token punctuation">(</span><span class="token keyword">const</span> Any <span class="token operator">&</span>other<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token function">Any</span><span class="token punctuation">(</span>other<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">swap</span><span class="token punctuation">(</span><span class="token operator">*</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">return</span> <span class="token operator">*</span><span class="token keyword">this</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    
    <span class="token keyword">class</span> <span class="token class-name">Connection</span><span class="token punctuation">;</span>
    <span class="token comment">//DISCONECTED -- 连接关闭状态;   CONNECTING -- 连接建立成功-待处理状态</span>
    <span class="token comment">//CONNECTED -- 连接建立完成,各种设置已完成,可以通信的状态;  DISCONNECTING -- 待关闭状态</span>
    <span class="token keyword">typedef</span> <span class="token keyword">enum</span> <span class="token punctuation">{<!-- --></span> DISCONNECTED<span class="token punctuation">,</span> CONNECTING<span class="token punctuation">,</span> CONNECTED<span class="token punctuation">,</span> DISCONNECTING<span class="token punctuation">}</span>ConnStatu<span class="token punctuation">;</span>
    <span class="token keyword">using</span> PtrConnection <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span>shared_ptr<span class="token operator"><</span>Connection<span class="token operator">></span><span class="token punctuation">;</span>
    <span class="token keyword">class</span> <span class="token class-name">Connection</span> <span class="token operator">:</span> <span class="token base-clause"><span class="token keyword">public</span> std<span class="token double-colon punctuation">::</span><span class="token class-name">enable_shared_from_this</span><span class="token operator"><</span><span class="token class-name">Connection</span><span class="token operator">></span></span> <span class="token punctuation">{<!-- --></span>
        <span class="token keyword">private</span><span class="token operator">:</span>
            <span class="token keyword">uint64_t</span> _conn_id<span class="token punctuation">;</span>  <span class="token comment">// 连接的唯一ID,便于连接的管理和查找</span>
            <span class="token comment">//uint64_t _timer_id;   //定时器ID,必须是唯一的,这块为了简化操作使用conn_id作为定时器ID</span>
            <span class="token keyword">int</span> _sockfd<span class="token punctuation">;</span>        <span class="token comment">// 连接关联的文件描述符</span>
            <span class="token keyword">bool</span> _enable_inactive_release<span class="token punctuation">;</span>  <span class="token comment">// 连接是否启动非活跃销毁的判断标志,默认为false</span>
            EventLoop <span class="token operator">*</span>_loop<span class="token punctuation">;</span>   <span class="token comment">// 连接所关联的一个EventLoop</span>
            ConnStatu _statu<span class="token punctuation">;</span>   <span class="token comment">// 连接状态</span>
            Socket _socket<span class="token punctuation">;</span>     <span class="token comment">// 套接字操作管理</span>
            Channel _channel<span class="token punctuation">;</span>   <span class="token comment">// 连接的事件管理</span>
            Buffer _in_buffer<span class="token punctuation">;</span>  <span class="token comment">// 输入缓冲区---存放从socket中读取到的数据</span>
            Buffer _out_buffer<span class="token punctuation">;</span> <span class="token comment">// 输出缓冲区---存放要发送给对端的数据</span>
            Any _context<span class="token punctuation">;</span>       <span class="token comment">// 请求的接收处理上下文</span>
    
            <span class="token comment">/*这四个回调函数,是让服务器模块来设置的(其实服务器模块的处理回调也是组件使用者设置的)*/</span>
            <span class="token comment">/*换句话说,这几个回调都是组件使用者使用的*/</span>
            <span class="token keyword">using</span> ConnectedCallback <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span>function<span class="token operator"><</span><span class="token keyword">void</span><span class="token punctuation">(</span><span class="token keyword">const</span> PtrConnection<span class="token operator">&</span><span class="token punctuation">)</span><span class="token operator">></span><span class="token punctuation">;</span>
            <span class="token keyword">using</span> MessageCallback <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span>function<span class="token operator"><</span><span class="token keyword">void</span><span class="token punctuation">(</span><span class="token keyword">const</span> PtrConnection<span class="token operator">&</span><span class="token punctuation">,</span> Buffer <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">></span><span class="token punctuation">;</span>
            <span class="token keyword">using</span> ClosedCallback <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span>function<span class="token operator"><</span><span class="token keyword">void</span><span class="token punctuation">(</span><span class="token keyword">const</span> PtrConnection<span class="token operator">&</span><span class="token punctuation">)</span><span class="token operator">></span><span class="token punctuation">;</span>
            <span class="token keyword">using</span> AnyEventCallback <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span>function<span class="token operator"><</span><span class="token keyword">void</span><span class="token punctuation">(</span><span class="token keyword">const</span> PtrConnection<span class="token operator">&</span><span class="token punctuation">)</span><span class="token operator">></span><span class="token punctuation">;</span>
            ConnectedCallback _connected_callback<span class="token punctuation">;</span>
            MessageCallback _message_callback<span class="token punctuation">;</span>
            ClosedCallback _closed_callback<span class="token punctuation">;</span>
            AnyEventCallback _event_callback<span class="token punctuation">;</span>
            <span class="token comment">/*组件内的连接关闭回调--组件内设置的,因为服务器组件内会把所有的连接管理起来,一旦某个连接要关闭*/</span>
            <span class="token comment">/*就应该从管理的地方移除掉自己的信息*/</span>
            ClosedCallback _server_closed_callback<span class="token punctuation">;</span>
        <span class="token keyword">private</span><span class="token operator">:</span>
            <span class="token comment">/*五个channel的事件回调函数*/</span>
            <span class="token comment">//描述符可读事件触发后调用的函数,接收socket数据放到接收缓冲区中,然后调用_message_callback</span>
            <span class="token keyword">void</span> <span class="token function">HandleRead</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//1. 接收socket的数据,放到缓冲区</span>
                <span class="token keyword">char</span> buf<span class="token punctuation">[</span><span class="token number">65536</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
                ssize_t ret <span class="token operator">=</span> _socket<span class="token punctuation">.</span><span class="token function">NonBlockRecv</span><span class="token punctuation">(</span>buf<span class="token punctuation">,</span> <span class="token number">65535</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token comment">//出错了,不能直接关闭连接</span>
                    <span class="token keyword">return</span> <span class="token function">ShutdownInLoop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token comment">//这里的等于0表示的是没有读取到数据,而并不是连接断开了,连接断开返回的是-1</span>
                <span class="token comment">//将数据放入输入缓冲区,写入之后顺便将写偏移向后移动</span>
                _in_buffer<span class="token punctuation">.</span><span class="token function">WriteAndPush</span><span class="token punctuation">(</span>buf<span class="token punctuation">,</span> ret<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token comment">//2. 调用message_callback进行业务处理</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_in_buffer<span class="token punctuation">.</span><span class="token function">ReadAbleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token comment">//shared_from_this--从当前对象自身获取自身的shared_ptr管理对象</span>
                    <span class="token keyword">return</span> <span class="token function">_message_callback</span><span class="token punctuation">(</span><span class="token function">shared_from_this</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token operator">&</span>_in_buffer<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//描述符可写事件触发后调用的函数,将发送缓冲区中的数据进行发送</span>
            <span class="token keyword">void</span> <span class="token function">HandleWrite</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//_out_buffer中保存的数据就是要发送的数据</span>
                ssize_t ret <span class="token operator">=</span> _socket<span class="token punctuation">.</span><span class="token function">NonBlockSend</span><span class="token punctuation">(</span>_out_buffer<span class="token punctuation">.</span><span class="token function">ReadPosition</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> _out_buffer<span class="token punctuation">.</span><span class="token function">ReadAbleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token comment">//发送错误就该关闭连接了,</span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>_in_buffer<span class="token punctuation">.</span><span class="token function">ReadAbleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                        <span class="token function">_message_callback</span><span class="token punctuation">(</span><span class="token function">shared_from_this</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token operator">&</span>_in_buffer<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                    <span class="token keyword">return</span> <span class="token function">Release</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//这时候就是实际的关闭释放操作了。</span>
                <span class="token punctuation">}</span>
                _out_buffer<span class="token punctuation">.</span><span class="token function">MoveReadOffset</span><span class="token punctuation">(</span>ret<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//千万不要忘了,将读偏移向后移动</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_out_buffer<span class="token punctuation">.</span><span class="token function">ReadAbleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    _channel<span class="token punctuation">.</span><span class="token function">DisableWrite</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 没有数据待发送了,关闭写事件监控</span>
                    <span class="token comment">//如果当前是连接待关闭状态,则有数据,发送完数据释放连接,没有数据则直接释放</span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>_statu <span class="token operator">==</span> DISCONNECTING<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                        <span class="token keyword">return</span> <span class="token function">Release</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//描述符触发挂断事件</span>
            <span class="token keyword">void</span> <span class="token function">HandleClose</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">/*一旦连接挂断了,套接字就什么都干不了了,因此有数据待处理就处理一下,完毕关闭连接*/</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_in_buffer<span class="token punctuation">.</span><span class="token function">ReadAbleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token function">_message_callback</span><span class="token punctuation">(</span><span class="token function">shared_from_this</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token operator">&</span>_in_buffer<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">return</span> <span class="token function">Release</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//描述符触发出错事件</span>
            <span class="token keyword">void</span> <span class="token function">HandleError</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">return</span> <span class="token function">HandleClose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//描述符触发任意事件: 1. 刷新连接的活跃度--延迟定时销毁任务;  2. 调用组件使用者的任意事件回调</span>
            <span class="token keyword">void</span> <span class="token function">HandleEvent</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_enable_inactive_release <span class="token operator">==</span> <span class="token boolean">true</span><span class="token punctuation">)</span>  <span class="token punctuation">{<!-- --></span>  _loop<span class="token operator">-></span><span class="token function">TimerRefresh</span><span class="token punctuation">(</span>_conn_id<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_event_callback<span class="token punctuation">)</span>  <span class="token punctuation">{<!-- --></span>  <span class="token function">_event_callback</span><span class="token punctuation">(</span><span class="token function">shared_from_this</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//连接获取之后,所处的状态下要进行各种设置(启动读监控,调用回调函数)</span>
            <span class="token keyword">void</span> <span class="token function">EstablishedInLoop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">// 1. 修改连接状态;  2. 启动读事件监控;  3. 调用回调函数</span>
                <span class="token function">assert</span><span class="token punctuation">(</span>_statu <span class="token operator">==</span> CONNECTING<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//当前的状态必须一定是上层的半连接状态</span>
                _statu <span class="token operator">=</span> CONNECTED<span class="token punctuation">;</span><span class="token comment">//当前函数执行完毕,则连接进入已完成连接状态</span>
                <span class="token comment">// 一旦启动读事件监控就有可能会立即触发读事件,如果这时候启动了非活跃连接销毁</span>
                _channel<span class="token punctuation">.</span><span class="token function">EnableRead</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_connected_callback<span class="token punctuation">)</span> <span class="token function">_connected_callback</span><span class="token punctuation">(</span><span class="token function">shared_from_this</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//这个接口才是实际的释放接口</span>
            <span class="token keyword">void</span> <span class="token function">ReleaseInLoop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//1. 修改连接状态,将其置为DISCONNECTED</span>
                _statu <span class="token operator">=</span> DISCONNECTED<span class="token punctuation">;</span>
                <span class="token comment">//2. 移除连接的事件监控</span>
                _channel<span class="token punctuation">.</span><span class="token function">Remove</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token comment">//3. 关闭描述符</span>
                _socket<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token comment">//4. 如果当前定时器队列中还有定时销毁任务,则取消任务</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_loop<span class="token operator">-></span><span class="token function">HasTimer</span><span class="token punctuation">(</span>_conn_id<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token function">CancelInactiveReleaseInLoop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token comment">//5. 调用关闭回调函数,避免先移除服务器管理的连接信息导致Connection被释放,再去处理会出错,因此先调用用户的回调函数</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_closed_callback<span class="token punctuation">)</span> <span class="token function">_closed_callback</span><span class="token punctuation">(</span><span class="token function">shared_from_this</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token comment">//移除服务器内部管理的连接信息</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_server_closed_callback<span class="token punctuation">)</span> <span class="token function">_server_closed_callback</span><span class="token punctuation">(</span><span class="token function">shared_from_this</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//这个接口并不是实际的发送接口,而只是把数据放到了发送缓冲区,启动了可写事件监控</span>
            <span class="token keyword">void</span> <span class="token function">SendInLoop</span><span class="token punctuation">(</span>Buffer <span class="token operator">&</span>buf<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_statu <span class="token operator">==</span> DISCONNECTED<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">;</span>
                _out_buffer<span class="token punctuation">.</span><span class="token function">WriteBufferAndPush</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_channel<span class="token punctuation">.</span><span class="token function">WriteAble</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    _channel<span class="token punctuation">.</span><span class="token function">EnableWrite</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//这个关闭操作并非实际的连接释放操作,需要判断还有没有数据待处理,待发送</span>
            <span class="token keyword">void</span> <span class="token function">ShutdownInLoop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _statu <span class="token operator">=</span> DISCONNECTING<span class="token punctuation">;</span><span class="token comment">// 设置连接为半关闭状态</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_in_buffer<span class="token punctuation">.</span><span class="token function">ReadAbleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>_message_callback<span class="token punctuation">)</span> <span class="token function">_message_callback</span><span class="token punctuation">(</span><span class="token function">shared_from_this</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token operator">&</span>_in_buffer<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token comment">//要么就是写入数据的时候出错关闭,要么就是没有待发送数据,直接关闭</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_out_buffer<span class="token punctuation">.</span><span class="token function">ReadAbleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span>_channel<span class="token punctuation">.</span><span class="token function">WriteAble</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                        _channel<span class="token punctuation">.</span><span class="token function">EnableWrite</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_out_buffer<span class="token punctuation">.</span><span class="token function">ReadAbleSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token function">Release</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//启动非活跃连接超时释放规则</span>
            <span class="token keyword">void</span> <span class="token function">EnableInactiveReleaseInLoop</span><span class="token punctuation">(</span><span class="token keyword">int</span> sec<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//1. 将判断标志 _enable_inactive_release 置为true</span>
                _enable_inactive_release <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
                <span class="token comment">//2. 如果当前定时销毁任务已经存在,那就刷新延迟一下即可</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_loop<span class="token operator">-></span><span class="token function">HasTimer</span><span class="token punctuation">(</span>_conn_id<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> _loop<span class="token operator">-></span><span class="token function">TimerRefresh</span><span class="token punctuation">(</span>_conn_id<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token comment">//3. 如果不存在定时销毁任务,则新增</span>
                _loop<span class="token operator">-></span><span class="token function">TimerAdd</span><span class="token punctuation">(</span>_conn_id<span class="token punctuation">,</span> sec<span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token operator">&</span>Connection<span class="token double-colon punctuation">::</span>Release<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">CancelInactiveReleaseInLoop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _enable_inactive_release <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_loop<span class="token operator">-></span><span class="token function">HasTimer</span><span class="token punctuation">(</span>_conn_id<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> 
                    _loop<span class="token operator">-></span><span class="token function">TimerCancel</span><span class="token punctuation">(</span>_conn_id<span class="token punctuation">)</span><span class="token punctuation">;</span> 
                <span class="token punctuation">}</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">UpgradeInLoop</span><span class="token punctuation">(</span><span class="token keyword">const</span> Any <span class="token operator">&</span>context<span class="token punctuation">,</span> 
                        <span class="token keyword">const</span> ConnectedCallback <span class="token operator">&</span>conn<span class="token punctuation">,</span> 
                        <span class="token keyword">const</span> MessageCallback <span class="token operator">&</span>msg<span class="token punctuation">,</span> 
                        <span class="token keyword">const</span> ClosedCallback <span class="token operator">&</span>closed<span class="token punctuation">,</span> 
                        <span class="token keyword">const</span> AnyEventCallback <span class="token operator">&</span>event<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _context <span class="token operator">=</span> context<span class="token punctuation">;</span>
                _connected_callback <span class="token operator">=</span> conn<span class="token punctuation">;</span>
                _message_callback <span class="token operator">=</span> msg<span class="token punctuation">;</span>
                _closed_callback <span class="token operator">=</span> closed<span class="token punctuation">;</span>
                _event_callback <span class="token operator">=</span> event<span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token keyword">public</span><span class="token operator">:</span>
            <span class="token function">Connection</span><span class="token punctuation">(</span>EventLoop <span class="token operator">*</span>loop<span class="token punctuation">,</span> <span class="token keyword">uint64_t</span> conn_id<span class="token punctuation">,</span> <span class="token keyword">int</span> sockfd<span class="token punctuation">)</span><span class="token operator">:</span><span class="token function">_conn_id</span><span class="token punctuation">(</span>conn_id<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">_sockfd</span><span class="token punctuation">(</span>sockfd<span class="token punctuation">)</span><span class="token punctuation">,</span>
                <span class="token function">_enable_inactive_release</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">_loop</span><span class="token punctuation">(</span>loop<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">_statu</span><span class="token punctuation">(</span>CONNECTING<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">_socket</span><span class="token punctuation">(</span>_sockfd<span class="token punctuation">)</span><span class="token punctuation">,</span>
                <span class="token function">_channel</span><span class="token punctuation">(</span>loop<span class="token punctuation">,</span> _sockfd<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _channel<span class="token punctuation">.</span><span class="token function">SetCloseCallback</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token operator">&</span>Connection<span class="token double-colon punctuation">::</span>HandleClose<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                _channel<span class="token punctuation">.</span><span class="token function">SetEventCallback</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token operator">&</span>Connection<span class="token double-colon punctuation">::</span>HandleEvent<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                _channel<span class="token punctuation">.</span><span class="token function">SetReadCallback</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token operator">&</span>Connection<span class="token double-colon punctuation">::</span>HandleRead<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                _channel<span class="token punctuation">.</span><span class="token function">SetWriteCallback</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token operator">&</span>Connection<span class="token double-colon punctuation">::</span>HandleWrite<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                _channel<span class="token punctuation">.</span><span class="token function">SetErrorCallback</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token operator">&</span>Connection<span class="token double-colon punctuation">::</span>HandleError<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token operator">~</span><span class="token function">Connection</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token function">DBG_LOG</span><span class="token punctuation">(</span><span class="token string">"RELEASE CONNECTION:%p"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token comment">//获取管理的文件描述符</span>
            <span class="token keyword">int</span> <span class="token function">Fd</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> _sockfd<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token comment">//获取连接ID</span>
            <span class="token keyword">int</span> <span class="token function">Id</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> _conn_id<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token comment">//是否处于CONNECTED状态</span>
            <span class="token keyword">bool</span> <span class="token function">Connected</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> <span class="token punctuation">(</span>_statu <span class="token operator">==</span> CONNECTED<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token comment">//设置上下文--连接建立完成时进行调用</span>
            <span class="token keyword">void</span> <span class="token function">SetContext</span><span class="token punctuation">(</span><span class="token keyword">const</span> Any <span class="token operator">&</span>context<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> _context <span class="token operator">=</span> context<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token comment">//获取上下文,返回的是指针</span>
            Any <span class="token operator">*</span><span class="token function">GetContext</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> <span class="token operator">&</span>_context<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">SetConnectedCallback</span><span class="token punctuation">(</span><span class="token keyword">const</span> ConnectedCallback<span class="token operator">&</span>cb<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> _connected_callback <span class="token operator">=</span> cb<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">SetMessageCallback</span><span class="token punctuation">(</span><span class="token keyword">const</span> MessageCallback<span class="token operator">&</span>cb<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> _message_callback <span class="token operator">=</span> cb<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">SetClosedCallback</span><span class="token punctuation">(</span><span class="token keyword">const</span> ClosedCallback<span class="token operator">&</span>cb<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> _closed_callback <span class="token operator">=</span> cb<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">SetAnyEventCallback</span><span class="token punctuation">(</span><span class="token keyword">const</span> AnyEventCallback<span class="token operator">&</span>cb<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> _event_callback <span class="token operator">=</span> cb<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">SetSrvClosedCallback</span><span class="token punctuation">(</span><span class="token keyword">const</span> ClosedCallback<span class="token operator">&</span>cb<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> _server_closed_callback <span class="token operator">=</span> cb<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token comment">//连接建立就绪后,进行channel回调设置,启动读监控,调用_connected_callback</span>
            <span class="token keyword">void</span> <span class="token function">Established</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _loop<span class="token operator">-></span><span class="token function">RunInLoop</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token operator">&</span>Connection<span class="token double-colon punctuation">::</span>EstablishedInLoop<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//发送数据,将数据放到发送缓冲区,启动写事件监控</span>
            <span class="token keyword">void</span> <span class="token function">Send</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>data<span class="token punctuation">,</span> size_t len<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token comment">//外界传入的data,可能是个临时的空间,我们现在只是把发送操作压入了任务池,有可能并没有被立即执行</span>
                <span class="token comment">//因此有可能执行的时候,data指向的空间有可能已经被释放了。</span>
                Buffer buf<span class="token punctuation">;</span>
                buf<span class="token punctuation">.</span><span class="token function">WriteAndPush</span><span class="token punctuation">(</span>data<span class="token punctuation">,</span> len<span class="token punctuation">)</span><span class="token punctuation">;</span>
                _loop<span class="token operator">-></span><span class="token function">RunInLoop</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token operator">&</span>Connection<span class="token double-colon punctuation">::</span>SendInLoop<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span><span class="token function">move</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//提供给组件使用者的关闭接口--并不实际关闭,需要判断有没有数据待处理</span>
            <span class="token keyword">void</span> <span class="token function">Shutdown</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _loop<span class="token operator">-></span><span class="token function">RunInLoop</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token operator">&</span>Connection<span class="token double-colon punctuation">::</span>ShutdownInLoop<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">Release</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _loop<span class="token operator">-></span><span class="token function">QueueInLoop</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token operator">&</span>Connection<span class="token double-colon punctuation">::</span>ReleaseInLoop<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//启动非活跃销毁,并定义多长时间无通信就是非活跃,添加定时任务</span>
            <span class="token keyword">void</span> <span class="token function">EnableInactiveRelease</span><span class="token punctuation">(</span><span class="token keyword">int</span> sec<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _loop<span class="token operator">-></span><span class="token function">RunInLoop</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token operator">&</span>Connection<span class="token double-colon punctuation">::</span>EnableInactiveReleaseInLoop<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">,</span> sec<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//取消非活跃销毁</span>
            <span class="token keyword">void</span> <span class="token function">CancelInactiveRelease</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _loop<span class="token operator">-></span><span class="token function">RunInLoop</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token operator">&</span>Connection<span class="token double-colon punctuation">::</span>CancelInactiveReleaseInLoop<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//切换协议---重置上下文以及阶段性回调处理函数 -- 而是这个接口必须在EventLoop线程中立即执行</span>
            <span class="token comment">//防备新的事件触发后,处理的时候,切换任务还没有被执行--会导致数据使用原协议处理了。</span>
            <span class="token keyword">void</span> <span class="token function">Upgrade</span><span class="token punctuation">(</span><span class="token keyword">const</span> Any <span class="token operator">&</span>context<span class="token punctuation">,</span> <span class="token keyword">const</span> ConnectedCallback <span class="token operator">&</span>conn<span class="token punctuation">,</span> <span class="token keyword">const</span> MessageCallback <span class="token operator">&</span>msg<span class="token punctuation">,</span> 
                         <span class="token keyword">const</span> ClosedCallback <span class="token operator">&</span>closed<span class="token punctuation">,</span> <span class="token keyword">const</span> AnyEventCallback <span class="token operator">&</span>event<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _loop<span class="token operator">-></span><span class="token function">AssertInLoop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                _loop<span class="token operator">-></span><span class="token function">RunInLoop</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token operator">&</span>Connection<span class="token double-colon punctuation">::</span>UpgradeInLoop<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">,</span> context<span class="token punctuation">,</span> conn<span class="token punctuation">,</span> msg<span class="token punctuation">,</span> closed<span class="token punctuation">,</span> event<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    
    <span class="token keyword">class</span> <span class="token class-name">Acceptor</span> <span class="token punctuation">{<!-- --></span>
        <span class="token keyword">private</span><span class="token operator">:</span>
            Socket _socket<span class="token punctuation">;</span><span class="token comment">//用于创建监听套接字</span>
            EventLoop <span class="token operator">*</span>_loop<span class="token punctuation">;</span> <span class="token comment">//用于对监听套接字进行事件监控</span>
            Channel _channel<span class="token punctuation">;</span> <span class="token comment">//用于对监听套接字进行事件管理</span>
    
            <span class="token keyword">using</span> AcceptCallback <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span>function<span class="token operator"><</span><span class="token keyword">void</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span><span class="token operator">></span><span class="token punctuation">;</span>
            AcceptCallback _accept_callback<span class="token punctuation">;</span>
        <span class="token keyword">private</span><span class="token operator">:</span>
            <span class="token comment">/*监听套接字的读事件回调处理函数---获取新连接,调用_accept_callback函数进行新连接处理*/</span>
            <span class="token keyword">void</span> <span class="token function">HandleRead</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">int</span> newfd <span class="token operator">=</span> _socket<span class="token punctuation">.</span><span class="token function">Accept</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>newfd <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token keyword">return</span> <span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_accept_callback<span class="token punctuation">)</span> <span class="token function">_accept_callback</span><span class="token punctuation">(</span>newfd<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">int</span> <span class="token function">CreateServer</span><span class="token punctuation">(</span><span class="token keyword">int</span> port<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">bool</span> ret <span class="token operator">=</span> _socket<span class="token punctuation">.</span><span class="token function">CreateServer</span><span class="token punctuation">(</span>port<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token function">assert</span><span class="token punctuation">(</span>ret <span class="token operator">==</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">return</span> _socket<span class="token punctuation">.</span><span class="token function">Fd</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token keyword">public</span><span class="token operator">:</span>
            <span class="token comment">/*不能将启动读事件监控,放到构造函数中,必须在设置回调函数后,再去启动*/</span>
            <span class="token comment">/*否则有可能造成启动监控后,立即有事件,处理的时候,回调函数还没设置:新连接得不到处理,且资源泄漏*/</span>
            <span class="token function">Acceptor</span><span class="token punctuation">(</span>EventLoop <span class="token operator">*</span>loop<span class="token punctuation">,</span> <span class="token keyword">int</span> port<span class="token punctuation">)</span><span class="token operator">:</span> <span class="token function">_socket</span><span class="token punctuation">(</span><span class="token function">CreateServer</span><span class="token punctuation">(</span>port<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">_loop</span><span class="token punctuation">(</span>loop<span class="token punctuation">)</span><span class="token punctuation">,</span> 
                <span class="token function">_channel</span><span class="token punctuation">(</span>loop<span class="token punctuation">,</span> _socket<span class="token punctuation">.</span><span class="token function">Fd</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _channel<span class="token punctuation">.</span><span class="token function">SetReadCallback</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token operator">&</span>Acceptor<span class="token double-colon punctuation">::</span>HandleRead<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">SetAcceptCallback</span><span class="token punctuation">(</span><span class="token keyword">const</span> AcceptCallback <span class="token operator">&</span>cb<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> _accept_callback <span class="token operator">=</span> cb<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">Listen</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> _channel<span class="token punctuation">.</span><span class="token function">EnableRead</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    
    <span class="token keyword">class</span> <span class="token class-name">TcpServer</span> <span class="token punctuation">{<!-- --></span>
        <span class="token keyword">private</span><span class="token operator">:</span>
            <span class="token keyword">uint64_t</span> _next_id<span class="token punctuation">;</span>      <span class="token comment">//这是一个自动增长的连接ID,</span>
            <span class="token keyword">int</span> _port<span class="token punctuation">;</span>
            <span class="token keyword">int</span> _timeout<span class="token punctuation">;</span>           <span class="token comment">//这是非活跃连接的统计时间---多长时间无通信就是非活跃连接</span>
            <span class="token keyword">bool</span> _enable_inactive_release<span class="token punctuation">;</span><span class="token comment">//是否启动了非活跃连接超时销毁的判断标志</span>
            EventLoop _baseloop<span class="token punctuation">;</span>    <span class="token comment">//这是主线程的EventLoop对象,负责监听事件的处理</span>
            Acceptor _acceptor<span class="token punctuation">;</span>    <span class="token comment">//这是监听套接字的管理对象</span>
            LoopThreadPool _pool<span class="token punctuation">;</span>   <span class="token comment">//这是从属EventLoop线程池</span>
            std<span class="token double-colon punctuation">::</span>unordered_map<span class="token operator"><</span><span class="token keyword">uint64_t</span><span class="token punctuation">,</span> PtrConnection<span class="token operator">></span> _conns<span class="token punctuation">;</span><span class="token comment">//保存管理所有连接对应的shared_ptr对象</span>
    
            <span class="token keyword">using</span> ConnectedCallback <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span>function<span class="token operator"><</span><span class="token keyword">void</span><span class="token punctuation">(</span><span class="token keyword">const</span> PtrConnection<span class="token operator">&</span><span class="token punctuation">)</span><span class="token operator">></span><span class="token punctuation">;</span>
            <span class="token keyword">using</span> MessageCallback <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span>function<span class="token operator"><</span><span class="token keyword">void</span><span class="token punctuation">(</span><span class="token keyword">const</span> PtrConnection<span class="token operator">&</span><span class="token punctuation">,</span> Buffer <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">></span><span class="token punctuation">;</span>
            <span class="token keyword">using</span> ClosedCallback <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span>function<span class="token operator"><</span><span class="token keyword">void</span><span class="token punctuation">(</span><span class="token keyword">const</span> PtrConnection<span class="token operator">&</span><span class="token punctuation">)</span><span class="token operator">></span><span class="token punctuation">;</span>
            <span class="token keyword">using</span> AnyEventCallback <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span>function<span class="token operator"><</span><span class="token keyword">void</span><span class="token punctuation">(</span><span class="token keyword">const</span> PtrConnection<span class="token operator">&</span><span class="token punctuation">)</span><span class="token operator">></span><span class="token punctuation">;</span>
            <span class="token keyword">using</span> Functor <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span>function<span class="token operator"><</span><span class="token keyword">void</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">></span><span class="token punctuation">;</span>
            ConnectedCallback _connected_callback<span class="token punctuation">;</span>
            MessageCallback _message_callback<span class="token punctuation">;</span>
            ClosedCallback _closed_callback<span class="token punctuation">;</span>
            AnyEventCallback _event_callback<span class="token punctuation">;</span>
        <span class="token keyword">private</span><span class="token operator">:</span>
            <span class="token keyword">void</span> <span class="token function">RunAfterInLoop</span><span class="token punctuation">(</span><span class="token keyword">const</span> Functor <span class="token operator">&</span>task<span class="token punctuation">,</span> <span class="token keyword">int</span> delay<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _next_id<span class="token operator">++</span><span class="token punctuation">;</span>
                _baseloop<span class="token punctuation">.</span><span class="token function">TimerAdd</span><span class="token punctuation">(</span>_next_id<span class="token punctuation">,</span> delay<span class="token punctuation">,</span> task<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//为新连接构造一个Connection进行管理</span>
            <span class="token keyword">void</span> <span class="token function">NewConnection</span><span class="token punctuation">(</span><span class="token keyword">int</span> fd<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _next_id<span class="token operator">++</span><span class="token punctuation">;</span>
                PtrConnection <span class="token function">conn</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token function">Connection</span><span class="token punctuation">(</span>_pool<span class="token punctuation">.</span><span class="token function">NextLoop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> _next_id<span class="token punctuation">,</span> fd<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                conn<span class="token operator">-></span><span class="token function">SetMessageCallback</span><span class="token punctuation">(</span>_message_callback<span class="token punctuation">)</span><span class="token punctuation">;</span>
                conn<span class="token operator">-></span><span class="token function">SetClosedCallback</span><span class="token punctuation">(</span>_closed_callback<span class="token punctuation">)</span><span class="token punctuation">;</span>
                conn<span class="token operator">-></span><span class="token function">SetConnectedCallback</span><span class="token punctuation">(</span>_connected_callback<span class="token punctuation">)</span><span class="token punctuation">;</span>
                conn<span class="token operator">-></span><span class="token function">SetAnyEventCallback</span><span class="token punctuation">(</span>_event_callback<span class="token punctuation">)</span><span class="token punctuation">;</span>
                conn<span class="token operator">-></span><span class="token function">SetSrvClosedCallback</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token operator">&</span>TcpServer<span class="token double-colon punctuation">::</span>RemoveConnection<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>placeholders<span class="token double-colon punctuation">::</span>_1<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>_enable_inactive_release<span class="token punctuation">)</span> conn<span class="token operator">-></span><span class="token function">EnableInactiveRelease</span><span class="token punctuation">(</span>_timeout<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//启动非活跃超时销毁</span>
                conn<span class="token operator">-></span><span class="token function">Established</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//就绪初始化</span>
                _conns<span class="token punctuation">.</span><span class="token function">insert</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">make_pair</span><span class="token punctuation">(</span>_next_id<span class="token punctuation">,</span> conn<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">RemoveConnectionInLoop</span><span class="token punctuation">(</span><span class="token keyword">const</span> PtrConnection <span class="token operator">&</span>conn<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token keyword">int</span> id <span class="token operator">=</span> conn<span class="token operator">-></span><span class="token function">Id</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">auto</span> it <span class="token operator">=</span> _conns<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>it <span class="token operator">!=</span> _conns<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                    _conns<span class="token punctuation">.</span><span class="token function">erase</span><span class="token punctuation">(</span>it<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//从管理Connection的_conns中移除连接信息</span>
            <span class="token keyword">void</span> <span class="token function">RemoveConnection</span><span class="token punctuation">(</span><span class="token keyword">const</span> PtrConnection <span class="token operator">&</span>conn<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _baseloop<span class="token punctuation">.</span><span class="token function">RunInLoop</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token operator">&</span>TcpServer<span class="token double-colon punctuation">::</span>RemoveConnectionInLoop<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">,</span> conn<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token keyword">public</span><span class="token operator">:</span>
            <span class="token function">TcpServer</span><span class="token punctuation">(</span><span class="token keyword">int</span> port<span class="token punctuation">)</span><span class="token operator">:</span>
                <span class="token function">_port</span><span class="token punctuation">(</span>port<span class="token punctuation">)</span><span class="token punctuation">,</span> 
                <span class="token function">_next_id</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span> 
                <span class="token function">_enable_inactive_release</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">,</span> 
                <span class="token function">_acceptor</span><span class="token punctuation">(</span><span class="token operator">&</span>_baseloop<span class="token punctuation">,</span> port<span class="token punctuation">)</span><span class="token punctuation">,</span>
                <span class="token function">_pool</span><span class="token punctuation">(</span><span class="token operator">&</span>_baseloop<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _acceptor<span class="token punctuation">.</span><span class="token function">SetAcceptCallback</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token operator">&</span>TcpServer<span class="token double-colon punctuation">::</span>NewConnection<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>placeholders<span class="token double-colon punctuation">::</span>_1<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                _acceptor<span class="token punctuation">.</span><span class="token function">Listen</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//将监听套接字挂到baseloop上</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">SetThreadCount</span><span class="token punctuation">(</span><span class="token keyword">int</span> count<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> _pool<span class="token punctuation">.</span><span class="token function">SetThreadCount</span><span class="token punctuation">(</span>count<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">SetConnectedCallback</span><span class="token punctuation">(</span><span class="token keyword">const</span> ConnectedCallback<span class="token operator">&</span>cb<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> _connected_callback <span class="token operator">=</span> cb<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">SetMessageCallback</span><span class="token punctuation">(</span><span class="token keyword">const</span> MessageCallback<span class="token operator">&</span>cb<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> _message_callback <span class="token operator">=</span> cb<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">SetClosedCallback</span><span class="token punctuation">(</span><span class="token keyword">const</span> ClosedCallback<span class="token operator">&</span>cb<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> _closed_callback <span class="token operator">=</span> cb<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">SetAnyEventCallback</span><span class="token punctuation">(</span><span class="token keyword">const</span> AnyEventCallback<span class="token operator">&</span>cb<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> _event_callback <span class="token operator">=</span> cb<span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">EnableInactiveRelease</span><span class="token punctuation">(</span><span class="token keyword">int</span> timeout<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> _timeout <span class="token operator">=</span> timeout<span class="token punctuation">;</span> _enable_inactive_release <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
            <span class="token comment">//用于添加一个定时任务</span>
            <span class="token keyword">void</span> <span class="token function">RunAfter</span><span class="token punctuation">(</span><span class="token keyword">const</span> Functor <span class="token operator">&</span>task<span class="token punctuation">,</span> <span class="token keyword">int</span> delay<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                _baseloop<span class="token punctuation">.</span><span class="token function">RunInLoop</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token operator">&</span>TcpServer<span class="token double-colon punctuation">::</span>RunAfterInLoop<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">,</span> task<span class="token punctuation">,</span> delay<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">void</span> <span class="token function">Start</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> _pool<span class="token punctuation">.</span><span class="token function">Create</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  _baseloop<span class="token punctuation">.</span><span class="token function">Start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    
    
    <span class="token keyword">void</span> <span class="token class-name">Channel</span><span class="token double-colon punctuation">::</span><span class="token function">Remove</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> _loop<span class="token operator">-></span><span class="token function">RemoveEvent</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
    <span class="token keyword">void</span> <span class="token class-name">Channel</span><span class="token double-colon punctuation">::</span><span class="token function">Update</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> _loop<span class="token operator">-></span><span class="token function">UpdateEvent</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
    <span class="token keyword">void</span> <span class="token class-name">TimerWheel</span><span class="token double-colon punctuation">::</span><span class="token function">TimerAdd</span><span class="token punctuation">(</span><span class="token keyword">uint64_t</span> id<span class="token punctuation">,</span> <span class="token keyword">uint32_t</span> delay<span class="token punctuation">,</span> <span class="token keyword">const</span> TaskFunc <span class="token operator">&</span>cb<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
        _loop<span class="token operator">-></span><span class="token function">RunInLoop</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token operator">&</span>TimerWheel<span class="token double-colon punctuation">::</span>TimerAddInLoop<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">,</span> id<span class="token punctuation">,</span> delay<span class="token punctuation">,</span> cb<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token comment">//刷新/延迟定时任务</span>
    <span class="token keyword">void</span> <span class="token class-name">TimerWheel</span><span class="token double-colon punctuation">::</span><span class="token function">TimerRefresh</span><span class="token punctuation">(</span><span class="token keyword">uint64_t</span> id<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
        _loop<span class="token operator">-></span><span class="token function">RunInLoop</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token operator">&</span>TimerWheel<span class="token double-colon punctuation">::</span>TimerRefreshInLoop<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">,</span> id<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">void</span> <span class="token class-name">TimerWheel</span><span class="token double-colon punctuation">::</span><span class="token function">TimerCancel</span><span class="token punctuation">(</span><span class="token keyword">uint64_t</span> id<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
        _loop<span class="token operator">-></span><span class="token function">RunInLoop</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token operator">&</span>TimerWheel<span class="token double-colon punctuation">::</span>TimerCancelInLoop<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">,</span> id<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    
    
    <span class="token keyword">class</span> <span class="token class-name">NetWork</span> <span class="token punctuation">{<!-- --></span>
        <span class="token keyword">public</span><span class="token operator">:</span>
            <span class="token function">NetWork</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
                <span class="token function">DBG_LOG</span><span class="token punctuation">(</span><span class="token string">"SIGPIPE INIT"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token function">signal</span><span class="token punctuation">(</span>SIGPIPE<span class="token punctuation">,</span> SIG_IGN<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token keyword">static</span> NetWork nw<span class="token punctuation">;</span>
    <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li><li style="color: rgb(153, 153, 153);">39</li><li style="color: rgb(153, 153, 153);">40</li><li style="color: rgb(153, 153, 153);">41</li><li style="color: rgb(153, 153, 153);">42</li><li style="color: rgb(153, 153, 153);">43</li><li style="color: rgb(153, 153, 153);">44</li><li style="color: rgb(153, 153, 153);">45</li><li style="color: rgb(153, 153, 153);">46</li><li style="color: rgb(153, 153, 153);">47</li><li style="color: rgb(153, 153, 153);">48</li><li style="color: rgb(153, 153, 153);">49</li><li style="color: rgb(153, 153, 153);">50</li><li style="color: rgb(153, 153, 153);">51</li><li style="color: rgb(153, 153, 153);">52</li><li style="color: rgb(153, 153, 153);">53</li><li style="color: rgb(153, 153, 153);">54</li><li style="color: rgb(153, 153, 153);">55</li><li style="color: rgb(153, 153, 153);">56</li><li style="color: rgb(153, 153, 153);">57</li><li style="color: rgb(153, 153, 153);">58</li><li style="color: rgb(153, 153, 153);">59</li><li style="color: rgb(153, 153, 153);">60</li><li style="color: rgb(153, 153, 153);">61</li><li style="color: rgb(153, 153, 153);">62</li><li style="color: rgb(153, 153, 153);">63</li><li style="color: rgb(153, 153, 153);">64</li><li style="color: rgb(153, 153, 153);">65</li><li style="color: rgb(153, 153, 153);">66</li><li style="color: rgb(153, 153, 153);">67</li><li style="color: rgb(153, 153, 153);">68</li><li style="color: rgb(153, 153, 153);">69</li><li style="color: rgb(153, 153, 153);">70</li><li style="color: rgb(153, 153, 153);">71</li><li style="color: rgb(153, 153, 153);">72</li><li style="color: rgb(153, 153, 153);">73</li><li style="color: rgb(153, 153, 153);">74</li><li style="color: rgb(153, 153, 153);">75</li><li style="color: rgb(153, 153, 153);">76</li><li style="color: rgb(153, 153, 153);">77</li><li style="color: rgb(153, 153, 153);">78</li><li style="color: rgb(153, 153, 153);">79</li><li style="color: rgb(153, 153, 153);">80</li><li style="color: rgb(153, 153, 153);">81</li><li style="color: rgb(153, 153, 153);">82</li><li style="color: rgb(153, 153, 153);">83</li><li style="color: rgb(153, 153, 153);">84</li><li style="color: rgb(153, 153, 153);">85</li><li style="color: rgb(153, 153, 153);">86</li><li style="color: rgb(153, 153, 153);">87</li><li style="color: rgb(153, 153, 153);">88</li><li style="color: rgb(153, 153, 153);">89</li><li style="color: rgb(153, 153, 153);">90</li><li style="color: rgb(153, 153, 153);">91</li><li style="color: rgb(153, 153, 153);">92</li><li style="color: rgb(153, 153, 153);">93</li><li style="color: rgb(153, 153, 153);">94</li><li style="color: rgb(153, 153, 153);">95</li><li style="color: rgb(153, 153, 153);">96</li><li style="color: rgb(153, 153, 153);">97</li><li style="color: rgb(153, 153, 153);">98</li><li style="color: rgb(153, 153, 153);">99</li><li style="color: rgb(153, 153, 153);">100</li><li style="color: rgb(153, 153, 153);">101</li><li style="color: rgb(153, 153, 153);">102</li><li style="color: rgb(153, 153, 153);">103</li><li style="color: rgb(153, 153, 153);">104</li><li style="color: rgb(153, 153, 153);">105</li><li style="color: rgb(153, 153, 153);">106</li><li style="color: rgb(153, 153, 153);">107</li><li style="color: rgb(153, 153, 153);">108</li><li style="color: rgb(153, 153, 153);">109</li><li style="color: rgb(153, 153, 153);">110</li><li style="color: rgb(153, 153, 153);">111</li><li style="color: rgb(153, 153, 153);">112</li><li style="color: rgb(153, 153, 153);">113</li><li style="color: rgb(153, 153, 153);">114</li><li style="color: rgb(153, 153, 153);">115</li><li style="color: rgb(153, 153, 153);">116</li><li style="color: rgb(153, 153, 153);">117</li><li style="color: rgb(153, 153, 153);">118</li><li style="color: rgb(153, 153, 153);">119</li><li style="color: rgb(153, 153, 153);">120</li><li style="color: rgb(153, 153, 153);">121</li><li style="color: rgb(153, 153, 153);">122</li><li style="color: rgb(153, 153, 153);">123</li><li style="color: rgb(153, 153, 153);">124</li><li style="color: rgb(153, 153, 153);">125</li><li style="color: rgb(153, 153, 153);">126</li><li style="color: rgb(153, 153, 153);">127</li><li style="color: rgb(153, 153, 153);">128</li><li style="color: rgb(153, 153, 153);">129</li><li style="color: rgb(153, 153, 153);">130</li><li style="color: rgb(153, 153, 153);">131</li><li style="color: rgb(153, 153, 153);">132</li><li style="color: rgb(153, 153, 153);">133</li><li style="color: rgb(153, 153, 153);">134</li><li style="color: rgb(153, 153, 153);">135</li><li style="color: rgb(153, 153, 153);">136</li><li style="color: rgb(153, 153, 153);">137</li><li style="color: rgb(153, 153, 153);">138</li><li style="color: rgb(153, 153, 153);">139</li><li style="color: rgb(153, 153, 153);">140</li><li style="color: rgb(153, 153, 153);">141</li><li style="color: rgb(153, 153, 153);">142</li><li style="color: rgb(153, 153, 153);">143</li><li style="color: rgb(153, 153, 153);">144</li><li style="color: rgb(153, 153, 153);">145</li><li style="color: rgb(153, 153, 153);">146</li><li style="color: rgb(153, 153, 153);">147</li><li style="color: rgb(153, 153, 153);">148</li><li style="color: rgb(153, 153, 153);">149</li><li style="color: rgb(153, 153, 153);">150</li><li style="color: rgb(153, 153, 153);">151</li><li style="color: rgb(153, 153, 153);">152</li><li style="color: rgb(153, 153, 153);">153</li><li style="color: rgb(153, 153, 153);">154</li><li style="color: rgb(153, 153, 153);">155</li><li style="color: rgb(153, 153, 153);">156</li><li style="color: rgb(153, 153, 153);">157</li><li style="color: rgb(153, 153, 153);">158</li><li style="color: rgb(153, 153, 153);">159</li><li style="color: rgb(153, 153, 153);">160</li><li style="color: rgb(153, 153, 153);">161</li><li style="color: rgb(153, 153, 153);">162</li><li style="color: rgb(153, 153, 153);">163</li><li style="color: rgb(153, 153, 153);">164</li><li style="color: rgb(153, 153, 153);">165</li><li style="color: rgb(153, 153, 153);">166</li><li style="color: rgb(153, 153, 153);">167</li><li style="color: rgb(153, 153, 153);">168</li><li style="color: rgb(153, 153, 153);">169</li><li style="color: rgb(153, 153, 153);">170</li><li style="color: rgb(153, 153, 153);">171</li><li style="color: rgb(153, 153, 153);">172</li><li style="color: rgb(153, 153, 153);">173</li><li style="color: rgb(153, 153, 153);">174</li><li style="color: rgb(153, 153, 153);">175</li><li style="color: rgb(153, 153, 153);">176</li><li style="color: rgb(153, 153, 153);">177</li><li style="color: rgb(153, 153, 153);">178</li><li style="color: rgb(153, 153, 153);">179</li><li style="color: rgb(153, 153, 153);">180</li><li style="color: rgb(153, 153, 153);">181</li><li style="color: rgb(153, 153, 153);">182</li><li style="color: rgb(153, 153, 153);">183</li><li style="color: rgb(153, 153, 153);">184</li><li style="color: rgb(153, 153, 153);">185</li><li style="color: rgb(153, 153, 153);">186</li><li style="color: rgb(153, 153, 153);">187</li><li style="color: rgb(153, 153, 153);">188</li><li style="color: rgb(153, 153, 153);">189</li><li style="color: rgb(153, 153, 153);">190</li><li style="color: rgb(153, 153, 153);">191</li><li style="color: rgb(153, 153, 153);">192</li><li style="color: rgb(153, 153, 153);">193</li><li style="color: rgb(153, 153, 153);">194</li><li style="color: rgb(153, 153, 153);">195</li><li style="color: rgb(153, 153, 153);">196</li><li style="color: rgb(153, 153, 153);">197</li><li style="color: rgb(153, 153, 153);">198</li><li style="color: rgb(153, 153, 153);">199</li><li style="color: rgb(153, 153, 153);">200</li><li style="color: rgb(153, 153, 153);">201</li><li style="color: rgb(153, 153, 153);">202</li><li style="color: rgb(153, 153, 153);">203</li><li style="color: rgb(153, 153, 153);">204</li><li style="color: rgb(153, 153, 153);">205</li><li style="color: rgb(153, 153, 153);">206</li><li style="color: rgb(153, 153, 153);">207</li><li style="color: rgb(153, 153, 153);">208</li><li style="color: rgb(153, 153, 153);">209</li><li style="color: rgb(153, 153, 153);">210</li><li style="color: rgb(153, 153, 153);">211</li><li style="color: rgb(153, 153, 153);">212</li><li style="color: rgb(153, 153, 153);">213</li><li style="color: rgb(153, 153, 153);">214</li><li style="color: rgb(153, 153, 153);">215</li><li style="color: rgb(153, 153, 153);">216</li><li style="color: rgb(153, 153, 153);">217</li><li style="color: rgb(153, 153, 153);">218</li><li style="color: rgb(153, 153, 153);">219</li><li style="color: rgb(153, 153, 153);">220</li><li style="color: rgb(153, 153, 153);">221</li><li style="color: rgb(153, 153, 153);">222</li><li style="color: rgb(153, 153, 153);">223</li><li style="color: rgb(153, 153, 153);">224</li><li style="color: rgb(153, 153, 153);">225</li><li style="color: rgb(153, 153, 153);">226</li><li style="color: rgb(153, 153, 153);">227</li><li style="color: rgb(153, 153, 153);">228</li><li style="color: rgb(153, 153, 153);">229</li><li style="color: rgb(153, 153, 153);">230</li><li style="color: rgb(153, 153, 153);">231</li><li style="color: rgb(153, 153, 153);">232</li><li style="color: rgb(153, 153, 153);">233</li><li style="color: rgb(153, 153, 153);">234</li><li style="color: rgb(153, 153, 153);">235</li><li style="color: rgb(153, 153, 153);">236</li><li style="color: rgb(153, 153, 153);">237</li><li style="color: rgb(153, 153, 153);">238</li><li style="color: rgb(153, 153, 153);">239</li><li style="color: rgb(153, 153, 153);">240</li><li style="color: rgb(153, 153, 153);">241</li><li style="color: rgb(153, 153, 153);">242</li><li style="color: rgb(153, 153, 153);">243</li><li style="color: rgb(153, 153, 153);">244</li><li style="color: rgb(153, 153, 153);">245</li><li style="color: rgb(153, 153, 153);">246</li><li style="color: rgb(153, 153, 153);">247</li><li style="color: rgb(153, 153, 153);">248</li><li style="color: rgb(153, 153, 153);">249</li><li style="color: rgb(153, 153, 153);">250</li><li style="color: rgb(153, 153, 153);">251</li><li style="color: rgb(153, 153, 153);">252</li><li style="color: rgb(153, 153, 153);">253</li><li style="color: rgb(153, 153, 153);">254</li><li style="color: rgb(153, 153, 153);">255</li><li style="color: rgb(153, 153, 153);">256</li><li style="color: rgb(153, 153, 153);">257</li><li style="color: rgb(153, 153, 153);">258</li><li style="color: rgb(153, 153, 153);">259</li><li style="color: rgb(153, 153, 153);">260</li><li style="color: rgb(153, 153, 153);">261</li><li style="color: rgb(153, 153, 153);">262</li><li style="color: rgb(153, 153, 153);">263</li><li style="color: rgb(153, 153, 153);">264</li><li style="color: rgb(153, 153, 153);">265</li><li style="color: rgb(153, 153, 153);">266</li><li style="color: rgb(153, 153, 153);">267</li><li style="color: rgb(153, 153, 153);">268</li><li style="color: rgb(153, 153, 153);">269</li><li style="color: rgb(153, 153, 153);">270</li><li style="color: rgb(153, 153, 153);">271</li><li style="color: rgb(153, 153, 153);">272</li><li style="color: rgb(153, 153, 153);">273</li><li style="color: rgb(153, 153, 153);">274</li><li style="color: rgb(153, 153, 153);">275</li><li style="color: rgb(153, 153, 153);">276</li><li style="color: rgb(153, 153, 153);">277</li><li style="color: rgb(153, 153, 153);">278</li><li style="color: rgb(153, 153, 153);">279</li><li style="color: rgb(153, 153, 153);">280</li><li style="color: rgb(153, 153, 153);">281</li><li style="color: rgb(153, 153, 153);">282</li><li style="color: rgb(153, 153, 153);">283</li><li style="color: rgb(153, 153, 153);">284</li><li style="color: rgb(153, 153, 153);">285</li><li style="color: rgb(153, 153, 153);">286</li><li style="color: rgb(153, 153, 153);">287</li><li style="color: rgb(153, 153, 153);">288</li><li style="color: rgb(153, 153, 153);">289</li><li style="color: rgb(153, 153, 153);">290</li><li style="color: rgb(153, 153, 153);">291</li><li style="color: rgb(153, 153, 153);">292</li><li style="color: rgb(153, 153, 153);">293</li><li style="color: rgb(153, 153, 153);">294</li><li style="color: rgb(153, 153, 153);">295</li><li style="color: rgb(153, 153, 153);">296</li><li style="color: rgb(153, 153, 153);">297</li><li style="color: rgb(153, 153, 153);">298</li><li style="color: rgb(153, 153, 153);">299</li><li style="color: rgb(153, 153, 153);">300</li><li style="color: rgb(153, 153, 153);">301</li><li style="color: rgb(153, 153, 153);">302</li><li style="color: rgb(153, 153, 153);">303</li><li style="color: rgb(153, 153, 153);">304</li><li style="color: rgb(153, 153, 153);">305</li><li style="color: rgb(153, 153, 153);">306</li><li style="color: rgb(153, 153, 153);">307</li><li style="color: rgb(153, 153, 153);">308</li><li style="color: rgb(153, 153, 153);">309</li><li style="color: rgb(153, 153, 153);">310</li><li style="color: rgb(153, 153, 153);">311</li><li style="color: rgb(153, 153, 153);">312</li><li style="color: rgb(153, 153, 153);">313</li><li style="color: rgb(153, 153, 153);">314</li><li style="color: rgb(153, 153, 153);">315</li><li style="color: rgb(153, 153, 153);">316</li><li style="color: rgb(153, 153, 153);">317</li><li style="color: rgb(153, 153, 153);">318</li><li style="color: rgb(153, 153, 153);">319</li><li style="color: rgb(153, 153, 153);">320</li><li style="color: rgb(153, 153, 153);">321</li><li style="color: rgb(153, 153, 153);">322</li><li style="color: rgb(153, 153, 153);">323</li><li style="color: rgb(153, 153, 153);">324</li><li style="color: rgb(153, 153, 153);">325</li><li style="color: rgb(153, 153, 153);">326</li><li style="color: rgb(153, 153, 153);">327</li><li style="color: rgb(153, 153, 153);">328</li><li style="color: rgb(153, 153, 153);">329</li><li style="color: rgb(153, 153, 153);">330</li><li style="color: rgb(153, 153, 153);">331</li><li style="color: rgb(153, 153, 153);">332</li><li style="color: rgb(153, 153, 153);">333</li><li style="color: rgb(153, 153, 153);">334</li><li style="color: rgb(153, 153, 153);">335</li><li style="color: rgb(153, 153, 153);">336</li><li style="color: rgb(153, 153, 153);">337</li><li style="color: rgb(153, 153, 153);">338</li><li style="color: rgb(153, 153, 153);">339</li><li style="color: rgb(153, 153, 153);">340</li><li style="color: rgb(153, 153, 153);">341</li><li style="color: rgb(153, 153, 153);">342</li><li style="color: rgb(153, 153, 153);">343</li><li style="color: rgb(153, 153, 153);">344</li><li style="color: rgb(153, 153, 153);">345</li><li style="color: rgb(153, 153, 153);">346</li><li style="color: rgb(153, 153, 153);">347</li><li style="color: rgb(153, 153, 153);">348</li><li style="color: rgb(153, 153, 153);">349</li><li style="color: rgb(153, 153, 153);">350</li><li style="color: rgb(153, 153, 153);">351</li><li style="color: rgb(153, 153, 153);">352</li><li style="color: rgb(153, 153, 153);">353</li><li style="color: rgb(153, 153, 153);">354</li><li style="color: rgb(153, 153, 153);">355</li><li style="color: rgb(153, 153, 153);">356</li><li style="color: rgb(153, 153, 153);">357</li><li style="color: rgb(153, 153, 153);">358</li><li style="color: rgb(153, 153, 153);">359</li><li style="color: rgb(153, 153, 153);">360</li><li style="color: rgb(153, 153, 153);">361</li><li style="color: rgb(153, 153, 153);">362</li><li style="color: rgb(153, 153, 153);">363</li><li style="color: rgb(153, 153, 153);">364</li><li style="color: rgb(153, 153, 153);">365</li><li style="color: rgb(153, 153, 153);">366</li><li style="color: rgb(153, 153, 153);">367</li><li style="color: rgb(153, 153, 153);">368</li><li style="color: rgb(153, 153, 153);">369</li><li style="color: rgb(153, 153, 153);">370</li><li style="color: rgb(153, 153, 153);">371</li><li style="color: rgb(153, 153, 153);">372</li><li style="color: rgb(153, 153, 153);">373</li><li style="color: rgb(153, 153, 153);">374</li><li style="color: rgb(153, 153, 153);">375</li><li style="color: rgb(153, 153, 153);">376</li><li style="color: rgb(153, 153, 153);">377</li><li style="color: rgb(153, 153, 153);">378</li><li style="color: rgb(153, 153, 153);">379</li><li style="color: rgb(153, 153, 153);">380</li><li style="color: rgb(153, 153, 153);">381</li><li style="color: rgb(153, 153, 153);">382</li><li style="color: rgb(153, 153, 153);">383</li><li style="color: rgb(153, 153, 153);">384</li><li style="color: rgb(153, 153, 153);">385</li><li style="color: rgb(153, 153, 153);">386</li><li style="color: rgb(153, 153, 153);">387</li><li style="color: rgb(153, 153, 153);">388</li><li style="color: rgb(153, 153, 153);">389</li><li style="color: rgb(153, 153, 153);">390</li><li style="color: rgb(153, 153, 153);">391</li><li style="color: rgb(153, 153, 153);">392</li><li style="color: rgb(153, 153, 153);">393</li><li style="color: rgb(153, 153, 153);">394</li><li style="color: rgb(153, 153, 153);">395</li><li style="color: rgb(153, 153, 153);">396</li><li style="color: rgb(153, 153, 153);">397</li><li style="color: rgb(153, 153, 153);">398</li><li style="color: rgb(153, 153, 153);">399</li><li style="color: rgb(153, 153, 153);">400</li><li style="color: rgb(153, 153, 153);">401</li><li style="color: rgb(153, 153, 153);">402</li><li style="color: rgb(153, 153, 153);">403</li><li style="color: rgb(153, 153, 153);">404</li><li style="color: rgb(153, 153, 153);">405</li><li style="color: rgb(153, 153, 153);">406</li><li style="color: rgb(153, 153, 153);">407</li><li style="color: rgb(153, 153, 153);">408</li><li style="color: rgb(153, 153, 153);">409</li><li style="color: rgb(153, 153, 153);">410</li><li style="color: rgb(153, 153, 153);">411</li><li style="color: rgb(153, 153, 153);">412</li><li style="color: rgb(153, 153, 153);">413</li><li style="color: rgb(153, 153, 153);">414</li><li style="color: rgb(153, 153, 153);">415</li><li style="color: rgb(153, 153, 153);">416</li><li style="color: rgb(153, 153, 153);">417</li><li style="color: rgb(153, 153, 153);">418</li><li style="color: rgb(153, 153, 153);">419</li><li style="color: rgb(153, 153, 153);">420</li><li style="color: rgb(153, 153, 153);">421</li><li style="color: rgb(153, 153, 153);">422</li><li style="color: rgb(153, 153, 153);">423</li><li style="color: rgb(153, 153, 153);">424</li><li style="color: rgb(153, 153, 153);">425</li><li style="color: rgb(153, 153, 153);">426</li><li style="color: rgb(153, 153, 153);">427</li><li style="color: rgb(153, 153, 153);">428</li><li style="color: rgb(153, 153, 153);">429</li><li style="color: rgb(153, 153, 153);">430</li><li style="color: rgb(153, 153, 153);">431</li><li style="color: rgb(153, 153, 153);">432</li><li style="color: rgb(153, 153, 153);">433</li><li style="color: rgb(153, 153, 153);">434</li><li style="color: rgb(153, 153, 153);">435</li><li style="color: rgb(153, 153, 153);">436</li><li style="color: rgb(153, 153, 153);">437</li><li style="color: rgb(153, 153, 153);">438</li><li style="color: rgb(153, 153, 153);">439</li><li style="color: rgb(153, 153, 153);">440</li><li style="color: rgb(153, 153, 153);">441</li><li style="color: rgb(153, 153, 153);">442</li><li style="color: rgb(153, 153, 153);">443</li><li style="color: rgb(153, 153, 153);">444</li><li style="color: rgb(153, 153, 153);">445</li><li style="color: rgb(153, 153, 153);">446</li><li style="color: rgb(153, 153, 153);">447</li><li style="color: rgb(153, 153, 153);">448</li><li style="color: rgb(153, 153, 153);">449</li><li style="color: rgb(153, 153, 153);">450</li><li style="color: rgb(153, 153, 153);">451</li><li style="color: rgb(153, 153, 153);">452</li><li style="color: rgb(153, 153, 153);">453</li><li style="color: rgb(153, 153, 153);">454</li><li style="color: rgb(153, 153, 153);">455</li><li style="color: rgb(153, 153, 153);">456</li><li style="color: rgb(153, 153, 153);">457</li><li style="color: rgb(153, 153, 153);">458</li><li style="color: rgb(153, 153, 153);">459</li><li style="color: rgb(153, 153, 153);">460</li><li style="color: rgb(153, 153, 153);">461</li><li style="color: rgb(153, 153, 153);">462</li><li style="color: rgb(153, 153, 153);">463</li><li style="color: rgb(153, 153, 153);">464</li><li style="color: rgb(153, 153, 153);">465</li><li style="color: rgb(153, 153, 153);">466</li><li style="color: rgb(153, 153, 153);">467</li><li style="color: rgb(153, 153, 153);">468</li><li style="color: rgb(153, 153, 153);">469</li><li style="color: rgb(153, 153, 153);">470</li><li style="color: rgb(153, 153, 153);">471</li><li style="color: rgb(153, 153, 153);">472</li><li style="color: rgb(153, 153, 153);">473</li><li style="color: rgb(153, 153, 153);">474</li><li style="color: rgb(153, 153, 153);">475</li><li style="color: rgb(153, 153, 153);">476</li><li style="color: rgb(153, 153, 153);">477</li><li style="color: rgb(153, 153, 153);">478</li><li style="color: rgb(153, 153, 153);">479</li><li style="color: rgb(153, 153, 153);">480</li><li style="color: rgb(153, 153, 153);">481</li><li style="color: rgb(153, 153, 153);">482</li><li style="color: rgb(153, 153, 153);">483</li><li style="color: rgb(153, 153, 153);">484</li><li style="color: rgb(153, 153, 153);">485</li><li style="color: rgb(153, 153, 153);">486</li><li style="color: rgb(153, 153, 153);">487</li><li style="color: rgb(153, 153, 153);">488</li><li style="color: rgb(153, 153, 153);">489</li><li style="color: rgb(153, 153, 153);">490</li><li style="color: rgb(153, 153, 153);">491</li><li style="color: rgb(153, 153, 153);">492</li><li style="color: rgb(153, 153, 153);">493</li><li style="color: rgb(153, 153, 153);">494</li><li style="color: rgb(153, 153, 153);">495</li><li style="color: rgb(153, 153, 153);">496</li><li style="color: rgb(153, 153, 153);">497</li><li style="color: rgb(153, 153, 153);">498</li><li style="color: rgb(153, 153, 153);">499</li><li style="color: rgb(153, 153, 153);">500</li><li style="color: rgb(153, 153, 153);">501</li><li style="color: rgb(153, 153, 153);">502</li><li style="color: rgb(153, 153, 153);">503</li><li style="color: rgb(153, 153, 153);">504</li><li style="color: rgb(153, 153, 153);">505</li><li style="color: rgb(153, 153, 153);">506</li><li style="color: rgb(153, 153, 153);">507</li><li style="color: rgb(153, 153, 153);">508</li><li style="color: rgb(153, 153, 153);">509</li><li style="color: rgb(153, 153, 153);">510</li><li style="color: rgb(153, 153, 153);">511</li><li style="color: rgb(153, 153, 153);">512</li><li style="color: rgb(153, 153, 153);">513</li><li style="color: rgb(153, 153, 153);">514</li><li style="color: rgb(153, 153, 153);">515</li><li style="color: rgb(153, 153, 153);">516</li><li style="color: rgb(153, 153, 153);">517</li><li style="color: rgb(153, 153, 153);">518</li><li style="color: rgb(153, 153, 153);">519</li><li style="color: rgb(153, 153, 153);">520</li><li style="color: rgb(153, 153, 153);">521</li><li style="color: rgb(153, 153, 153);">522</li><li style="color: rgb(153, 153, 153);">523</li><li style="color: rgb(153, 153, 153);">524</li><li style="color: rgb(153, 153, 153);">525</li><li style="color: rgb(153, 153, 153);">526</li><li style="color: rgb(153, 153, 153);">527</li><li style="color: rgb(153, 153, 153);">528</li><li style="color: rgb(153, 153, 153);">529</li><li style="color: rgb(153, 153, 153);">530</li><li style="color: rgb(153, 153, 153);">531</li><li style="color: rgb(153, 153, 153);">532</li><li style="color: rgb(153, 153, 153);">533</li><li style="color: rgb(153, 153, 153);">534</li><li style="color: rgb(153, 153, 153);">535</li><li style="color: rgb(153, 153, 153);">536</li><li style="color: rgb(153, 153, 153);">537</li><li style="color: rgb(153, 153, 153);">538</li><li style="color: rgb(153, 153, 153);">539</li><li style="color: rgb(153, 153, 153);">540</li><li style="color: rgb(153, 153, 153);">541</li><li style="color: rgb(153, 153, 153);">542</li><li style="color: rgb(153, 153, 153);">543</li><li style="color: rgb(153, 153, 153);">544</li><li style="color: rgb(153, 153, 153);">545</li><li style="color: rgb(153, 153, 153);">546</li><li style="color: rgb(153, 153, 153);">547</li><li style="color: rgb(153, 153, 153);">548</li><li style="color: rgb(153, 153, 153);">549</li><li style="color: rgb(153, 153, 153);">550</li><li style="color: rgb(153, 153, 153);">551</li><li style="color: rgb(153, 153, 153);">552</li><li style="color: rgb(153, 153, 153);">553</li><li style="color: rgb(153, 153, 153);">554</li><li style="color: rgb(153, 153, 153);">555</li><li style="color: rgb(153, 153, 153);">556</li><li style="color: rgb(153, 153, 153);">557</li><li style="color: rgb(153, 153, 153);">558</li><li style="color: rgb(153, 153, 153);">559</li><li style="color: rgb(153, 153, 153);">560</li><li style="color: rgb(153, 153, 153);">561</li><li style="color: rgb(153, 153, 153);">562</li><li style="color: rgb(153, 153, 153);">563</li><li style="color: rgb(153, 153, 153);">564</li><li style="color: rgb(153, 153, 153);">565</li><li style="color: rgb(153, 153, 153);">566</li><li style="color: rgb(153, 153, 153);">567</li><li style="color: rgb(153, 153, 153);">568</li><li style="color: rgb(153, 153, 153);">569</li><li style="color: rgb(153, 153, 153);">570</li><li style="color: rgb(153, 153, 153);">571</li><li style="color: rgb(153, 153, 153);">572</li><li style="color: rgb(153, 153, 153);">573</li><li style="color: rgb(153, 153, 153);">574</li><li style="color: rgb(153, 153, 153);">575</li><li style="color: rgb(153, 153, 153);">576</li><li style="color: rgb(153, 153, 153);">577</li><li style="color: rgb(153, 153, 153);">578</li><li style="color: rgb(153, 153, 153);">579</li><li style="color: rgb(153, 153, 153);">580</li><li style="color: rgb(153, 153, 153);">581</li><li style="color: rgb(153, 153, 153);">582</li><li style="color: rgb(153, 153, 153);">583</li><li style="color: rgb(153, 153, 153);">584</li><li style="color: rgb(153, 153, 153);">585</li><li style="color: rgb(153, 153, 153);">586</li><li style="color: rgb(153, 153, 153);">587</li><li style="color: rgb(153, 153, 153);">588</li><li style="color: rgb(153, 153, 153);">589</li><li style="color: rgb(153, 153, 153);">590</li><li style="color: rgb(153, 153, 153);">591</li><li style="color: rgb(153, 153, 153);">592</li><li style="color: rgb(153, 153, 153);">593</li><li style="color: rgb(153, 153, 153);">594</li><li style="color: rgb(153, 153, 153);">595</li><li style="color: rgb(153, 153, 153);">596</li><li style="color: rgb(153, 153, 153);">597</li><li style="color: rgb(153, 153, 153);">598</li><li style="color: rgb(153, 153, 153);">599</li><li style="color: rgb(153, 153, 153);">600</li><li style="color: rgb(153, 153, 153);">601</li><li style="color: rgb(153, 153, 153);">602</li><li style="color: rgb(153, 153, 153);">603</li><li style="color: rgb(153, 153, 153);">604</li><li style="color: rgb(153, 153, 153);">605</li><li style="color: rgb(153, 153, 153);">606</li><li style="color: rgb(153, 153, 153);">607</li><li style="color: rgb(153, 153, 153);">608</li><li style="color: rgb(153, 153, 153);">609</li><li style="color: rgb(153, 153, 153);">610</li><li style="color: rgb(153, 153, 153);">611</li><li style="color: rgb(153, 153, 153);">612</li><li style="color: rgb(153, 153, 153);">613</li><li style="color: rgb(153, 153, 153);">614</li><li style="color: rgb(153, 153, 153);">615</li><li style="color: rgb(153, 153, 153);">616</li><li style="color: rgb(153, 153, 153);">617</li><li style="color: rgb(153, 153, 153);">618</li><li style="color: rgb(153, 153, 153);">619</li><li style="color: rgb(153, 153, 153);">620</li><li style="color: rgb(153, 153, 153);">621</li><li style="color: rgb(153, 153, 153);">622</li><li style="color: rgb(153, 153, 153);">623</li><li style="color: rgb(153, 153, 153);">624</li><li style="color: rgb(153, 153, 153);">625</li><li style="color: rgb(153, 153, 153);">626</li><li style="color: rgb(153, 153, 153);">627</li><li style="color: rgb(153, 153, 153);">628</li><li style="color: rgb(153, 153, 153);">629</li><li style="color: rgb(153, 153, 153);">630</li><li style="color: rgb(153, 153, 153);">631</li><li style="color: rgb(153, 153, 153);">632</li><li style="color: rgb(153, 153, 153);">633</li><li style="color: rgb(153, 153, 153);">634</li><li style="color: rgb(153, 153, 153);">635</li><li style="color: rgb(153, 153, 153);">636</li><li style="color: rgb(153, 153, 153);">637</li><li style="color: rgb(153, 153, 153);">638</li><li style="color: rgb(153, 153, 153);">639</li><li style="color: rgb(153, 153, 153);">640</li><li style="color: rgb(153, 153, 153);">641</li><li style="color: rgb(153, 153, 153);">642</li><li style="color: rgb(153, 153, 153);">643</li><li style="color: rgb(153, 153, 153);">644</li><li style="color: rgb(153, 153, 153);">645</li><li style="color: rgb(153, 153, 153);">646</li><li style="color: rgb(153, 153, 153);">647</li><li style="color: rgb(153, 153, 153);">648</li><li style="color: rgb(153, 153, 153);">649</li><li style="color: rgb(153, 153, 153);">650</li><li style="color: rgb(153, 153, 153);">651</li><li style="color: rgb(153, 153, 153);">652</li><li style="color: rgb(153, 153, 153);">653</li><li style="color: rgb(153, 153, 153);">654</li><li style="color: rgb(153, 153, 153);">655</li><li style="color: rgb(153, 153, 153);">656</li><li style="color: rgb(153, 153, 153);">657</li><li style="color: rgb(153, 153, 153);">658</li><li style="color: rgb(153, 153, 153);">659</li><li style="color: rgb(153, 153, 153);">660</li><li style="color: rgb(153, 153, 153);">661</li><li style="color: rgb(153, 153, 153);">662</li><li style="color: rgb(153, 153, 153);">663</li><li style="color: rgb(153, 153, 153);">664</li><li style="color: rgb(153, 153, 153);">665</li><li style="color: rgb(153, 153, 153);">666</li><li style="color: rgb(153, 153, 153);">667</li><li style="color: rgb(153, 153, 153);">668</li><li style="color: rgb(153, 153, 153);">669</li><li style="color: rgb(153, 153, 153);">670</li><li style="color: rgb(153, 153, 153);">671</li><li style="color: rgb(153, 153, 153);">672</li><li style="color: rgb(153, 153, 153);">673</li><li style="color: rgb(153, 153, 153);">674</li><li style="color: rgb(153, 153, 153);">675</li><li style="color: rgb(153, 153, 153);">676</li><li style="color: rgb(153, 153, 153);">677</li><li style="color: rgb(153, 153, 153);">678</li><li style="color: rgb(153, 153, 153);">679</li><li style="color: rgb(153, 153, 153);">680</li><li style="color: rgb(153, 153, 153);">681</li><li style="color: rgb(153, 153, 153);">682</li><li style="color: rgb(153, 153, 153);">683</li><li style="color: rgb(153, 153, 153);">684</li><li style="color: rgb(153, 153, 153);">685</li><li style="color: rgb(153, 153, 153);">686</li><li style="color: rgb(153, 153, 153);">687</li><li style="color: rgb(153, 153, 153);">688</li><li style="color: rgb(153, 153, 153);">689</li><li style="color: rgb(153, 153, 153);">690</li><li style="color: rgb(153, 153, 153);">691</li><li style="color: rgb(153, 153, 153);">692</li><li style="color: rgb(153, 153, 153);">693</li><li style="color: rgb(153, 153, 153);">694</li><li style="color: rgb(153, 153, 153);">695</li><li style="color: rgb(153, 153, 153);">696</li><li style="color: rgb(153, 153, 153);">697</li><li style="color: rgb(153, 153, 153);">698</li><li style="color: rgb(153, 153, 153);">699</li><li style="color: rgb(153, 153, 153);">700</li><li style="color: rgb(153, 153, 153);">701</li><li style="color: rgb(153, 153, 153);">702</li><li style="color: rgb(153, 153, 153);">703</li><li style="color: rgb(153, 153, 153);">704</li><li style="color: rgb(153, 153, 153);">705</li><li style="color: rgb(153, 153, 153);">706</li><li style="color: rgb(153, 153, 153);">707</li><li style="color: rgb(153, 153, 153);">708</li><li style="color: rgb(153, 153, 153);">709</li><li style="color: rgb(153, 153, 153);">710</li><li style="color: rgb(153, 153, 153);">711</li><li style="color: rgb(153, 153, 153);">712</li><li style="color: rgb(153, 153, 153);">713</li><li style="color: rgb(153, 153, 153);">714</li><li style="color: rgb(153, 153, 153);">715</li><li style="color: rgb(153, 153, 153);">716</li><li style="color: rgb(153, 153, 153);">717</li><li style="color: rgb(153, 153, 153);">718</li><li style="color: rgb(153, 153, 153);">719</li><li style="color: rgb(153, 153, 153);">720</li><li style="color: rgb(153, 153, 153);">721</li><li style="color: rgb(153, 153, 153);">722</li><li style="color: rgb(153, 153, 153);">723</li><li style="color: rgb(153, 153, 153);">724</li><li style="color: rgb(153, 153, 153);">725</li><li style="color: rgb(153, 153, 153);">726</li><li style="color: rgb(153, 153, 153);">727</li><li style="color: rgb(153, 153, 153);">728</li><li style="color: rgb(153, 153, 153);">729</li><li style="color: rgb(153, 153, 153);">730</li><li style="color: rgb(153, 153, 153);">731</li><li style="color: rgb(153, 153, 153);">732</li><li style="color: rgb(153, 153, 153);">733</li><li style="color: rgb(153, 153, 153);">734</li><li style="color: rgb(153, 153, 153);">735</li><li style="color: rgb(153, 153, 153);">736</li><li style="color: rgb(153, 153, 153);">737</li><li style="color: rgb(153, 153, 153);">738</li><li style="color: rgb(153, 153, 153);">739</li><li style="color: rgb(153, 153, 153);">740</li><li style="color: rgb(153, 153, 153);">741</li><li style="color: rgb(153, 153, 153);">742</li><li style="color: rgb(153, 153, 153);">743</li><li style="color: rgb(153, 153, 153);">744</li><li style="color: rgb(153, 153, 153);">745</li><li style="color: rgb(153, 153, 153);">746</li><li style="color: rgb(153, 153, 153);">747</li><li style="color: rgb(153, 153, 153);">748</li><li style="color: rgb(153, 153, 153);">749</li><li style="color: rgb(153, 153, 153);">750</li><li style="color: rgb(153, 153, 153);">751</li><li style="color: rgb(153, 153, 153);">752</li><li style="color: rgb(153, 153, 153);">753</li><li style="color: rgb(153, 153, 153);">754</li><li style="color: rgb(153, 153, 153);">755</li><li style="color: rgb(153, 153, 153);">756</li><li style="color: rgb(153, 153, 153);">757</li><li style="color: rgb(153, 153, 153);">758</li><li style="color: rgb(153, 153, 153);">759</li><li style="color: rgb(153, 153, 153);">760</li><li style="color: rgb(153, 153, 153);">761</li><li style="color: rgb(153, 153, 153);">762</li><li style="color: rgb(153, 153, 153);">763</li><li style="color: rgb(153, 153, 153);">764</li><li style="color: rgb(153, 153, 153);">765</li><li style="color: rgb(153, 153, 153);">766</li><li style="color: rgb(153, 153, 153);">767</li><li style="color: rgb(153, 153, 153);">768</li><li style="color: rgb(153, 153, 153);">769</li><li style="color: rgb(153, 153, 153);">770</li><li style="color: rgb(153, 153, 153);">771</li><li style="color: rgb(153, 153, 153);">772</li><li style="color: rgb(153, 153, 153);">773</li><li style="color: rgb(153, 153, 153);">774</li><li style="color: rgb(153, 153, 153);">775</li><li style="color: rgb(153, 153, 153);">776</li><li style="color: rgb(153, 153, 153);">777</li><li style="color: rgb(153, 153, 153);">778</li><li style="color: rgb(153, 153, 153);">779</li><li style="color: rgb(153, 153, 153);">780</li><li style="color: rgb(153, 153, 153);">781</li><li style="color: rgb(153, 153, 153);">782</li><li style="color: rgb(153, 153, 153);">783</li><li style="color: rgb(153, 153, 153);">784</li><li style="color: rgb(153, 153, 153);">785</li><li style="color: rgb(153, 153, 153);">786</li><li style="color: rgb(153, 153, 153);">787</li><li style="color: rgb(153, 153, 153);">788</li><li style="color: rgb(153, 153, 153);">789</li><li style="color: rgb(153, 153, 153);">790</li><li style="color: rgb(153, 153, 153);">791</li><li style="color: rgb(153, 153, 153);">792</li><li style="color: rgb(153, 153, 153);">793</li><li style="color: rgb(153, 153, 153);">794</li><li style="color: rgb(153, 153, 153);">795</li><li style="color: rgb(153, 153, 153);">796</li><li style="color: rgb(153, 153, 153);">797</li><li style="color: rgb(153, 153, 153);">798</li><li style="color: rgb(153, 153, 153);">799</li><li style="color: rgb(153, 153, 153);">800</li><li style="color: rgb(153, 153, 153);">801</li><li style="color: rgb(153, 153, 153);">802</li><li style="color: rgb(153, 153, 153);">803</li><li style="color: rgb(153, 153, 153);">804</li><li style="color: rgb(153, 153, 153);">805</li><li style="color: rgb(153, 153, 153);">806</li><li style="color: rgb(153, 153, 153);">807</li><li style="color: rgb(153, 153, 153);">808</li><li style="color: rgb(153, 153, 153);">809</li><li style="color: rgb(153, 153, 153);">810</li><li style="color: rgb(153, 153, 153);">811</li><li style="color: rgb(153, 153, 153);">812</li><li style="color: rgb(153, 153, 153);">813</li><li style="color: rgb(153, 153, 153);">814</li><li style="color: rgb(153, 153, 153);">815</li><li style="color: rgb(153, 153, 153);">816</li><li style="color: rgb(153, 153, 153);">817</li><li style="color: rgb(153, 153, 153);">818</li><li style="color: rgb(153, 153, 153);">819</li><li style="color: rgb(153, 153, 153);">820</li><li style="color: rgb(153, 153, 153);">821</li><li style="color: rgb(153, 153, 153);">822</li><li style="color: rgb(153, 153, 153);">823</li><li style="color: rgb(153, 153, 153);">824</li><li style="color: rgb(153, 153, 153);">825</li><li style="color: rgb(153, 153, 153);">826</li><li style="color: rgb(153, 153, 153);">827</li><li style="color: rgb(153, 153, 153);">828</li><li style="color: rgb(153, 153, 153);">829</li><li style="color: rgb(153, 153, 153);">830</li><li style="color: rgb(153, 153, 153);">831</li><li style="color: rgb(153, 153, 153);">832</li><li style="color: rgb(153, 153, 153);">833</li><li style="color: rgb(153, 153, 153);">834</li><li style="color: rgb(153, 153, 153);">835</li><li style="color: rgb(153, 153, 153);">836</li><li style="color: rgb(153, 153, 153);">837</li><li style="color: rgb(153, 153, 153);">838</li><li style="color: rgb(153, 153, 153);">839</li><li style="color: rgb(153, 153, 153);">840</li><li style="color: rgb(153, 153, 153);">841</li><li style="color: rgb(153, 153, 153);">842</li><li style="color: rgb(153, 153, 153);">843</li><li style="color: rgb(153, 153, 153);">844</li><li style="color: rgb(153, 153, 153);">845</li><li style="color: rgb(153, 153, 153);">846</li><li style="color: rgb(153, 153, 153);">847</li><li style="color: rgb(153, 153, 153);">848</li><li style="color: rgb(153, 153, 153);">849</li><li style="color: rgb(153, 153, 153);">850</li><li style="color: rgb(153, 153, 153);">851</li><li style="color: rgb(153, 153, 153);">852</li><li style="color: rgb(153, 153, 153);">853</li><li style="color: rgb(153, 153, 153);">854</li><li style="color: rgb(153, 153, 153);">855</li><li style="color: rgb(153, 153, 153);">856</li><li style="color: rgb(153, 153, 153);">857</li><li style="color: rgb(153, 153, 153);">858</li><li style="color: rgb(153, 153, 153);">859</li><li style="color: rgb(153, 153, 153);">860</li><li style="color: rgb(153, 153, 153);">861</li><li style="color: rgb(153, 153, 153);">862</li><li style="color: rgb(153, 153, 153);">863</li><li style="color: rgb(153, 153, 153);">864</li><li style="color: rgb(153, 153, 153);">865</li><li style="color: rgb(153, 153, 153);">866</li><li style="color: rgb(153, 153, 153);">867</li><li style="color: rgb(153, 153, 153);">868</li><li style="color: rgb(153, 153, 153);">869</li><li style="color: rgb(153, 153, 153);">870</li><li style="color: rgb(153, 153, 153);">871</li><li style="color: rgb(153, 153, 153);">872</li><li style="color: rgb(153, 153, 153);">873</li><li style="color: rgb(153, 153, 153);">874</li><li style="color: rgb(153, 153, 153);">875</li><li style="color: rgb(153, 153, 153);">876</li><li style="color: rgb(153, 153, 153);">877</li><li style="color: rgb(153, 153, 153);">878</li><li style="color: rgb(153, 153, 153);">879</li><li style="color: rgb(153, 153, 153);">880</li><li style="color: rgb(153, 153, 153);">881</li><li style="color: rgb(153, 153, 153);">882</li><li style="color: rgb(153, 153, 153);">883</li><li style="color: rgb(153, 153, 153);">884</li><li style="color: rgb(153, 153, 153);">885</li><li style="color: rgb(153, 153, 153);">886</li><li style="color: rgb(153, 153, 153);">887</li><li style="color: rgb(153, 153, 153);">888</li><li style="color: rgb(153, 153, 153);">889</li><li style="color: rgb(153, 153, 153);">890</li><li style="color: rgb(153, 153, 153);">891</li><li style="color: rgb(153, 153, 153);">892</li><li style="color: rgb(153, 153, 153);">893</li><li style="color: rgb(153, 153, 153);">894</li><li style="color: rgb(153, 153, 153);">895</li><li style="color: rgb(153, 153, 153);">896</li><li style="color: rgb(153, 153, 153);">897</li><li style="color: rgb(153, 153, 153);">898</li><li style="color: rgb(153, 153, 153);">899</li><li style="color: rgb(153, 153, 153);">900</li><li style="color: rgb(153, 153, 153);">901</li><li style="color: rgb(153, 153, 153);">902</li><li style="color: rgb(153, 153, 153);">903</li><li style="color: rgb(153, 153, 153);">904</li><li style="color: rgb(153, 153, 153);">905</li><li style="color: rgb(153, 153, 153);">906</li><li style="color: rgb(153, 153, 153);">907</li><li style="color: rgb(153, 153, 153);">908</li><li style="color: rgb(153, 153, 153);">909</li><li style="color: rgb(153, 153, 153);">910</li><li style="color: rgb(153, 153, 153);">911</li><li style="color: rgb(153, 153, 153);">912</li><li style="color: rgb(153, 153, 153);">913</li><li style="color: rgb(153, 153, 153);">914</li><li style="color: rgb(153, 153, 153);">915</li><li style="color: rgb(153, 153, 153);">916</li><li style="color: rgb(153, 153, 153);">917</li><li style="color: rgb(153, 153, 153);">918</li><li style="color: rgb(153, 153, 153);">919</li><li style="color: rgb(153, 153, 153);">920</li><li style="color: rgb(153, 153, 153);">921</li><li style="color: rgb(153, 153, 153);">922</li><li style="color: rgb(153, 153, 153);">923</li><li style="color: rgb(153, 153, 153);">924</li><li style="color: rgb(153, 153, 153);">925</li><li style="color: rgb(153, 153, 153);">926</li><li style="color: rgb(153, 153, 153);">927</li><li style="color: rgb(153, 153, 153);">928</li><li style="color: rgb(153, 153, 153);">929</li><li style="color: rgb(153, 153, 153);">930</li><li style="color: rgb(153, 153, 153);">931</li><li style="color: rgb(153, 153, 153);">932</li><li style="color: rgb(153, 153, 153);">933</li><li style="color: rgb(153, 153, 153);">934</li><li style="color: rgb(153, 153, 153);">935</li><li style="color: rgb(153, 153, 153);">936</li><li style="color: rgb(153, 153, 153);">937</li><li style="color: rgb(153, 153, 153);">938</li><li style="color: rgb(153, 153, 153);">939</li><li style="color: rgb(153, 153, 153);">940</li><li style="color: rgb(153, 153, 153);">941</li><li style="color: rgb(153, 153, 153);">942</li><li style="color: rgb(153, 153, 153);">943</li><li style="color: rgb(153, 153, 153);">944</li><li style="color: rgb(153, 153, 153);">945</li><li style="color: rgb(153, 153, 153);">946</li><li style="color: rgb(153, 153, 153);">947</li><li style="color: rgb(153, 153, 153);">948</li><li style="color: rgb(153, 153, 153);">949</li><li style="color: rgb(153, 153, 153);">950</li><li style="color: rgb(153, 153, 153);">951</li><li style="color: rgb(153, 153, 153);">952</li><li style="color: rgb(153, 153, 153);">953</li><li style="color: rgb(153, 153, 153);">954</li><li style="color: rgb(153, 153, 153);">955</li><li style="color: rgb(153, 153, 153);">956</li><li style="color: rgb(153, 153, 153);">957</li><li style="color: rgb(153, 153, 153);">958</li><li style="color: rgb(153, 153, 153);">959</li><li style="color: rgb(153, 153, 153);">960</li><li style="color: rgb(153, 153, 153);">961</li><li style="color: rgb(153, 153, 153);">962</li><li style="color: rgb(153, 153, 153);">963</li><li style="color: rgb(153, 153, 153);">964</li><li style="color: rgb(153, 153, 153);">965</li><li style="color: rgb(153, 153, 153);">966</li><li style="color: rgb(153, 153, 153);">967</li><li style="color: rgb(153, 153, 153);">968</li><li style="color: rgb(153, 153, 153);">969</li><li style="color: rgb(153, 153, 153);">970</li><li style="color: rgb(153, 153, 153);">971</li><li style="color: rgb(153, 153, 153);">972</li><li style="color: rgb(153, 153, 153);">973</li><li style="color: rgb(153, 153, 153);">974</li><li style="color: rgb(153, 153, 153);">975</li><li style="color: rgb(153, 153, 153);">976</li><li style="color: rgb(153, 153, 153);">977</li><li style="color: rgb(153, 153, 153);">978</li><li style="color: rgb(153, 153, 153);">979</li><li style="color: rgb(153, 153, 153);">980</li><li style="color: rgb(153, 153, 153);">981</li><li style="color: rgb(153, 153, 153);">982</li><li style="color: rgb(153, 153, 153);">983</li><li style="color: rgb(153, 153, 153);">984</li><li style="color: rgb(153, 153, 153);">985</li><li style="color: rgb(153, 153, 153);">986</li><li style="color: rgb(153, 153, 153);">987</li><li style="color: rgb(153, 153, 153);">988</li><li style="color: rgb(153, 153, 153);">989</li><li style="color: rgb(153, 153, 153);">990</li><li style="color: rgb(153, 153, 153);">991</li><li style="color: rgb(153, 153, 153);">992</li><li style="color: rgb(153, 153, 153);">993</li><li style="color: rgb(153, 153, 153);">994</li><li style="color: rgb(153, 153, 153);">995</li><li style="color: rgb(153, 153, 153);">996</li><li style="color: rgb(153, 153, 153);">997</li><li style="color: rgb(153, 153, 153);">998</li><li style="color: rgb(153, 153, 153);">999</li><li style="color: rgb(153, 153, 153);">1000</li><li style="color: rgb(153, 153, 153);">1001</li><li style="color: rgb(153, 153, 153);">1002</li><li style="color: rgb(153, 153, 153);">1003</li><li style="color: rgb(153, 153, 153);">1004</li><li style="color: rgb(153, 153, 153);">1005</li><li style="color: rgb(153, 153, 153);">1006</li><li style="color: rgb(153, 153, 153);">1007</li><li style="color: rgb(153, 153, 153);">1008</li><li style="color: rgb(153, 153, 153);">1009</li><li style="color: rgb(153, 153, 153);">1010</li><li style="color: rgb(153, 153, 153);">1011</li><li style="color: rgb(153, 153, 153);">1012</li><li style="color: rgb(153, 153, 153);">1013</li><li style="color: rgb(153, 153, 153);">1014</li><li style="color: rgb(153, 153, 153);">1015</li><li style="color: rgb(153, 153, 153);">1016</li><li style="color: rgb(153, 153, 153);">1017</li><li style="color: rgb(153, 153, 153);">1018</li><li style="color: rgb(153, 153, 153);">1019</li><li style="color: rgb(153, 153, 153);">1020</li><li style="color: rgb(153, 153, 153);">1021</li><li style="color: rgb(153, 153, 153);">1022</li><li style="color: rgb(153, 153, 153);">1023</li><li style="color: rgb(153, 153, 153);">1024</li><li style="color: rgb(153, 153, 153);">1025</li><li style="color: rgb(153, 153, 153);">1026</li><li style="color: rgb(153, 153, 153);">1027</li><li style="color: rgb(153, 153, 153);">1028</li><li style="color: rgb(153, 153, 153);">1029</li><li style="color: rgb(153, 153, 153);">1030</li><li style="color: rgb(153, 153, 153);">1031</li><li style="color: rgb(153, 153, 153);">1032</li><li style="color: rgb(153, 153, 153);">1033</li><li style="color: rgb(153, 153, 153);">1034</li><li style="color: rgb(153, 153, 153);">1035</li><li style="color: rgb(153, 153, 153);">1036</li><li style="color: rgb(153, 153, 153);">1037</li><li style="color: rgb(153, 153, 153);">1038</li><li style="color: rgb(153, 153, 153);">1039</li><li style="color: rgb(153, 153, 153);">1040</li><li style="color: rgb(153, 153, 153);">1041</li><li style="color: rgb(153, 153, 153);">1042</li><li style="color: rgb(153, 153, 153);">1043</li><li style="color: rgb(153, 153, 153);">1044</li><li style="color: rgb(153, 153, 153);">1045</li><li style="color: rgb(153, 153, 153);">1046</li><li style="color: rgb(153, 153, 153);">1047</li><li style="color: rgb(153, 153, 153);">1048</li><li style="color: rgb(153, 153, 153);">1049</li><li style="color: rgb(153, 153, 153);">1050</li><li style="color: rgb(153, 153, 153);">1051</li><li style="color: rgb(153, 153, 153);">1052</li><li style="color: rgb(153, 153, 153);">1053</li><li style="color: rgb(153, 153, 153);">1054</li><li style="color: rgb(153, 153, 153);">1055</li><li style="color: rgb(153, 153, 153);">1056</li><li style="color: rgb(153, 153, 153);">1057</li><li style="color: rgb(153, 153, 153);">1058</li><li style="color: rgb(153, 153, 153);">1059</li><li style="color: rgb(153, 153, 153);">1060</li><li style="color: rgb(153, 153, 153);">1061</li><li style="color: rgb(153, 153, 153);">1062</li><li style="color: rgb(153, 153, 153);">1063</li><li style="color: rgb(153, 153, 153);">1064</li><li style="color: rgb(153, 153, 153);">1065</li><li style="color: rgb(153, 153, 153);">1066</li><li style="color: rgb(153, 153, 153);">1067</li><li style="color: rgb(153, 153, 153);">1068</li><li style="color: rgb(153, 153, 153);">1069</li><li style="color: rgb(153, 153, 153);">1070</li><li style="color: rgb(153, 153, 153);">1071</li><li style="color: rgb(153, 153, 153);">1072</li><li style="color: rgb(153, 153, 153);">1073</li><li style="color: rgb(153, 153, 153);">1074</li><li style="color: rgb(153, 153, 153);">1075</li><li style="color: rgb(153, 153, 153);">1076</li><li style="color: rgb(153, 153, 153);">1077</li><li style="color: rgb(153, 153, 153);">1078</li><li style="color: rgb(153, 153, 153);">1079</li><li style="color: rgb(153, 153, 153);">1080</li><li style="color: rgb(153, 153, 153);">1081</li><li style="color: rgb(153, 153, 153);">1082</li><li style="color: rgb(153, 153, 153);">1083</li><li style="color: rgb(153, 153, 153);">1084</li><li style="color: rgb(153, 153, 153);">1085</li><li style="color: rgb(153, 153, 153);">1086</li><li style="color: rgb(153, 153, 153);">1087</li><li style="color: rgb(153, 153, 153);">1088</li><li style="color: rgb(153, 153, 153);">1089</li><li style="color: rgb(153, 153, 153);">1090</li><li style="color: rgb(153, 153, 153);">1091</li><li style="color: rgb(153, 153, 153);">1092</li><li style="color: rgb(153, 153, 153);">1093</li><li style="color: rgb(153, 153, 153);">1094</li><li style="color: rgb(153, 153, 153);">1095</li><li style="color: rgb(153, 153, 153);">1096</li><li style="color: rgb(153, 153, 153);">1097</li><li style="color: rgb(153, 153, 153);">1098</li><li style="color: rgb(153, 153, 153);">1099</li><li style="color: rgb(153, 153, 153);">1100</li><li style="color: rgb(153, 153, 153);">1101</li><li style="color: rgb(153, 153, 153);">1102</li><li style="color: rgb(153, 153, 153);">1103</li><li style="color: rgb(153, 153, 153);">1104</li><li style="color: rgb(153, 153, 153);">1105</li><li style="color: rgb(153, 153, 153);">1106</li><li style="color: rgb(153, 153, 153);">1107</li><li style="color: rgb(153, 153, 153);">1108</li><li style="color: rgb(153, 153, 153);">1109</li><li style="color: rgb(153, 153, 153);">1110</li><li style="color: rgb(153, 153, 153);">1111</li><li style="color: rgb(153, 153, 153);">1112</li><li style="color: rgb(153, 153, 153);">1113</li><li style="color: rgb(153, 153, 153);">1114</li><li style="color: rgb(153, 153, 153);">1115</li><li style="color: rgb(153, 153, 153);">1116</li><li style="color: rgb(153, 153, 153);">1117</li><li style="color: rgb(153, 153, 153);">1118</li><li style="color: rgb(153, 153, 153);">1119</li><li style="color: rgb(153, 153, 153);">1120</li><li style="color: rgb(153, 153, 153);">1121</li><li style="color: rgb(153, 153, 153);">1122</li><li style="color: rgb(153, 153, 153);">1123</li><li style="color: rgb(153, 153, 153);">1124</li><li style="color: rgb(153, 153, 153);">1125</li><li style="color: rgb(153, 153, 153);">1126</li><li style="color: rgb(153, 153, 153);">1127</li><li style="color: rgb(153, 153, 153);">1128</li><li style="color: rgb(153, 153, 153);">1129</li><li style="color: rgb(153, 153, 153);">1130</li><li style="color: rgb(153, 153, 153);">1131</li><li style="color: rgb(153, 153, 153);">1132</li><li style="color: rgb(153, 153, 153);">1133</li><li style="color: rgb(153, 153, 153);">1134</li><li style="color: rgb(153, 153, 153);">1135</li><li style="color: rgb(153, 153, 153);">1136</li><li style="color: rgb(153, 153, 153);">1137</li><li style="color: rgb(153, 153, 153);">1138</li><li style="color: rgb(153, 153, 153);">1139</li><li style="color: rgb(153, 153, 153);">1140</li><li style="color: rgb(153, 153, 153);">1141</li><li style="color: rgb(153, 153, 153);">1142</li><li style="color: rgb(153, 153, 153);">1143</li><li style="color: rgb(153, 153, 153);">1144</li><li style="color: rgb(153, 153, 153);">1145</li><li style="color: rgb(153, 153, 153);">1146</li><li style="color: rgb(153, 153, 153);">1147</li><li style="color: rgb(153, 153, 153);">1148</li><li style="color: rgb(153, 153, 153);">1149</li><li style="color: rgb(153, 153, 153);">1150</li><li style="color: rgb(153, 153, 153);">1151</li><li style="color: rgb(153, 153, 153);">1152</li><li style="color: rgb(153, 153, 153);">1153</li><li style="color: rgb(153, 153, 153);">1154</li><li style="color: rgb(153, 153, 153);">1155</li><li style="color: rgb(153, 153, 153);">1156</li><li style="color: rgb(153, 153, 153);">1157</li><li style="color: rgb(153, 153, 153);">1158</li><li style="color: rgb(153, 153, 153);">1159</li></ul></pre> 
    <h4><a name="t13"></a><a id="httplibh_3060"></a>httplib.h(第三方库)</h4> 
    <h4><a name="t14"></a><a id="cppjieba_3062"></a>cppjieba(第三方库)</h4> 
    <h4><a name="t15"></a><a id="_3064"></a>目录结构</h4> 
    <p><img src="https://1000bd.com/contentImg/2024/04/25/305bd9bb48e9bc73.png" alt="在这里插入图片描述"></p>
                    </div>
                        </div>
                    </li>
    
                    <li class="list-group-item ul-li">
    
                        <b>相关阅读:</b><br>
                        <nobr>
    <a href="/Article/Index/1399957">【数据结构】面试OJ题——时间复杂度</a>                            <br />
    <a href="/Article/Index/799812">电脑上怎么把mov转换成mp4?</a>                            <br />
    <a href="/Article/Index/912224">哈希详解与实现1(哈希是什么以及解决哈希冲突)</a>                            <br />
    <a href="/Article/Index/1164676">SpringBoot的异常处理方式</a>                            <br />
    <a href="/Article/Index/1465380">牛客 —— 链表中倒数第k个结点(C语言,快慢指针,配图)</a>                            <br />
    <a href="/Article/Index/1022185">8个老手都不一定知道的sketch技巧</a>                            <br />
    <a href="/Article/Index/1256062">使用Apache Doris自动同步整个 MySQL/Oracle 数据库进行数据分析</a>                            <br />
    <a href="/Article/Index/876532">UML类图</a>                            <br />
    <a href="/Article/Index/934455">基于java最短路径算法的简单实现</a>                            <br />
    <a href="/Article/Index/936081">SSM+优秀宿舍评选系统 毕业设计-附源码221511</a>                            <br />
                        </nobr>
                    </li>
                    <li class="list-group-item from-a mb-2">
                        原文地址:https://blog.csdn.net/m0_74215144/article/details/138157231
                    </li>
    
                </ul>
            </div>
    
            <div class="col-lg-4 col-sm-12">
                <ul class="list-group" style="word-break:break-all;">
                    <li class="list-group-item ul-li-bg" aria-current="true">
                        最新文章
                    </li>
                    <li class="list-group-item ul-li">
                        <nobr>
    <a href="/Article/Index/1484446">攻防演习之三天拿下官网站群</a>                            <br />
    <a href="/Article/Index/1515268">数据安全治理学习——前期安全规划和安全管理体系建设</a>                            <br />
    <a href="/Article/Index/1759065">企业安全 | 企业内一次钓鱼演练准备过程</a>                            <br />
    <a href="/Article/Index/1485036">内网渗透测试 | Kerberos协议及其部分攻击手法</a>                            <br />
    <a href="/Article/Index/1877332">0day的产生 | 不懂代码的"代码审计"</a>                            <br />
    <a href="/Article/Index/1887576">安装scrcpy-client模块av模块异常,环境问题解决方案</a>                            <br />
    <a href="/Article/Index/1887578">leetcode hot100【LeetCode 279. 完全平方数】java实现</a>                            <br />
    <a href="/Article/Index/1887512">OpenWrt下安装Mosquitto</a>                            <br />
    <a href="/Article/Index/1887520">AnatoMask论文汇总</a>                            <br />
    <a href="/Article/Index/1887496">【AI日记】24.11.01 LangChain、openai api和github copilot</a>                            <br />
                        </nobr>
                    </li>
                </ul>
    
                <ul class="list-group pt-2" style="word-break:break-all;">
                    <li class="list-group-item ul-li-bg" aria-current="true">
                        热门文章
                    </li>
                    <li class="list-group-item ul-li">
                        <nobr>
    <a href="/Article/Index/888177">十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!</a>                            <br />
    <a href="/Article/Index/797680">奉劝各位学弟学妹们,该打造你的技术影响力了!</a>                            <br />
    <a href="/Article/Index/888183">五年了,我在 CSDN 的两个一百万。</a>                            <br />
    <a href="/Article/Index/888179">Java俄罗斯方块,老程序员花了一个周末,连接中学年代!</a>                            <br />
    <a href="/Article/Index/797730">面试官都震惊,你这网络基础可以啊!</a>                            <br />
    <a href="/Article/Index/797725">你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法</a>                            <br />
    <a href="/Article/Index/797702">心情不好的时候,用 Python 画棵樱花树送给自己吧</a>                            <br />
    <a href="/Article/Index/797709">通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!</a>                            <br />
    <a href="/Article/Index/797716">13 万字 C 语言从入门到精通保姆级教程2021 年版</a>                            <br />
    <a href="/Article/Index/888192">10行代码集2000张美女图,Python爬虫120例,再上征途</a>                            <br />
                        </nobr>
                    </li>
                </ul>
    
            </div>
        </div>
    </div>
    <!-- 主体 -->
    
    
        <!--body结束-->
        <!--这里是footer模板-->
        
        <!--footer-->
    <nav class="navbar navbar-inverse navbar-fixed-bottom">
        <div class="container">
            <div class="row">
                <div class="col-md-12">
                    <div class="text-muted center foot-height">
                        Copyright © 2022 侵权请联系<a href="mailto:2656653265@qq.com">2656653265@qq.com</a>   
                        <a href="https://beian.miit.gov.cn/" target="_blank">京ICP备2022015340号-1</a>
                    </div>
                    <div style="width:300px;margin:0 auto; padding:0px 5px;">
                        <a href="/regex.html">正则表达式工具</a>
                        <a href="/cron.html">cron表达式工具</a>
                        <a href="/pwdcreator.html">密码生成工具</a>
                    </div>
                    <div style="width:300px;margin:0 auto; padding:5px 0;">
                        <a target="_blank" href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=11010502049817" style="display:inline-block;text-decoration:none;height:20px;line-height:20px;">
                        <img src="" style="float:left;" /><p style="float:left;height:20px;line-height:20px;margin: 0px 0px 0px 5px; color:#939393;">京公网安备 11010502049817号</p></a>
                    </div>
                </div>
            </div>
        </div>
      
    </nav>
    <!--footer-->
    
        <!--footer模板结束-->
    
        <script src="/js/plugins/jquery/jquery.js"></script>
        <script src="/js/bootstrap.min.js"></script>
    
        <!--这里是scripts模板-->
        
    
        
     
    
    
        <!--scripts模板结束-->
    
    </body>
    </html>