{"id":15670,"date":"2025-04-18T22:12:55","date_gmt":"2025-04-18T14:12:55","guid":{"rendered":"https:\/\/www.wsisp.com\/helps\/15670.html"},"modified":"2025-04-18T22:12:55","modified_gmt":"2025-04-18T14:12:55","slug":"%e4%bb%bfmudou%e5%ba%93one-thread-oneloop%e5%bc%8f%e5%b9%b6%e5%8f%91%e6%9c%8d%e5%8a%a1%e5%99%a8","status":"publish","type":"post","link":"https:\/\/www.wsisp.com\/helps\/15670.html","title":{"rendered":"\u4effmudou\u5e93one thread oneloop\u5f0f\u5e76\u53d1\u670d\u52a1\u5668"},"content":{"rendered":"<h2 style=\"background-color:transparent\">\u9879\u76eegitee&#xff1a;\u4effmuduo: \u4effmuduo<\/h2>\n<h2>\u4e00&#xff1a;\u9879\u76ee\u76ee\u7684<\/h2>\n<h3 style=\"background-color:transparent\">1.1\u9879\u76ee\u7b80\u4ecb<\/h3>\n<p> <span style=\"color:#1f2329\">\u901a\u8fc7\u54b1\u4eec\u5b9e\u73b0\u7684\u2fbc\u5e76\u53d1\u670d\u52a1\u5668\u7ec4\u4ef6&#xff0c;\u53ef\u4ee5\u7b80\u6d01\u5feb\u901f\u7684\u5b8c\u6210\u2f00\u4e2a\u2fbc\u6027\u80fd\u7684\u670d\u52a1\u5668\u642d\u5efa\u3002 <\/span> <\/p>\n<p> <span style=\"color:#1f2329\">\u5e76\u4e14&#xff0c;\u901a\u8fc7\u7ec4\u4ef6\u5185\u63d0\u4f9b\u7684\u4e0d\u540c\u5e94\u2f64\u5c42\u534f\u8bae\u2f40\u6301&#xff0c;\u4e5f\u53ef\u4ee5\u5feb\u901f\u5b8c\u6210\u2f00\u4e2a\u2fbc\u6027\u80fd\u5e94\u2f64\u670d\u52a1\u5668\u7684\u642d\u5efa&#xff08;\u5f53\u524d\u9879\u2f6c\u4e2d\u63d0\u4f9bHTTP\u534f\u8bae\u7ec4\u4ef6\u7684\u2f40\u6301&#xff09;\u3002 <\/span> <\/p>\n<p> <span style=\"color:#1f2329\">\u5728\u8fd9\u2fa5&#xff0c;\u8981\u660e\u786e\u7684\u662f\u54b1\u4eec\u8981\u5b9e\u73b0\u7684\u662f\u2f00\u4e2a\u2fbc\u5e76\u53d1\u670d\u52a1\u5668\u7ec4\u4ef6&#xff0c;\u56e0\u6b64\u5f53\u524d\u7684\u9879\u2f6c\u4e2d\u5e76\u4e0d\u5305\u542b\u5b9e\u9645\u7684\u4e1a\u52a1\u5bb9\u3002 <\/span> <\/p>\n<h3>1.2<span style=\"color:#1f2329\">HTTP\u670d\u52a1\u5668<\/span><\/h3>\n<p> <span style=\"color:#1f2329\">\u6982\u5ff5&#xff1a; <\/span> <\/p>\n<p>  <span style=\"color:#1f2329\">HTTP&#xff08;Hyper Text Transfer Protocol&#xff09;&#xff0c;\u8d85\u2f42\u672c\u4f20\u8f93\u534f\u8bae\u662f\u5e94\u2f64\u5c42\u534f\u8bae&#xff0c;\u662f\u2f00\u79cd\u7b80\u5355\u7684\u8bf7\u6c42-\u54cd\u5e94\u534f \u8bae&#xff08;\u5ba2\u2f3e\u7aef\u6839\u636e\u2f83\u2f30\u7684\u9700\u8981\u5411\u670d\u52a1\u5668\u53d1\u9001\u8bf7\u6c42&#xff0c;\u670d\u52a1\u5668\u9488\u5bf9\u8bf7\u6c42\u63d0\u4f9b\u670d\u52a1&#xff0c;\u5b8c\u6bd5\u540e\u901a\u4fe1\u7ed3\u675f&#xff09;\u3002 \u534f\u8bae\u7ec6\u8282\u5728\u4e4b\u524d\u7684\u535a\u5ba2\u4e0a\u5df2\u7ecf\u8bb2\u8fc7&#xff0c;\u8fd9\u2fa5\u4e0d\u518d\u8d58\u8ff0\u3002\u4f46\u662f\u9700\u8981\u6ce8\u610f\u7684\u662fHTTP\u534f\u8bae\u662f\u2f00\u4e2a\u8fd0\u2f8f\u5728TCP\u534f\u8bae\u4e4b\u4e0a \u7684\u5e94\u2f64\u5c42\u534f\u8bae&#xff0c;\u8fd9\u2f00\u70b9\u672c\u8d28\u4e0a\u662f\u544a\u8bc9\u6211\u4eec&#xff0c;HTTP\u670d\u52a1\u5668\u5176\u5b9e\u5c31\u662f\u4e2aTCP\u670d\u52a1\u5668&#xff0c;\u53ea\u4e0d\u8fc7\u5728\u5e94\u2f64\u5c42\u57fa\u4e8e HTTP\u534f\u8bae\u683c\u5f0f\u8fdb\u2f8f\u6570\u636e\u7684\u7ec4\u7ec7\u548c\u89e3\u6790\u6765\u660e\u786e\u5ba2\u2f3e\u7aef\u7684\u8bf7\u6c42\u5e76\u5b8c\u6210\u4e1a\u52a1\u5904\u7406\u3002 <\/span> <\/p>\n<p>  <span style=\"color:#1f2329\">\u56e0\u6b64\u5b9e\u73b0HTTP\u670d\u52a1\u5668\u7b80\u5355\u7406\u89e3&#xff0c;\u53ea\u9700\u8981\u4ee5\u4e0b\u2f0f\u6b65\u5373\u53ef <\/span> <\/p>\n<p>  <span style=\"color:#1456f0\">1. <\/span><br \/>\n  <span style=\"color:#646a73\">\u642d\u5efa\u2f00\u4e2aTCP\u670d\u52a1\u5668&#xff0c;\u63a5\u6536\u5ba2\u2f3e\u7aef\u8bf7\u6c42\u3002 <\/span> <\/p>\n<p>  <span style=\"color:#1456f0\">2. <\/span><br \/>\n  <span style=\"color:#646a73\">\u4ee5HTTP\u534f\u8bae\u683c\u5f0f\u8fdb\u2f8f\u89e3\u6790\u8bf7\u6c42\u6570\u636e&#xff0c;\u660e\u786e\u5ba2\u2f3e\u7aef\u2f6c\u7684\u3002 <\/span> <\/p>\n<p>  <span style=\"color:#1456f0\">3. <\/span><br \/>\n  <span style=\"color:#646a73\">\u660e\u786e\u5ba2\u2f3e\u7aef\u8bf7\u6c42\u2f6c\u7684\u540e\u63d0\u4f9b\u5bf9\u5e94\u670d\u52a1\u3002 <\/span> <\/p>\n<p>  <span style=\"color:#1456f0\">4. <\/span><br \/>\n  <span style=\"color:#646a73\">\u5c06\u670d\u52a1\u7ed3\u679c\u2f00HTTP\u534f\u8bae\u683c\u5f0f\u8fdb\u2f8f\u7ec4\u7ec7&#xff0c;\u53d1\u9001\u7ed9\u5ba2\u2f3e\u7aef<\/span> <\/p>\n<p>   <span style=\"color:#1f2329\">\u5b9e\u73b0\u2f00\u4e2aHTTP\u670d\u52a1\u5668\u5f88\u7b80\u5355&#xff0c;\u4f46\u662f\u5b9e\u73b0\u2f00\u4e2a\u2fbc\u6027\u80fd\u7684\u670d\u52a1\u5668\u5e76\u4e0d\u7b80\u5355&#xff0c;\u8fd9\u4e2a\u5355\u5143\u4e2d\u5c06\u8bb2\u89e3\u57fa\u4e8e <\/span> <\/p>\n<p>   <span style=\"color:#1f2329\">Reactor\u6a21\u5f0f\u7684\u2fbc\u6027\u80fd\u670d\u52a1\u5668\u5b9e\u73b0\u3002 <\/span> <\/p>\n<p>   <span style=\"color:#1f2329\">\u5f53\u7136\u51c6\u786e\u6765\u8bf4&#xff0c;\u56e0\u4e3a\u6211\u4eec\u8981\u5b9e\u73b0\u7684\u670d\u52a1\u5668\u672c\u2f9d\u5e76\u4e0d\u5b58\u5728\u4e1a\u52a1&#xff0c;\u54b1\u4eec\u8981\u5b9e\u73b0\u7684\u5e94\u8be5\u7b97\u662f\u2f00\u4e2a\u2fbc\u6027\u80fd\u670d\u52a1 \u5668\u57fa\u7840\u5e93&#xff0c;\u662f\u2f00\u4e2a\u57fa\u7840\u7ec4\u4ef6\u3002<\/span> <\/p>\n<h3>1.3<span style=\"color:#1f2329\">Reactor\u6a21\u578b&#xff1a;<\/span><\/h3>\n<p>    <span style=\"color:#1f2329\">\u6982\u5ff5 <\/span> <\/p>\n<p>    <span style=\"color:#1f2329\">Reactor \u6a21\u5f0f&#xff0c;\u662f\u6307\u901a\u8fc7\u2f00\u4e2a\u6216\u591a\u4e2a\u8f93\u2f0a\u540c\u65f6\u4f20\u9012\u7ed9\u670d\u52a1\u5668\u8fdb\u2f8f\u8bf7\u6c42\u5904\u7406\u65f6\u7684\u4e8b\u4ef6\u9a71\u52a8\u5904\u7406\u6a21\u5f0f\u3002 <\/span> <\/p>\n<p>    <span style=\"color:#1f2329\">\u670d\u52a1\u7aef\u7a0b\u5e8f\u5904\u7406\u4f20\u2f0a\u591a\u8def\u8bf7\u6c42&#xff0c;\u5e76\u5c06\u5b83\u4eec\u540c\u6b65\u5206\u6d3e\u7ed9\u8bf7\u6c42\u5bf9\u5e94\u7684\u5904\u7406\u7ebf\u7a0b&#xff0c;Reactor \u6a21\u5f0f\u4e5f\u53eb <\/span> <\/p>\n<p>    <span style=\"color:#1f2329\">Dispatcher \u6a21\u5f0f\u3002 <\/span> <\/p>\n<p>    <span style=\"color:#1f2329\">\u7b80\u5355\u7406\u89e3\u5c31\u662f\u4f7f\u2f64 <\/span><br \/>\n    <span style=\"color:#1f2329\">I\/O<\/span><br \/>\n    <span style=\"color:#1f2329\">\u591a\u8def\u590d\u2f64 \u7edf\u2f00\u76d1\u542c\u4e8b\u4ef6&#xff0c;\u6536\u5230\u4e8b\u4ef6\u540e\u5206\u53d1\u7ed9\u5904\u7406\u8fdb\u7a0b\u6216\u7ebf\u7a0b&#xff0c;\u662f\u7f16\u5199\u2fbc\u6027\u80fd <\/span> <\/p>\n<p>    <span style=\"color:#1f2329\">\u2f79\u7edc\u670d\u52a1\u5668\u7684\u5fc5\u5907\u6280\u672f\u4e4b\u2f00\u3002<\/span> <\/p>\n<p>     <span style=\"color:#1f2329\">\u5206\u7c7b&#xff1a; <\/span> <\/p>\n<h4><span style=\"color:#1f2329\">\u5355Reactor\u5355\u7ebf\u7a0b&#xff1a;\u5355I\/O\u591a\u8def\u590d\u2f64&#043;\u4e1a\u52a1\u5904\u7406 <\/span><\/h4>\n<p>     <span style=\"color:#1456f0\">1. <\/span><br \/>\n     <span style=\"color:#646a73\">\u901a\u8fc7IO\u591a\u8def\u590d\u2f64\u6a21\u578b\u8fdb\u2f8f\u5ba2\u2f3e\u7aef\u8bf7\u6c42\u76d1\u63a7 <\/span> <\/p>\n<p>     <span style=\"color:#1456f0\">2. <\/span><br \/>\n     <span style=\"color:#646a73\">\u89e6\u53d1\u4e8b\u4ef6\u540e&#xff0c;\u8fdb\u2f8f\u4e8b\u4ef6\u5904\u7406 <\/span> <\/p>\n<p>     <span style=\"color:#1456f0\">a. <\/span><br \/>\n     <span style=\"color:#646a73\">\u5982\u679c\u662f\u65b0\u5efa\u8fde\u63a5\u8bf7\u6c42&#xff0c;\u5219\u83b7\u53d6\u65b0\u5efa\u8fde\u63a5&#xff0c;\u5e76\u6dfb\u52a0\u2f84\u591a\u8def\u590d\u2f64\u6a21\u578b\u8fdb\u2f8f\u4e8b\u4ef6\u76d1\u63a7\u3002 <\/span> <\/p>\n<p>     <span style=\"color:#1456f0\">b. <\/span><br \/>\n     <span style=\"color:#646a73\">\u5982\u679c\u662f\u6570\u636e\u901a\u4fe1\u8bf7\u6c42&#xff0c;\u5219\u8fdb\u2f8f\u5bf9\u5e94\u6570\u636e\u5904\u7406&#xff08;\u63a5\u6536\u6570\u636e&#xff0c;\u5904\u7406\u6570\u636e&#xff0c;\u53d1\u9001\u54cd\u5e94&#xff09;\u3002 <\/span> <\/p>\n<p>     <span style=\"color:#1f2329\">\u4f18\u70b9&#xff1a;\u6240\u6709\u64cd\u4f5c\u5747\u5728\u540c\u2f00\u7ebf\u7a0b\u4e2d\u5b8c\u6210&#xff0c;\u601d\u60f3\u6d41\u7a0b\u8f83\u4e3a\u7b80\u5355&#xff0c;\u4e0d\u6d89\u53ca\u8fdb\u7a0b\/\u7ebf\u7a0b\u95f4\u901a\u4fe1\u53ca\u8d44\u6e90\u4e89\u62a2\u95ee\u9898\u3002 <\/span> <\/p>\n<p>     <span style=\"color:#1f2329\">\u7f3a\u70b9&#xff1a;\u2f46\u6cd5\u6709\u6548\u5229\u2f64CPU\u591a\u6838\u8d44\u6e90&#xff0c;\u5f88\u5bb9\u6613\u8fbe\u5230\u6027\u80fd\u74f6\u9888\u3002 <\/span> <\/p>\n<p>     <span style=\"color:#1f2329\">\u9002\u2f64\u573a\u666f&#xff1a;\u9002\u2f64\u4e8e\u5ba2\u2f3e\u7aef\u6570\u91cf\u8f83\u5c11&#xff0c;\u4e14\u5904\u7406\u901f\u5ea6\u8f83\u4e3a\u5feb\u901f\u7684\u573a\u666f\u3002&#xff08;\u5904\u7406\u8f83\u6162\u6216\u6d3b\u8dc3\u8fde\u63a5\u8f83\u591a&#xff0c;\u4f1a\u5bfc <\/span> <\/p>\n<p>     <span style=\"color:#1f2329\">\u81f4\u4e32\u2f8f\u5904\u7406\u7684\u60c5\u51b5\u4e0b&#xff0c;\u540e\u5904\u7406\u7684\u8fde\u63a5\u2ed3\u65f6\u95f4\u2f46\u6cd5\u5f97\u5230\u54cd\u5e94&#xff09;\u3002 <\/span> <\/p>\n<h4><span style=\"color:#1f2329\">\u5355Reactor\u591a\u7ebf\u7a0b&#xff1a;\u5355I\/O\u591a\u8def\u590d\u2f64&#043;\u7ebf\u7a0b\u6c60&#xff08;\u4e1a\u52a1\u5904\u7406&#xff09; <\/span><\/h4>\n<p>     <span style=\"color:#1456f0\">1. <\/span><br \/>\n     <span style=\"color:#646a73\">Reactor\u7ebf\u7a0b\u901a\u8fc7I\/O\u591a\u8def\u590d\u2f64\u6a21\u578b\u8fdb\u2f8f\u5ba2\u2f3e\u7aef\u8bf7\u6c42\u76d1\u63a7 <\/span> <\/p>\n<p>     <span style=\"color:#1456f0\">2. <\/span><br \/>\n     <span style=\"color:#646a73\">\u89e6\u53d1\u4e8b\u4ef6\u540e&#xff0c;\u8fdb\u2f8f\u4e8b\u4ef6\u5904\u7406 <\/span> <\/p>\n<p>     <span style=\"color:#1456f0\">a. <\/span><br \/>\n     <span style=\"color:#646a73\">\u5982\u679c\u662f\u65b0\u5efa\u8fde\u63a5\u8bf7\u6c42&#xff0c;\u5219\u83b7\u53d6\u65b0\u5efa\u8fde\u63a5&#xff0c;\u5e76\u6dfb\u52a0\u2f84\u591a\u8def\u590d\u2f64\u6a21\u578b\u8fdb\u2f8f\u4e8b\u4ef6\u76d1\u63a7\u3002 <\/span> <\/p>\n<p>     <span style=\"color:#1456f0\">b. <\/span><br \/>\n     <span style=\"color:#646a73\">\u5982\u679c\u662f\u6570\u636e\u901a\u4fe1\u8bf7\u6c42&#xff0c;\u5219\u63a5\u6536\u6570\u636e\u540e\u5206\u53d1\u7ed9Worker\u7ebf\u7a0b\u6c60\u8fdb\u2f8f\u4e1a\u52a1\u5904\u7406\u3002 <\/span> <\/p>\n<p>     <span style=\"color:#1456f0\">c. <\/span><br \/>\n     <span style=\"color:#646a73\">\u2f2f\u4f5c\u7ebf\u7a0b\u5904\u7406\u5b8c\u6bd5\u540e&#xff0c;\u5c06\u54cd\u5e94\u4ea4\u7ed9Reactor\u7ebf\u7a0b\u8fdb\u2f8f\u6570\u636e\u54cd\u5e94 <\/span> <\/p>\n<p>     <span style=\"color:#1f2329\">\u4f18\u70b9&#xff1a;\u5145\u5206\u5229\u2f64CPU\u591a\u6838\u8d44\u6e90 <\/span> <\/p>\n<p>     <span style=\"color:#1f2329\">\u7f3a\u70b9&#xff1a;\u591a\u7ebf\u7a0b\u95f4\u7684\u6570\u636e\u5171\u4eab\u8bbf\u95ee\u63a7\u5236\u8f83\u4e3a\u590d\u6742&#xff0c;\u5355\u4e2aReactor \u627f\u62c5\u6240\u6709\u4e8b\u4ef6\u7684\u76d1\u542c\u548c\u54cd\u5e94&#xff0c;\u5728\u5355\u7ebf\u7a0b\u4e2d <\/span> <\/p>\n<p>     <span style=\"color:#1f2329\">\u8fd0\u2f8f&#xff0c;\u2fbc\u5e76\u53d1\u573a\u666f\u4e0b\u5bb9\u6613\u6210\u4e3a\u6027\u80fd\u74f6\u9888\u3002 <\/span> <\/p>\n<h4><span style=\"color:#1f2329\">\u591aReactor\u591a\u7ebf\u7a0b&#xff1a;\u591aI\/O\u591a\u8def\u590d\u2f64&#043;\u7ebf\u7a0b\u6c60&#xff08;\u4e1a\u52a1\u5904\u7406&#xff09; <\/span><\/h4>\n<p>     <span style=\"color:#1456f0\">1. <\/span><br \/>\n     <span style=\"color:#646a73\">\u5728\u4e3bReactor\u4e2d\u5904\u7406\u65b0\u8fde\u63a5\u8bf7\u6c42\u4e8b\u4ef6&#xff0c;\u6709\u65b0\u8fde\u63a5\u5230\u6765\u5219\u5206\u53d1\u5230\u2f26Reactor\u4e2d\u76d1\u63a7 <\/span> <\/p>\n<p>     <span style=\"color:#1456f0\">2. <\/span><br \/>\n     <span style=\"color:#646a73\">\u5728\u2f26Reactor\u4e2d\u8fdb\u2f8f\u5ba2\u2f3e\u7aef\u901a\u4fe1\u76d1\u63a7&#xff0c;\u6709\u4e8b\u4ef6\u89e6\u53d1&#xff0c;\u5219\u63a5\u6536\u6570\u636e\u5206\u53d1\u7ed9Worker\u7ebf\u7a0b\u6c60 <\/span> <\/p>\n<p>     <span style=\"color:#1456f0\">3. <\/span><br \/>\n     <span style=\"color:#646a73\">Worker\u7ebf\u7a0b\u6c60\u5206\u914d\u72ec\u2f74\u7684\u7ebf\u7a0b\u8fdb\u2f8f\u5177\u4f53\u7684\u4e1a\u52a1\u5904\u7406 <\/span> <\/p>\n<p>     <span style=\"color:#1456f0\">a. <\/span><br \/>\n     <span style=\"color:#646a73\">\u2f2f\u4f5c\u7ebf\u7a0b\u5904\u7406\u5b8c\u6bd5\u540e&#xff0c;\u5c06\u54cd\u5e94\u4ea4\u7ed9\u2f26Reactor\u7ebf\u7a0b\u8fdb\u2f8f\u6570\u636e\u54cd\u5e94 <\/span> <\/p>\n<p>     <span style=\"color:#1f2329\">\u4f18\u70b9&#xff1a;\u5145\u5206\u5229\u2f64CPU\u591a\u6838\u8d44\u6e90&#xff0c;\u4e3b\u4eceReactor\u5404\u53f8\u5176\u804c<\/span> <\/p>\n<h3><span style=\"color:#1f2329\">1.4\u2f6c\u6807\u5b9a\u4f4d&#xff1a;<\/span><\/h3>\n<p>      <span style=\"color:#1f2329\">One Thread One Loop\u4e3b\u4eceReactor\u6a21\u578b\u2fbc\u5e76\u53d1\u670d\u52a1\u5668 <\/span> <\/p>\n<p>      <span style=\"color:#1f2329\">\u54b1\u4eec\u8981\u5b9e\u73b0\u7684\u662f\u4e3b\u4eceReactor\u6a21\u578b\u670d\u52a1\u5668&#xff0c;\u4e5f\u5c31\u662f\u4e3bReactor\u7ebf\u7a0b\u4ec5\u4ec5\u76d1\u63a7\u76d1\u542c\u63cf\u8ff0\u7b26&#xff0c;\u83b7\u53d6\u65b0\u5efa\u8fde <\/span> <\/p>\n<p>      <span style=\"color:#1f2329\">\u63a5&#xff0c;\u4fdd\u8bc1\u83b7\u53d6\u65b0\u8fde\u63a5\u7684\u2fbc\u6548\u6027&#xff0c;\u63d0\u2fbc\u670d\u52a1\u5668\u7684\u5e76\u53d1\u6027\u80fd\u3002 <\/span> <\/p>\n<p>      <span style=\"color:#1f2329\">\u4e3bReactor\u83b7\u53d6\u5230\u65b0\u8fde\u63a5\u540e\u5206\u53d1\u7ed9\u2f26Reactor\u8fdb\u2f8f\u901a\u4fe1\u4e8b\u4ef6\u76d1\u63a7\u3002\u2f7d\u2f26Reactor\u7ebf\u7a0b\u76d1\u63a7\u5404\u2f83\u7684\u63cf\u8ff0\u7b26\u7684 \u8bfb\u5199\u4e8b\u4ef6\u8fdb\u2f8f\u6570\u636e\u8bfb\u5199\u4ee5\u53ca\u4e1a\u52a1\u5904\u7406\u3002<\/span> <\/p>\n<p>       <span style=\"color:#1f2329\">One Thread One Loop\u7684\u601d\u60f3\u5c31\u662f\u628a\u6240\u6709\u7684\u64cd\u4f5c\u90fd\u653e\u5230\u2f00\u4e2a\u7ebf\u7a0b\u4e2d\u8fdb\u2f8f&#xff0c;\u2f00\u4e2a\u7ebf\u7a0b\u5bf9\u5e94\u2f00\u4e2a\u4e8b\u4ef6\u5904\u7406 \u7684\u5faa\u73af\u3002 \u5f53\u524d\u5b9e\u73b0\u4e2d&#xff0c;\u56e0\u4e3a\u5e76\u4e0d\u786e\u5b9a\u7ec4\u4ef6\u4f7f\u2f64\u8005\u7684\u4f7f\u2f64\u610f\u5411&#xff0c;\u56e0\u6b64\u5e76\u4e0d\u63d0\u4f9b\u4e1a\u52a1\u5c42\u2f2f\u4f5c\u7ebf\u7a0b\u6c60\u7684\u5b9e\u73b0&#xff0c;\u53ea\u73b0 \u4e3b\u4eceReactor&#xff0c;\u2f7dWorker\u2f2f\u4f5c\u7ebf\u7a0b\u6c60&#xff0c;\u53ef\u7531\u7ec4\u4ef6\u5e93\u7684\u4f7f\u2f64\u8005\u7684\u9700\u8981\u2f83\u2f8f\u51b3\u5b9a\u662f\u5426\u4f7f\u2f64\u548c\u5b9e\u73b0\u3002<\/span> <\/p>\n<h2><span style=\"color:#1f2329\">\u4e8c&#xff1a;\u529f\u80fd\u6a21\u5757\u5212\u5206&#xff1a; <\/span><\/h2>\n<p>        <span style=\"color:#1f2329\">\u57fa\u4e8e\u4ee5\u4e0a\u7684\u7406\u89e3&#xff0c;\u6211\u4eec\u8981\u5b9e\u73b0\u7684\u662f\u2f00\u4e2a\u5e26\u6709\u534f\u8bae\u2f40\u6301\u7684Reactor\u6a21\u578b\u2fbc\u6027\u80fd\u670d\u52a1\u5668&#xff0c;\u56e0\u6b64\u5c06\u6574\u4e2a\u9879\u2f6c\u7684 \u5b9e\u73b0\u5212\u5206\u4e3a\u4e24\u4e2a\u2f24\u7684\u6a21\u5757&#xff1a; <\/span> <\/p>\n<p>        <span style=\"color:#1456f0\">\u2022 <\/span><br \/>\n        <span style=\"color:#1f2329\">SERVER\u6a21\u5757&#xff1a;\u5b9e\u73b0Reactor\u6a21\u578b\u7684TCP\u670d\u52a1\u5668&#xff1b; <\/span> <\/p>\n<p>        <span style=\"color:#1456f0\">\u2022 <\/span><br \/>\n        <span style=\"color:#1f2329\">\u534f\u8bae\u6a21\u5757&#xff1a;\u5bf9\u5f53\u524d\u7684Reactor\u6a21\u578b\u670d\u52a1\u5668\u63d0\u4f9b\u5e94\u2f64\u5c42\u534f\u8bae\u2f40\u6301\u3002 <\/span> <\/p>\n<h3 style=\"background-color:transparent\"><span style=\"color:#1f2329\">SERVER\u6a21\u5757&#xff1a; <\/span><\/h3>\n<p>        <span style=\"color:#1f2329\">SERVER\u6a21\u5757\u5c31\u662f\u5bf9\u6240\u6709\u7684\u8fde\u63a5\u4ee5\u53ca\u7ebf\u7a0b\u8fdb\u2f8f\u7ba1\u7406&#xff0c;\u8ba9\u5b83\u4eec\u5404\u53f8\u5176\u804c&#xff0c;\u5728\u5408\u9002\u7684\u65f6\u5019\u505a\u5408\u9002\u7684\u4e8b&#xff0c;\u6700\u7ec8 \u5b8c\u6210\u2fbc\u6027\u80fd\u670d\u52a1\u5668\u7ec4\u4ef6\u7684\u5b9e\u73b0\u3002 <\/span> <\/p>\n<p>        <span style=\"color:#1f2329\">\u2f7d\u5177\u4f53\u7684\u7ba1\u7406\u4e5f\u5206\u4e3a\u4e09\u4e2a\u2f45\u2faf&#xff1a; <\/span> <\/p>\n<p>        <span style=\"color:#1456f0\">\u2022 <\/span><br \/>\n        <span style=\"color:#1f2329\">\u76d1\u542c\u8fde\u63a5\u7ba1\u7406&#xff1a;\u5bf9\u76d1\u542c\u8fde\u63a5\u8fdb\u2f8f\u7ba1\u7406\u3002 <\/span> <\/p>\n<p>        <span style=\"color:#1456f0\">\u2022 <\/span><br \/>\n        <span style=\"color:#1f2329\">\u901a\u4fe1\u8fde\u63a5\u7ba1\u7406&#xff1a;\u5bf9\u901a\u4fe1\u8fde\u63a5\u8fdb\u2f8f\u7ba1\u7406\u3002 <\/span> <\/p>\n<p>        <span style=\"color:#1456f0\">\u2022 <\/span><br \/>\n        <span style=\"color:#1f2329\">\u8d85\u65f6\u8fde\u63a5\u7ba1\u7406&#xff1a;\u5bf9\u8d85\u65f6\u8fde\u63a5\u8fdb\u2f8f\u7ba1\u7406\u3002 <\/span> <\/p>\n<p>        <span style=\"color:#1f2329\">\u57fa\u4e8e\u4ee5\u4e0a\u7684\u7ba1\u7406\u601d\u60f3&#xff0c;\u5c06\u8fd9\u4e2a\u6a21\u5757\u8fdb\u2f8f\u7ec6\u81f4\u7684\u5212\u5206\u2f1c\u53ef\u4ee5\u5212\u5206\u4e3a\u4ee5\u4e0b\u591a\u4e2a\u2f26\u6a21\u5757&#xff1a;<\/span> <\/p>\n<h4 style=\"background-color:transparent\"><span style=\"color:#1f2329\">Buffer\u6a21\u5757&#xff1a; <\/span><\/h4>\n<p>         <span style=\"color:#1f2329\">Buffer\u6a21\u5757\u662f\u2f00\u4e2a\u7f13\u51b2\u533a\u6a21\u5757&#xff0c;\u2f64\u4e8e\u5b9e\u73b0\u901a\u4fe1\u4e2d\u2f64\u2f3e\u6001\u7684\u63a5\u6536\u7f13\u51b2\u533a\u548c\u53d1\u9001\u7f13\u51b2\u533a\u529f\u80fd <\/span> <\/p>\n<p>         <img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"363\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250418141243-68025ddb91edf.png\" width=\"1200\" \/> <\/p>\n<h4><span style=\"color:#1f2329\">Socket\u6a21\u5757&#xff1a; <\/span><\/h4>\n<p>         <span style=\"color:#1f2329\">Socket\u6a21\u5757\u662f\u5bf9\u5957\u63a5\u5b57\u64cd\u4f5c\u5c01\u88c5\u7684\u2f00\u4e2a\u6a21\u5757&#xff0c;\u4e3b\u8981\u5b9e\u73b0\u7684socket\u7684\u5404\u9879\u64cd\u4f5c\u3002 <\/span> <\/p>\n<p>         <img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"772\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250418141243-68025ddbcd343.png\" width=\"766\" \/> <\/p>\n<h4><span style=\"color:#1f2329\">Channel\u6a21\u5757&#xff1a; <\/span><\/h4>\n<p>         <span style=\"color:#1f2329\">Channel\u6a21\u5757\u662f\u5bf9\u2f00\u4e2a\u63cf\u8ff0\u7b26\u9700\u8981\u8fdb\u2f8f\u7684IO\u4e8b\u4ef6\u7ba1\u7406\u7684\u6a21\u5757&#xff0c;\u5b9e\u73b0\u5bf9\u63cf\u8ff0\u7b26\u53ef\u8bfb&#xff0c;\u53ef\u5199&#xff0c;\u9519\u8bef&#8230;\u4e8b\u4ef6\u7684 \u7ba1\u7406\u64cd\u4f5c&#xff0c;\u4ee5\u53caPoller\u6a21\u5757\u5bf9\u63cf\u8ff0\u7b26\u8fdb\u2f8fIO\u4e8b\u4ef6\u76d1\u63a7\u5c31\u7eea\u540e&#xff0c;\u6839\u636e\u4e0d\u540c\u7684\u4e8b\u4ef6&#xff0c;\u56de\u8c03\u4e0d\u540c\u7684\u5904\u7406\u51fd\u6570\u529f \u80fd\u3002 <\/span> <\/p>\n<p>         <img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"696\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250418141243-68025ddbf1bad.png\" width=\"1200\" \/> <\/p>\n<h4><span style=\"color:#1f2329\">Connection\u6a21\u5757 <\/span><\/h4>\n<p>          <span style=\"color:#1f2329\">Connection\u6a21\u5757\u662f\u5bf9Buffer\u6a21\u5757&#xff0c;Socket\u6a21\u5757&#xff0c;Channel\u6a21\u5757\u7684\u2f00\u4e2a\u6574\u4f53\u5c01\u88c5&#xff0c;\u5b9e\u73b0\u4e86\u5bf9\u2f00\u4e2a\u901a\u4fe1\u5957 \u63a5\u5b57\u7684\u6574\u4f53\u7684\u7ba1\u7406&#xff0c;\u6bcf\u2f00\u4e2a\u8fdb\u2f8f\u6570\u636e\u901a\u4fe1\u7684\u5957\u63a5\u5b57&#xff08;\u4e5f\u5c31\u662faccept\u83b7\u53d6\u5230\u7684\u65b0\u8fde\u63a5&#xff09;\u90fd\u4f1a\u4f7f\u2f64 <\/span> <\/p>\n<p>          <span style=\"color:#1f2329\">Connection\u8fdb\u2f8f\u7ba1\u7406\u3002 <\/span> <\/p>\n<p>          <span style=\"color:#1456f0\">\u2022 <\/span><br \/>\n          <span style=\"color:#1f2329\">Connection\u6a21\u5757\u5185\u90e8\u5305\u542b\u6709\u4e09\u4e2a\u7531\u7ec4\u4ef6\u4f7f\u2f64\u8005\u4f20\u2f0a\u7684\u56de\u8c03\u51fd\u6570&#xff1a;\u8fde\u63a5\u5efa\u2f74\u5b8c\u6210\u56de\u8c03&#xff0c;\u4e8b\u4ef6\u56de\u8c03&#xff0c; <\/span> <\/p>\n<p>          <span style=\"color:#1f2329\">\u65b0\u6570\u636e\u56de\u8c03&#xff0c;\u5173\u95ed\u56de\u8c03\u3002<\/span> <\/p>\n<p>           <span style=\"color:#1456f0\">\u2022 <\/span><br \/>\n           <span style=\"color:#1f2329\">Connection\u6a21\u5757\u5185\u90e8\u5305\u542b\u6709\u4e24\u4e2a\u7ec4\u4ef6\u4f7f\u2f64\u8005\u63d0\u4f9b\u7684\u63a5\u2f1d&#xff1a;\u6570\u636e\u53d1\u9001\u63a5\u2f1d&#xff0c;\u8fde\u63a5\u5173\u95ed\u63a5\u2f1d <\/span> <\/p>\n<p>           <span style=\"color:#1456f0\">\u2022 <\/span><br \/>\n           <span style=\"color:#1f2329\">Connection\u6a21\u5757\u5185\u90e8\u5305\u542b\u6709\u4e24\u4e2a\u2f64\u2f3e\u6001\u7f13\u51b2\u533a&#xff1a;\u2f64\u2f3e\u6001\u63a5\u6536\u7f13\u51b2\u533a&#xff0c;\u2f64\u2f3e\u6001\u53d1\u9001\u7f13\u51b2\u533a <\/span> <\/p>\n<p>           <span style=\"color:#1456f0\">\u2022 <\/span><br \/>\n           <span style=\"color:#1f2329\">Connection\u6a21\u5757\u5185\u90e8\u5305\u542b\u6709\u2f00\u4e2aSocket\u5bf9\u8c61&#xff1a;\u5b8c\u6210\u63cf\u8ff0\u7b26\u2faf\u5411\u7cfb\u7edf\u7684IO\u64cd\u4f5c <\/span> <\/p>\n<p>           <span style=\"color:#1456f0\">\u2022 <\/span><br \/>\n           <span style=\"color:#1f2329\">Connection\u6a21\u5757\u5185\u90e8\u5305\u542b\u6709\u2f00\u4e2aChannel\u5bf9\u8c61&#xff1a;\u5b8c\u6210\u63cf\u8ff0\u7b26IO\u4e8b\u4ef6\u5c31\u7eea\u7684\u5904\u7406 <\/span> <\/p>\n<p>           <span style=\"color:#1f2329\">\u5177\u4f53\u5904\u7406\u6d41\u7a0b\u5982\u4e0b&#xff1a; <\/span> <\/p>\n<p>           <span style=\"color:#1456f0\">1. <\/span><br \/>\n           <span style=\"color:#1f2329\">\u5b9e\u73b0\u5411Channel\u63d0\u4f9b\u53ef\u8bfb&#xff0c;\u53ef\u5199&#xff0c;\u9519\u8bef\u7b49\u4e0d\u540c\u4e8b\u4ef6\u7684IO\u4e8b\u4ef6\u56de\u8c03\u51fd\u6570&#xff0c;\u7136\u540e\u5c06Channel\u548c\u5bf9\u5e94\u7684\u63cf \u8ff0\u7b26\u6dfb\u52a0\u5230Poller\u4e8b\u4ef6\u76d1\u63a7\u4e2d\u3002 <\/span> <\/p>\n<p>           <span style=\"color:#1456f0\">2. <\/span><br \/>\n           <span style=\"color:#1f2329\">\u5f53\u63cf\u8ff0\u7b26\u5728Poller\u6a21\u5757\u4e2d\u5c31\u7eea\u4e86IO\u53ef\u8bfb\u4e8b\u4ef6&#xff0c;\u5219\u8c03\u2f64\u63cf\u8ff0\u7b26\u5bf9\u5e94Channel\u4e2d\u4fdd\u5b58\u7684\u8bfb\u4e8b\u4ef6\u5904\u7406\u51fd <\/span> <\/p>\n<p>           <span style=\"color:#1f2329\">\u6570&#xff0c;\u8fdb\u2f8f\u6570\u636e\u8bfb\u53d6&#xff0c;\u5c06socket\u63a5\u6536\u7f13\u51b2\u533a\u5168\u90e8\u8bfb\u53d6\u5230Connection\u7ba1\u7406\u7684\u2f64\u2f3e\u6001\u63a5\u6536\u7f13\u51b2\u533a\u4e2d\u3002\u7136 <\/span> <\/p>\n<p>           <span style=\"color:#1f2329\">\u540e\u8c03\u2f64\u7531\u7ec4\u4ef6\u4f7f\u2f64\u8005\u4f20\u2f0a\u7684\u65b0\u6570\u636e\u5230\u6765\u56de\u8c03\u51fd\u6570\u8fdb\u2f8f\u5904\u7406\u3002 <\/span> <\/p>\n<p>           <span style=\"color:#1456f0\">3. <\/span><br \/>\n           <span style=\"color:#1f2329\">\u7ec4\u4ef6\u4f7f\u2f64\u8005\u8fdb\u2f8f\u6570\u636e\u7684\u4e1a\u52a1\u5904\u7406\u5b8c\u6bd5\u540e&#xff0c;\u901a\u8fc7Connection\u5411\u4f7f\u2f64\u8005\u63d0\u4f9b\u7684\u6570\u636e\u53d1\u9001\u63a5\u2f1d&#xff0c;\u5c06\u6570\u636e \u5199\u2f0aConnection\u7684\u53d1\u9001\u7f13\u51b2\u533a\u4e2d\u3002 <\/span> <\/p>\n<p>           <span style=\"color:#1456f0\">4. <\/span><br \/>\n           <span style=\"color:#1f2329\">\u542f\u52a8\u63cf\u8ff0\u7b26\u5728Poll\u6a21\u5757\u4e2d\u7684IO\u5199\u4e8b\u4ef6\u76d1\u63a7&#xff0c;\u5c31\u7eea\u540e&#xff0c;\u8c03\u2f64Channel\u4e2d\u4fdd\u5b58\u7684\u5199\u4e8b\u4ef6\u5904\u7406\u51fd\u6570&#xff0c;\u5c06\u53d1 \u9001\u7f13\u51b2\u533a\u4e2d\u7684\u6570\u636e\u901a\u8fc7Socket\u8fdb\u2f8f\u2faf\u5411\u7cfb\u7edf\u7684\u5b9e\u9645\u6570\u636e\u53d1\u9001\u3002<\/span> <\/p>\n<p>         <img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"813\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250418141244-68025ddc8959b.png\" width=\"1200\" \/> <\/p>\n<h4><span style=\"color:#1f2329\">Acceptor\u6a21\u5757&#xff1a; <\/span><\/h4>\n<p>          <span style=\"color:#1f2329\">Acceptor\u6a21\u5757\u662f\u5bf9Socket\u6a21\u5757&#xff0c;Channel\u6a21\u5757\u7684\u2f00\u4e2a\u6574\u4f53\u5c01\u88c5&#xff0c;\u5b9e\u73b0\u4e86\u5bf9\u2f00\u4e2a\u76d1\u542c\u5957\u63a5\u5b57\u7684\u6574\u4f53\u7684\u7ba1 \u7406\u3002 <\/span> <\/p>\n<p>          <span style=\"color:#1456f0\">\u2022 <\/span><br \/>\n          <span style=\"color:#1f2329\">Acceptor\u6a21\u5757\u5185\u90e8\u5305\u542b\u6709\u2f00\u4e2aSocket\u5bf9\u8c61&#xff1a;\u5b9e\u73b0\u76d1\u542c\u5957\u63a5\u5b57\u7684\u64cd\u4f5c <\/span> <\/p>\n<p>          <span style=\"color:#1456f0\">\u2022 <\/span><br \/>\n          <span style=\"color:#1f2329\">Acceptor\u6a21\u5757\u5185\u90e8\u5305\u542b\u6709\u2f00\u4e2aChannel\u5bf9\u8c61&#xff1a;\u5b9e\u73b0\u76d1\u542c\u5957\u63a5\u5b57IO\u4e8b\u4ef6\u5c31\u7eea\u7684\u5904\u7406 <\/span> <\/p>\n<p>          <span style=\"color:#1f2329\">\u5177\u4f53\u5904\u7406\u6d41\u7a0b\u5982\u4e0b&#xff1a; <\/span> <\/p>\n<p>          <span style=\"color:#1456f0\">1. <\/span><br \/>\n          <span style=\"color:#1f2329\">\u5b9e\u73b0\u5411Channel\u63d0\u4f9b\u53ef\u8bfb\u4e8b\u4ef6\u7684IO\u4e8b\u4ef6\u5904\u7406\u56de\u8c03\u51fd\u6570&#xff0c;\u51fd\u6570\u7684\u529f\u80fd\u5176\u5b9e\u4e5f\u5c31\u662f\u83b7\u53d6\u65b0\u8fde\u63a5 <\/span> <\/p>\n<p>          <span style=\"color:#1456f0\">2. <\/span><br \/>\n          <span style=\"color:#1f2329\">\u4e3a\u65b0\u8fde\u63a5\u6784\u5efa\u2f00\u4e2aConnection\u5bf9\u8c61\u51fa\u6765\u3002 <\/span> <\/p>\n<p>          <img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"330\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250418141245-68025ddd3a896.png\" width=\"1200\" \/> <\/p>\n<h4><span style=\"color:#1f2329\">TimerQueue\u6a21\u5757&#xff1a; <\/span><\/h4>\n<p>          <span style=\"color:#1f2329\">TimerQueue\u6a21\u5757\u662f\u5b9e\u73b0\u56fa\u5b9a\u65f6\u95f4\u5b9a\u65f6\u4efb\u52a1\u7684\u6a21\u5757&#xff0c;\u53ef\u4ee5\u7406\u89e3\u5c31\u662f\u8981\u7ed9\u5b9a\u65f6\u4efb\u52a1\u7ba1\u7406\u5668&#xff0c;\u5411\u5b9a\u65f6\u4efb\u52a1\u7ba1 \u7406\u5668\u4e2d\u6dfb\u52a0\u2f00\u4e2a\u4efb\u52a1&#xff0c;\u4efb\u52a1\u5c06\u5728\u56fa\u5b9a\u65f6\u95f4\u540e\u88ab\u6267\u2f8f&#xff0c;\u540c\u65f6\u4e5f\u53ef\u4ee5\u901a\u8fc7\u5237\u65b0\u5b9a\u65f6\u4efb\u52a1\u6765\u5ef6\u8fdf\u4efb\u52a1\u7684\u6267 \u2f8f\u3002 <\/span> <\/p>\n<p>          <span style=\"color:#1f2329\">\u8fd9\u4e2a\u6a21\u5757\u4e3b\u8981\u662f\u5bf9Connection\u5bf9\u8c61\u7684\u2f63\u547d\u5468\u671f\u7ba1\u7406&#xff0c;\u5bf9\u2fae\u6d3b\u8dc3\u8fde\u63a5\u8fdb\u2f8f\u8d85\u65f6\u540e\u7684\u91ca\u653e\u529f\u80fd\u3002 <\/span> <\/p>\n<p>          <span style=\"color:#1f2329\">TimerQueue\u6a21\u5757\u5185\u90e8\u5305\u542b\u6709\u2f00\u4e2atimerfd&#xff1a;linux\u7cfb\u7edf\u63d0\u4f9b\u7684\u5b9a\u65f6\u5668\u3002 <\/span> <\/p>\n<p>          <span style=\"color:#1f2329\">TimerQueue\u6a21\u5757\u5185\u90e8\u5305\u542b\u6709\u2f00\u4e2aChannel\u5bf9\u8c61&#xff1a;\u5b9e\u73b0\u5bf9timerfd\u7684IO\u65f6\u95f4\u5c31\u7eea\u56de\u8c03\u5904\u7406<\/span> <\/p>\n<p>          <img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"333\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250418141245-68025ddd72e4f.png\" width=\"1200\" \/> <\/p>\n<h4><span style=\"color:#1f2329\">Poller\u6a21\u5757&#xff1a; <\/span><\/h4>\n<p>           <span style=\"color:#1f2329\">Poller\u6a21\u5757\u662f\u5bf9epoll\u8fdb\u2f8f\u5c01\u88c5\u7684\u2f00\u4e2a\u6a21\u5757&#xff0c;\u4e3b\u8981\u5b9e\u73b0epoll\u7684IO\u4e8b\u4ef6\u6dfb\u52a0&#xff0c;\u4fee\u6539&#xff0c;\u79fb\u9664&#xff0c;\u83b7\u53d6\u6d3b\u8dc3\u8fde\u63a5 \u529f\u80fd\u3002<\/span> <\/p>\n<p>           <img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"364\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250418141245-68025dddaa630.png\" width=\"1074\" \/> <\/p>\n<h4><span style=\"color:#1f2329\">EventLoop\u6a21\u5757&#xff1a; <\/span><\/h4>\n<p>            <span style=\"color:#1f2329\">EventLoop\u6a21\u5757\u53ef\u4ee5\u7406\u89e3\u5c31\u662f\u6211\u4eec\u4e0a\u8fb9\u6240\u8bf4\u7684Reactor\u6a21\u5757&#xff0c;\u5b83\u662f\u5bf9Poller\u6a21\u5757&#xff0c;TimerQueue\u6a21\u5757&#xff0c; Socket\u6a21\u5757\u7684\u2f00\u4e2a\u6574\u4f53\u5c01\u88c5&#xff0c;\u8fdb\u2f8f\u6240\u6709\u63cf\u8ff0\u7b26\u7684\u4e8b\u4ef6\u76d1\u63a7\u3002 <\/span> <\/p>\n<p>            <span style=\"color:#1f2329\">EventLoop\u6a21\u5757\u5fc5\u7136\u662f\u2f00\u4e2a\u5bf9\u8c61\u5bf9\u5e94\u2f00\u4e2a\u7ebf\u7a0b\u7684\u6a21\u5757&#xff0c;\u7ebf\u7a0b\u5185\u90e8\u7684\u2f6c\u7684\u5c31\u662f\u8fd0\u2f8fEventLoop\u7684\u542f\u52a8\u51fd \u6570\u3002 <\/span> <\/p>\n<p>            <span style=\"color:#1f2329\">EventLoop\u6a21\u5757\u4e3a\u4e86\u4fdd\u8bc1\u6574\u4e2a\u670d\u52a1\u5668\u7684\u7ebf\u7a0b\u5b89\u5168\u95ee\u9898&#xff0c;\u56e0\u6b64\u8981\u6c42\u4f7f\u2f64\u8005\u5bf9\u4e8eConnection\u7684\u6240\u6709\u64cd\u4f5c\u2f00 \u5b9a\u8981\u5728\u5176\u5bf9\u5e94\u7684EventLoop\u7ebf\u7a0b\u5185\u5b8c\u6210&#xff0c;\u4e0d\u80fd\u5728\u5176\u4ed6\u7ebf\u7a0b\u4e2d\u8fdb\u2f8f&#xff08;\u2f50\u5982\u7ec4\u4ef6\u4f7f\u2f64\u8005\u4f7f\u2f64Connection\u53d1 \u9001\u6570\u636e&#xff0c;\u4ee5\u53ca\u5173\u95ed\u8fde\u63a5\u8fd9\u79cd\u64cd\u4f5c&#xff09;\u3002 <\/span> <\/p>\n<p>            <span style=\"color:#1f2329\">EventLoop\u6a21\u5757\u4fdd\u8bc1\u2f83\u2f30\u5185\u90e8\u6240\u76d1\u63a7\u7684\u6240\u6709\u63cf\u8ff0\u7b26&#xff0c;\u90fd\u8981\u662f\u6d3b\u8dc3\u8fde\u63a5&#xff0c;\u2fae\u6d3b\u8dc3\u8fde\u63a5\u5c31\u8981\u53ca\u65f6\u91ca\u653e\u907f\u514d \u8d44\u6e90\u6d6a\u8d39\u3002 <\/span> <\/p>\n<p>            <span style=\"color:#1456f0\">\u2022 <\/span><br \/>\n            <span style=\"color:#1f2329\">EventLoop\u6a21\u5757\u5185\u90e8\u5305\u542b\u6709\u2f00\u4e2aeventfd&#xff1a;eventfd\u5176\u5b9e\u5c31\u662flinux\u5185\u6838\u63d0\u4f9b\u7684\u2f00\u4e2a\u4e8b\u4ef6fd&#xff0c;\u4e13\u2ed4\u2f64\u4e8e <\/span> <\/p>\n<p>            <span style=\"color:#1f2329\">\u4e8b\u4ef6\u901a\u77e5\u3002 <\/span> <\/p>\n<p>            <span style=\"color:#1456f0\">\u2022 <\/span><br \/>\n            <span style=\"color:#1f2329\">EventLoop\u6a21\u5757\u5185\u90e8\u5305\u542b\u6709\u2f00\u4e2aPoller\u5bf9\u8c61&#xff1a;\u2f64\u4e8e\u8fdb\u2f8f\u63cf\u8ff0\u7b26\u7684IO\u4e8b\u4ef6\u76d1\u63a7\u3002 <\/span> <\/p>\n<p>            <span style=\"color:#1456f0\">\u2022 <\/span><br \/>\n            <span style=\"color:#1f2329\">EventLoop\u6a21\u5757\u5185\u90e8\u5305\u542b\u6709\u2f00\u4e2aTimerQueue\u5bf9\u8c61&#xff1a;\u2f64\u4e8e\u8fdb\u2f8f\u5b9a\u65f6\u4efb\u52a1\u7684\u7ba1\u7406\u3002 <\/span> <\/p>\n<p>            <span style=\"color:#1456f0\">\u2022 <\/span><br \/>\n            <span style=\"color:#1f2329\">EventLoop\u6a21\u5757\u5185\u90e8\u5305\u542b\u6709\u2f00\u4e2aPendingTask\u961f\u5217&#xff1a;\u7ec4\u4ef6\u4f7f\u2f64\u8005\u5c06\u5bf9Connection\u8fdb\u2f8f\u7684\u6240\u6709\u64cd\u4f5c&#xff0c; \u90fd\u52a0\u2f0a\u5230\u4efb\u52a1\u961f\u5217\u4e2d&#xff0c;\u7531EventLoop\u6a21\u5757\u8fdb\u2f8f\u7ba1\u7406&#xff0c;\u5e76\u5728EventLoop\u5bf9\u5e94\u7684\u7ebf\u7a0b\u4e2d\u8fdb\u2f8f\u6267\u2f8f\u3002 <\/span> <\/p>\n<p>            <span style=\"color:#1456f0\">\u2022 <\/span><br \/>\n            <span style=\"color:#1f2329\">\u6bcf\u2f00\u4e2aConnection\u5bf9\u8c61\u90fd\u4f1a\u7ed1\u5b9a\u5230\u2f00\u4e2aEventLoop\u4e0a&#xff0c;\u8fd9\u6837\u80fd\u4fdd\u8bc1\u5bf9\u8fd9\u4e2a\u8fde\u63a5\u7684\u6240\u6709\u64cd\u4f5c\u90fd\u662f\u5728 <\/span> <\/p>\n<p>            <span style=\"color:#1f2329\">\u2f00\u4e2a\u7ebf\u7a0b\u4e2d\u5b8c\u6210\u7684\u3002 <\/span> <\/p>\n<p>            <span style=\"color:#1f2329\">\u5177\u4f53\u64cd\u4f5c\u6d41\u7a0b&#xff1a; <\/span> <\/p>\n<p>            <span style=\"color:#1456f0\">1. <\/span><br \/>\n            <span style=\"color:#1f2329\">\u901a\u8fc7Poller\u6a21\u5757\u5bf9\u5f53\u524d\u6a21\u5757\u7ba1\u7406\u5185\u7684\u6240\u6709\u63cf\u8ff0\u7b26\u8fdb\u2f8fIO\u4e8b\u4ef6\u76d1\u63a7&#xff0c;\u6709\u63cf\u8ff0\u7b26\u4e8b\u4ef6\u5c31\u7eea\u540e&#xff0c;\u901a\u8fc7\u63cf\u8ff0 \u7b26\u5bf9\u5e94\u7684Channel\u8fdb\u2f8f\u4e8b\u4ef6\u5904\u7406\u3002 <\/span> <\/p>\n<p>            <span style=\"color:#1456f0\">2. <\/span><br \/>\n            <span style=\"color:#1f2329\">\u6240\u6709\u5c31\u7eea\u7684\u63cf\u8ff0\u7b26IO\u4e8b\u4ef6\u5904\u7406\u5b8c\u6bd5\u540e&#xff0c;\u5bf9\u4efb\u52a1\u961f\u5217\u4e2d\u7684\u6240\u6709\u64cd\u4f5c\u987a\u5e8f\u8fdb\u2f8f\u6267\u2f8f\u3002 <\/span> <\/p>\n<p>            <span style=\"color:#1456f0\">3. <\/span><br \/>\n            <span style=\"color:#1f2329\">\u7531\u4e8eepoll\u7684\u4e8b\u4ef6\u76d1\u63a7&#xff0c;\u6709\u53ef\u80fd\u4f1a\u56e0\u4e3a\u6ca1\u6709\u4e8b\u4ef6\u5230\u6765\u2f7d\u6301\u7eed\u963b\u585e&#xff0c;\u5bfc\u81f4\u4efb\u52a1\u961f\u5217\u4e2d\u7684\u4efb\u52a1\u4e0d\u80fd\u53ca\u65f6\u5f97 \u5230\u6267\u2f8f&#xff0c;\u56e0\u6b64\u521b\u5efa\u4e86eventfd&#xff0c;\u6dfb\u52a0\u5230Poller\u7684\u4e8b\u4ef6\u76d1\u63a7\u4e2d&#xff0c;\u2f64\u4e8e\u5b9e\u73b0\u6bcf\u6b21\u5411\u4efb\u52a1\u961f\u5217\u6dfb\u52a0\u4efb\u52a1\u7684\u65f6 \u5019&#xff0c;\u901a\u8fc7\u5411eventfd\u5199\u2f0a\u6570\u636e\u6765\u5524\u9192epoll\u7684\u963b\u585e\u3002 <\/span> <\/p>\n<p>            <img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"766\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250418141245-68025ddde5f9b.png\" width=\"1200\" \/> <\/p>\n<h4><span style=\"color:#1f2329\">TcpServer\u6a21\u5757&#xff1a; <\/span><\/h4>\n<p>            <span style=\"color:#1f2329\">\u8fd9\u4e2a\u6a21\u5757\u662f\u2f00\u4e2a\u6574\u4f53Tcp\u670d\u52a1\u5668\u6a21\u5757\u7684\u5c01\u88c5&#xff0c;\u5185\u90e8\u5c01\u88c5\u4e86Acceptor\u6a21\u5757&#xff0c;EventLoopThreadPool\u6a21 <\/span> <\/p>\n<p>            <span style=\"color:#1f2329\">\u5757\u3002 <\/span> <\/p>\n<p>            <span style=\"color:#1456f0\">\u2022 <\/span><br \/>\n            <span style=\"color:#1f2329\">TcpServer\u4e2d\u5305\u542b\u6709\u2f00\u4e2aEventLoop\u5bf9\u8c61&#xff1a;\u4ee5\u5907\u5728\u8d85\u8f7b\u91cf\u4f7f\u2f64\u573a\u666f\u4e2d\u4e0d\u9700\u8981EventLoop\u7ebf\u7a0b\u6c60&#xff0c;\u53ea <\/span> <\/p>\n<p>            <span style=\"color:#1f2329\">\u9700\u8981\u5728\u4e3b\u7ebf\u7a0b\u4e2d\u5b8c\u6210\u6240\u6709\u64cd\u4f5c\u7684\u60c5\u51b5\u3002 <\/span> <\/p>\n<p>            <span style=\"color:#1456f0\">\u2022 <\/span><br \/>\n            <span style=\"color:#1f2329\">TcpServer\u6a21\u5757\u5185\u90e8\u5305\u542b\u6709\u2f00\u4e2aEventLoopThreadPool\u5bf9\u8c61&#xff1a;\u5176\u5b9e\u5c31\u662fEventLoop\u7ebf\u7a0b\u6c60&#xff0c;\u4e5f\u5c31\u662f <\/span> <\/p>\n<p>            <span style=\"color:#1f2329\">\u2f26Reactor\u7ebf\u7a0b\u6c60 <\/span> <\/p>\n<p>            <span style=\"color:#1456f0\">\u2022 <\/span><br \/>\n            <span style=\"color:#1f2329\">TcpServer\u6a21\u5757\u5185\u90e8\u5305\u542b\u6709\u2f00\u4e2aAcceptor\u5bf9\u8c61&#xff1a;\u2f00\u4e2aTcpServer\u670d\u52a1\u5668&#xff0c;\u5fc5\u7136\u5bf9\u5e94\u6709\u2f00\u4e2a\u76d1\u542c\u5957\u63a5 <\/span> <\/p>\n<p>            <span style=\"color:#1f2329\">\u5b57&#xff0c;\u80fd\u591f\u5b8c\u6210\u83b7\u53d6\u5ba2\u2f3e\u7aef\u65b0\u8fde\u63a5&#xff0c;\u5e76\u5904\u7406\u7684\u4efb\u52a1\u3002 <\/span> <\/p>\n<p>             <span style=\"color:#1456f0\">\u2022 <\/span><br \/>\n             <span style=\"color:#1f2329\">TcpServer\u6a21\u5757\u5185\u90e8\u5305\u542b\u6709\u2f00\u4e2astd::shared_ptr&lt;Connection&gt;\u7684hash\u8868&#xff1a;\u4fdd\u5b58\u4e86\u6240\u6709\u7684\u65b0\u5efa\u8fde\u63a5 <\/span> <\/p>\n<p>             <span style=\"color:#1f2329\">\u5bf9\u5e94\u7684Connection&#xff0c;\u6ce8\u610f&#xff0c;\u6240\u6709\u7684Connection\u4f7f\u2f64shared_ptr\u8fdb\u2f8f\u7ba1\u7406&#xff0c;\u8fd9\u6837\u80fd\u591f\u4fdd\u8bc1\u5728hash\u8868 <\/span> <\/p>\n<p>             <span style=\"color:#1f2329\">\u4e2d\u5220\u9664\u4e86Connection\u4fe1\u606f\u540e&#xff0c;\u5728shared_ptr\u8ba1\u6570\u5668\u4e3a0\u7684\u60c5\u51b5\u4e0b\u5b8c\u6210\u5bf9Connection\u8d44\u6e90\u7684\u91ca\u653e\u64cd <\/span> <\/p>\n<p>             <span style=\"color:#1f2329\">\u4f5c\u3002 <\/span> <\/p>\n<p>             <span style=\"color:#1f2329\">\u5177\u4f53\u64cd\u4f5c\u6d41\u7a0b\u5982\u4e0b&#xff1a; <\/span> <\/p>\n<p>             <span style=\"color:#1456f0\">1. <\/span><br \/>\n             <span style=\"color:#1f2329\">\u5728\u5b9e\u4f8b\u5316TcpServer\u5bf9\u8c61\u8fc7\u7a0b\u4e2d&#xff0c;\u5b8c\u6210BaseLoop\u7684\u8bbe\u7f6e&#xff0c;Acceptor\u5bf9\u8c61\u7684\u5b9e\u4f8b\u5316&#xff0c;\u4ee5\u53caEventLoop <\/span> <\/p>\n<p>             <span style=\"color:#1f2329\">\u7ebf\u7a0b\u6c60\u7684\u5b9e\u4f8b\u5316&#xff0c;\u4ee5\u53castd::shared_ptr&lt;Connection&gt;\u7684hash\u8868\u7684\u5b9e\u4f8b\u5316\u3002 <\/span> <\/p>\n<p>             <span style=\"color:#1456f0\">2. <\/span><br \/>\n             <span style=\"color:#1f2329\">\u4e3aAcceptor\u5bf9\u8c61\u8bbe\u7f6e\u56de\u8c03\u51fd\u6570&#xff1a;\u83b7\u53d6\u5230\u65b0\u8fde\u63a5\u540e&#xff0c;\u4e3a\u65b0\u8fde\u63a5\u6784\u5efaConnection\u5bf9\u8c61&#xff0c;\u8bbe\u7f6e <\/span> <\/p>\n<p>             <span style=\"color:#1f2329\">Connection\u7684\u5404\u9879\u56de\u8c03&#xff0c;\u5e76\u4f7f\u2f64shared_ptr\u8fdb\u2f8f\u7ba1\u7406&#xff0c;\u5e76\u6dfb\u52a0\u5230hash\u8868\u4e2d\u8fdb\u2f8f\u7ba1\u7406&#xff0c;\u5e76\u4e3a <\/span> <\/p>\n<p>             <span style=\"color:#1f2329\">Connection\u9009\u62e9\u2f00\u4e2aEventLoop\u7ebf\u7a0b&#xff0c;\u4e3aConnection\u6dfb\u52a0\u2f00\u4e2a\u5b9a\u65f6\u9500\u6bc1\u4efb\u52a1&#xff0c;\u4e3aConnection\u6dfb\u52a0 <\/span> <\/p>\n<p>             <span style=\"color:#1f2329\">\u4e8b\u4ef6\u76d1\u63a7&#xff0c; <\/span> <\/p>\n<p>             <span style=\"color:#1456f0\">3. <\/span><br \/>\n             <span style=\"color:#1f2329\">\u542f\u52a8BaseLoop\u3002<\/span> <\/p>\n<p>             <img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"553\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250418141246-68025dde913e5.png\" width=\"1200\" \/> <\/p>\n<p>              \u4e0b\u9762\u662f\u6a21\u5757\u4e4b\u95f4\u7684\u5173\u7cfb\u56fe <\/p>\n<h3 style=\"background-color:transparent\">\u6a21\u5757\u5173\u7cfb\u56fe<\/h3>\n<p>             <img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"2301\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250418141247-68025ddf2ad8a.png\" width=\"2822\" \/> <\/p>\n<h3><span style=\"color:#1f2329\">\u65f6\u95f4\u8f6e\u601d\u60f3&#xff1a; <\/span><\/h3>\n<p>              <span style=\"color:#1f2329\">\u4e0a\u8ff0\u7684\u4f8b\u2f26&#xff0c;\u5b58\u5728\u2f00\u4e2a\u5f88\u2f24\u7684\u95ee\u9898&#xff0c;\u6bcf\u6b21\u8d85\u65f6\u90fd\u8981\u5c06\u6240\u6709\u7684\u8fde\u63a5\u904d\u5386\u2f00\u904d&#xff0c;\u5982\u679c\u6709\u4e0a\u4e07\u4e2a\u8fde\u63a5&#xff0c;\u6548\u7387 \u2f46\u7591\u662f\u8f83\u4e3a\u4f4e\u4e0b\u7684\u3002 <\/span> <\/p>\n<p>              <span style=\"color:#1f2329\">\u8fd9\u65f6\u5019\u2f24\u5bb6\u5c31\u4f1a\u60f3\u5230&#xff0c;\u6211\u4eec\u53ef\u4ee5\u9488\u5bf9\u6240\u6709\u7684\u8fde\u63a5&#xff0c;\u6839\u636e\u6bcf\u4e2a\u8fde\u63a5\u6700\u8fd1\u2f00\u6b21\u901a\u4fe1\u7684\u7cfb\u7edf\u65f6\u95f4\u5efa\u2f74\u2f00\u4e2a\u2f29 \u6839\u5806&#xff0c;\u8fd9\u6837\u53ea\u9700\u8981\u6bcf\u6b21\u9488\u5bf9\u5806\u9876\u90e8\u5206\u7684\u8fde\u63a5\u9010\u4e2a\u91ca\u653e&#xff0c;\u76f4\u5230\u6ca1\u6709\u8d85\u65f6\u7684\u8fde\u63a5\u4e3a\u2f4c&#xff0c;\u8fd9\u6837\u4e5f\u53ef\u4ee5\u2f24\u2f24\u63d0 \u2fbc\u5904\u7406\u7684\u6548\u7387\u3002 <\/span> <\/p>\n<p>              <span style=\"color:#1f2329\">\u4e0a\u8ff0\u2f45\u6cd5\u53ef\u4ee5\u5b9e\u73b0\u5b9a\u65f6\u4efb\u52a1&#xff0c;\u4f46\u662f\u8fd9\u2fa5\u7ed9\u2f24\u5bb6\u4ecb\u7ecd\u53e6\u2f00\u79cd\u2f45\u6848&#xff1a;\u65f6\u95f4\u8f6e <\/span> <\/p>\n<p>              <span style=\"color:#1f2329\">\u65f6\u95f4\u8f6e\u7684\u601d\u60f3\u6765\u6e90\u4e8e\u949f\u8868&#xff0c;\u5982\u679c\u6211\u4eec\u5b9a\u4e86\u2f00\u4e2a3\u70b9\u949f\u7684\u95f9\u94c3&#xff0c;\u5219\u5f53\u65f6\u9488\u2f9b\u52303\u7684\u65f6\u5019&#xff0c;\u5c31\u4ee3\u8868\u65f6\u95f4\u5230 <\/span> <\/p>\n<p>              <span style=\"color:#1f2329\">\u4e86\u3002 \u540c\u6837\u7684\u9053\u7406&#xff0c;\u5982\u679c\u6211\u4eec\u5b9a\u4e49\u4e86\u2f00\u4e2a\u6570\u7ec4&#xff0c;\u5e76\u4e14\u6709\u2f00\u4e2a\u6307\u9488&#xff0c;\u6307\u5411\u6570\u7ec4\u8d77\u59cb\u4f4d\u7f6e&#xff0c;\u8fd9\u4e2a\u6307\u9488\u6bcf\u79d2\u949f\u5411\u540e \u2f9b\u52a8\u2f00\u6b65&#xff0c;\u2f9b\u5230\u54ea\u2fa5&#xff0c;\u5219\u4ee3\u8868\u54ea\u2fa5\u7684\u4efb\u52a1\u8be5\u88ab\u6267\u2f8f\u4e86&#xff0c;\u90a3\u4e48\u5982\u679c\u6211\u4eec\u60f3\u8981\u5b9a\u2f00\u4e2a3s\u540e\u7684\u4efb\u52a1&#xff0c;\u5219\u53ea\u9700 \u8981\u5c06\u4efb\u52a1\u6dfb\u52a0\u5230tick&#043;3\u4f4d\u7f6e&#xff0c;\u5219\u6bcf\u79d2\u4e2d\u2f9b\u2f00\u6b65&#xff0c;\u4e09\u79d2\u949f\u540etick\u2f9b\u5230\u5bf9\u5e94\u4f4d\u7f6e&#xff0c;\u8fd9\u65f6\u5019\u6267\u2f8f\u5bf9\u5e94\u4f4d\u7f6e\u7684\u4efb \u52a1\u5373\u53ef<\/span><br \/>\n              <span style=\"color:#1f2329\">\u4f46\u662f&#xff0c;\u540c\u2f00\u65f6\u95f4\u53ef\u80fd\u4f1a\u6709\u2f24\u6279\u91cf\u7684\u5b9a\u65f6\u4efb\u52a1&#xff0c;\u56e0\u6b64\u6211\u4eec\u53ef\u4ee5\u7ed9\u6570\u7ec4\u5bf9\u5e94\u4f4d\u7f6e\u4e0b\u62c9\u2f00\u4e2a\u6570\u7ec4&#xff0c;\u8fd9\u6837\u5c31\u53ef<\/span><br \/>\n              <span style=\"color:#1f2329\">\u4ee5\u5728\u540c\u2f00\u4e2a\u65f6\u523b\u4e0a\u6dfb\u52a0\u591a\u4e2a\u5b9a\u65f6\u4efb\u52a1\u4e86\u3002<\/span> <\/p>\n<p>              <img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"675\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250418141250-68025de2ada90.png\" width=\"1030\" \/> <\/p>\n<p>               <span style=\"color:#1f2329\">\u5f53\u7136&#xff0c;\u4e0a\u8ff0\u64cd\u4f5c\u4e5f\u6709\u2f00\u4e9b\u7f3a\u9677&#xff0c;\u2f50\u5982\u6211\u4eec\u5982\u679c\u8981\u5b9a\u4e49\u2f00\u4e2a60s\u540e\u7684\u4efb\u52a1&#xff0c;\u5219\u9700\u8981\u5c06\u6570\u7ec4\u7684\u5143\u7d20\u4e2a\u6570\u8bbe\u7f6e \u4e3a60\u624d\u53ef\u4ee5&#xff0c;\u5982\u679c\u8bbe\u7f6e\u2f00\u2f29\u65f6\u540e\u7684\u5b9a\u65f6\u4efb\u52a1&#xff0c;\u5219\u9700\u8981\u5b9a\u4e493600\u4e2a\u5143\u7d20\u7684\u6570\u7ec4&#xff0c;\u8fd9\u6837\u2f46\u7591\u662f\u2f50\u8f83\u2fc7\u70e6 \u7684\u3002 <\/span> <\/p>\n<p>               <span style=\"color:#1f2329\">\u56e0\u6b64&#xff0c;\u53ef\u4ee5\u91c7\u2f64\u591a\u5c42\u7ea7\u7684\u65f6\u95f4\u8f6e&#xff0c;\u6709\u79d2\u9488\u8f6e&#xff0c;\u5206\u9488\u8f6e&#xff0c;\u65f6\u9488\u8f6e&#xff0c; 60&lt;time&lt;3600\u5219time\/60\u5c31\u662f\u5206\u9488\u8f6e \u5bf9\u5e94\u5b58\u50a8\u7684\u4f4d\u7f6e&#xff0c;\u5f53tick\/3600\u7b49\u4e8e\u5bf9\u5e94\u4f4d\u7f6e\u7684\u65f6\u5019&#xff0c;\u5c06\u5176\u4f4d\u7f6e\u7684\u4efb\u52a1\u5411\u5206\u9488&#xff0c;\u79d2\u9488\u8f6e\u8fdb\u2f8f\u79fb\u52a8\u3002 \u56e0\u4e3a\u5f53\u524d\u6211\u4eec\u7684\u5e94\u2f64\u4e2d&#xff0c;\u5012\u662f\u4e0d\u2f64\u8bbe\u8ba1\u7684\u8fd9\u4e48\u2fc7\u70e6&#xff0c;\u56e0\u4e3a\u6211\u4eec\u7684\u5b9a\u65f6\u4efb\u52a1\u901a\u5e38\u8bbe\u7f6e\u768430s\u4ee5\u5185&#xff0c;\u6240\u4ee5\u7b80 \u5355\u7684\u5355\u5c42\u65f6\u95f4\u8f6e\u5c31\u591f\u2f64\u4e86\u3002 <\/span> <\/p>\n<p>               <span style=\"color:#1f2329\">\u4f46\u662f&#xff0c;\u6211\u4eec\u4e5f\u5f97\u8003\u8651\u2f00\u4e2a\u95ee\u9898&#xff0c;\u5f53\u524d\u7684\u8bbe\u8ba1\u662f\u65f6\u95f4\u5230\u4e86&#xff0c;\u5219\u4e3b\u52a8\u53bb\u6267\u2f8f\u5b9a\u65f6\u4efb\u52a1&#xff0c;\u91ca\u653e\u8fde\u63a5&#xff0c;\u90a3\u80fd\u4e0d \u80fd\u5728\u65f6\u95f4\u5230\u4e86\u540e&#xff0c;\u2f83\u52a8\u6267\u2f8f\u5b9a\u65f6\u4efb\u52a1\u5462&#xff0c;\u8fd9\u65f6\u5019\u6211\u4eec\u5c31\u60f3\u5230\u2f00\u4e2a\u64cd\u4f5c-\u7c7b\u7684\u6790\u6784\u51fd\u6570\u3002 <\/span> <\/p>\n<p>               <span style=\"color:#1f2329\">\u2f00\u4e2a\u7c7b\u7684\u6790\u6784\u51fd\u6570&#xff0c;\u5728\u5bf9\u8c61\u88ab\u91ca\u653e\u65f6\u4f1a\u2f83\u52a8\u88ab\u6267\u2f8f&#xff0c;\u90a3\u4e48\u6211\u4eec\u5982\u679c\u5c06\u2f00\u4e2a\u5b9a\u65f6\u4efb\u52a1\u4f5c\u4e3a\u2f00\u4e2a\u7c7b\u7684\u6790\u6784 \u51fd\u6570\u5185\u7684\u64cd\u4f5c&#xff0c;\u5219\u8fd9\u4e2a\u5b9a\u65f6\u4efb\u52a1\u5728\u5bf9\u8c61\u88ab\u91ca\u653e\u7684\u65f6\u5019\u5c31\u4f1a\u6267\u2f8f\u3002 <\/span> <\/p>\n<p>               <span style=\"color:#1f2329\">\u4f46\u662f\u4ec5\u4ec5\u4e3a\u4e86\u8fd9\u4e2a\u2f6c\u7684&#xff0c;\u2f7d\u8bbe\u8ba1\u2f00\u4e2a\u989d\u5916\u7684\u4efb\u52a1\u7c7b&#xff0c;\u597d\u50cf\u6709\u4e9b\u4e0d\u5212\u7b97&#xff0c;\u4f46\u662f&#xff0c;\u8fd9\u2fa5\u6211\u4eec\u2f1c\u8981\u8003\u8651\u53e6\u2f00 \u4e2a\u95ee\u9898&#xff0c;\u90a3\u5c31\u662f\u5047\u5982\u6709\u2f00\u4e2a\u8fde\u63a5\u5efa\u2f74\u6210\u529f\u4e86&#xff0c;\u6211\u4eec\u7ed9\u8fd9\u4e2a\u8fde\u63a5\u8bbe\u7f6e\u4e86\u2f00\u4e2a30s\u540e\u7684\u5b9a\u65f6\u9500\u6bc1\u4efb\u52a1&#xff0c;\u4f46\u662f <\/span> <\/p>\n<p>               <span style=\"color:#1f2329\">\u5728\u7b2c10s\u7684\u65f6\u5019&#xff0c;\u8fd9\u4e2a\u8fde\u63a5\u8fdb\u2f8f\u4e86\u2f00\u6b21\u901a\u4fe1&#xff0c;\u90a3\u4e48\u6211\u4eec\u5e94\u8be5\u65f6\u5728\u7b2c30s\u7684\u65f6\u5019\u5173\u95ed&#xff0c;\u8fd8\u662f\u7b2c40s\u7684\u65f6\u5019\u5173 \u95ed\u5462&#xff1f;\u2f46\u7591\u5e94\u8be5\u662f\u7b2c40s\u7684\u65f6\u5019\u3002\u4e5f\u5c31\u662f\u8bf4&#xff0c;\u8fd9\u65f6\u5019&#xff0c;\u6211\u4eec\u9700\u8981\u8ba9\u8fd9\u4e2a\u7b2c30s\u7684\u4efb\u52a1\u5931\u6548&#xff0c;\u4f46\u662f\u6211\u4eec\u8be5 \u5982\u4f55\u5b9e\u73b0\u8fd9\u4e2a\u64cd\u4f5c\u5462&#xff1f; <\/span> <\/p>\n<p>               <span style=\"color:#1f2329\">\u8fd9\u2fa5&#xff0c;\u6211\u4eec\u5c31\u2f64\u5230\u4e86\u667a\u80fd\u6307\u9488shared_ptr&#xff0c;shared_ptr\u6709\u4e2a\u8ba1\u6570\u5668&#xff0c;\u5f53\u8ba1\u6570\u4e3a0\u7684\u65f6\u5019&#xff0c;\u624d\u4f1a\u771f\u6b63\u91ca\u653e \u2f00\u4e2a\u5bf9\u8c61&#xff0c;\u90a3\u4e48\u5982\u679c\u8fde\u63a5\u5728\u7b2c10s\u8fdb\u2f8f\u4e86\u2f00\u6b21\u901a\u4fe1&#xff0c;\u5219\u6211\u4eec\u7ee7\u7eed\u5411\u5b9a\u65f6\u4efb\u52a1\u4e2d&#xff0c;\u6dfb\u52a0\u2f00\u4e2a30s\u540e&#xff08;\u4e5f\u5c31 <\/span> <\/p>\n<p>               <span style=\"color:#1f2329\">\u662f\u7b2c40s&#xff09;\u7684\u4efb\u52a1\u7c7b\u5bf9\u8c61\u7684shared_ptr&#xff0c;\u5219\u8fd9\u65f6\u5019\u4e24\u4e2a\u4efb\u52a1shared_ptr\u8ba1\u6570\u4e3a2&#xff0c;\u5219\u7b2c30s\u7684\u5b9a\u65f6\u4efb\u52a1 \u88ab\u91ca\u653e\u7684\u65f6\u5019&#xff0c;\u8ba1\u6570-1&#xff0c;\u53d8\u4e3a1&#xff0c;\u5e76\u4e0d\u4e3a0&#xff0c;\u5219\u5e76\u4e0d\u4f1a\u6267\u2f8f\u5b9e\u9645\u7684\u6790\u6784\u51fd\u6570&#xff0c;\u90a3\u4e48\u5c31\u76f8\u5f53\u4e8e\u8fd9\u4e2a\u7b2c30s\u7684 \u4efb\u52a1\u5931\u6548\u4e86&#xff0c;\u53ea\u6709\u5728\u7b2c40s\u7684\u65f6\u5019&#xff0c;\u8fd9\u4e2a\u4efb\u52a1\u624d\u4f1a\u88ab\u771f\u6b63\u91ca\u653e\u3002 <\/span> <\/p>\n<p>                <span style=\"color:#1f2329\">\u4e0a\u8ff0\u8fc7\u7a0b\u5c31\u662f\u65f6\u95f4\u8f6e\u5b9a\u65f6\u4efb\u52a1\u7684\u601d\u60f3\u4e86&#xff0c;\u5f53\u7136\u8fd9\u2fa5\u4e3a\u4e86\u66f4\u52a0\u7b80\u4fbf\u7684\u5b9e\u73b0&#xff0c;\u8fdb\u2f8f\u4e86\u2f00\u4e9b\u2f29\u2f29\u7684\u8c03\u6574\u5b9e <\/span> <\/p>\n<p>                <span style=\"color:#1f2329\">\u73b0\u3002<\/span> <\/p>\n<p>                <span style=\"color:#1f2329\">\u5177\u4f53\u6a21\u5757\u5b9e\u73b0\u4ee3\u7801\u5982\u4e0b<\/span> <\/p>\n<p>                #include &lt;iostream&gt;<br \/>\n#include &lt;vector&gt;<br \/>\n#include &lt;unordered_map&gt;<br \/>\n#include &lt;functional&gt;<br \/>\n#include &lt;cstdint&gt;<br \/>\n#include &lt;memory&gt;<br \/>\n#include &lt;unistd.h&gt;<\/p>\n<p>using TaskFunc &#061; std::function&lt;void()&gt;;<br \/>\nusing ReleaseFunc &#061; std::function&lt;void()&gt;;<br \/>\nclass TimerTask<br \/>\n{<br \/>\n    uint64_t _id;         \/\/ \u5b9a\u65f6\u5668\u7684ID<br \/>\n    uint64_t _timeout;    \/\/ \u8d85\u65f6\u65f6\u95f4<br \/>\n    bool _canceled;       \/\/\u53d6\u6d88\u5b9a\u65f6\u4efb\u52a1<br \/>\n    TaskFunc _task_cb;    \/\/ \u56de\u8c03\u51fd\u6570\u7684\u4efb\u52a1<br \/>\n    ReleaseFunc _release; \/\/ \u6e05\u695a\u65f6\u95f4\u8f6e\u4e2d\u7684\u8bb0\u5f55<\/p>\n<p>public:<br \/>\n    TimerTask(uint64_t id, uint64_t timeout, TaskFunc cb)<br \/>\n        : _id(id),<br \/>\n          _timeout(timeout),<br \/>\n          _task_cb(cb),<br \/>\n          _canceled(false)<br \/>\n    {<br \/>\n    }<\/p>\n<p>    void SetRelease(ReleaseFunc release)<br \/>\n    {<br \/>\n        _release &#061; release;<br \/>\n    }<\/p>\n<p>    ~TimerTask()<br \/>\n    {<br \/>\n        if(!_canceled)<br \/>\n        _task_cb();<br \/>\n        _release();<br \/>\n    }<\/p>\n<p>    void Cancel()<br \/>\n    {<br \/>\n        _canceled&#061;true;<br \/>\n    }<\/p>\n<p>    uint32_t DelayTime()<br \/>\n    {<br \/>\n        return _timeout;<br \/>\n    }<br \/>\n};<\/p>\n<p>class TimeWheel<br \/>\n{<br \/>\nprivate:<br \/>\n    using WeakTask &#061; std::weak_ptr&lt;TimerTask&gt;;<br \/>\n    using PtrTask &#061; std::shared_ptr&lt;TimerTask&gt;;<br \/>\n    int _tick;                                      \/\/ \u79d2\u9488<br \/>\n    int _capacity;                                  \/\/ \u6700\u5927\u5b9a\u65f6\u65f6\u95f4<br \/>\n    std::vector&lt;std::vector&lt;PtrTask&gt;&gt; _timeWheel;   \/\/ \u65f6\u95f4\u8f6e<br \/>\n    std::unordered_map&lt;uint32_t, WeakTask&gt; _timers; \/\/ \u7528\u6765\u4fdd\u5b58\u5b9a\u65f6\u5668\u7684\u4fe1\u606f<br \/>\nprivate:<br \/>\n    void RemoveTimer(uint64_t id)<br \/>\n    {<br \/>\n        auto it &#061; _timers.find(id);<br \/>\n        if (it !&#061; _timers.end())<br \/>\n        {<br \/>\n            _timers.erase(it);<br \/>\n        }<br \/>\n    }<\/p>\n<p>public:<br \/>\n    TimeWheel()<br \/>\n        : _tick(0),<br \/>\n          _capacity(60),<br \/>\n          _timeWheel(_capacity)<br \/>\n    {<br \/>\n    }<\/p>\n<p>    void TimerAdd(uint64_t id, uint64_t timeout, TaskFunc cb)<br \/>\n    {<br \/>\n        PtrTask pt(new TimerTask(id, timeout, cb));                   \/\/ \u521b\u5efa\u4efb\u52a1<\/p>\n<p>        pt-&gt;SetRelease(std::bind(&amp;TimeWheel::RemoveTimer, this, id)); \/\/ \u8bbe\u7f6e\u5220\u9664\u51fd\u6570\u56de\u8c03<br \/>\n        int pos &#061; (_tick &#043; pt-&gt;DelayTime()) % _capacity;              \/\/ \u627e\u5230\u8981\u63d2\u5165\u5230\u65f6\u95f4\u8f6e\u7684\u4f4d\u7f6e<br \/>\n        _timeWheel[pos].push_back(pt);                                \/\/ \u63d2\u5165\u65f6\u95f4\u8f6e<br \/>\n        _timers[id] &#061; WeakTask(pt);                                   \/\/ \u4fdd\u5b58\u5b9a\u65f6\u5668\u7684\u4fe1\u606f<br \/>\n    }<\/p>\n<p>    void TimerRefresh(uint64_t id)<br \/>\n    {<br \/>\n        auto it &#061; _timers.find(id);<br \/>\n        if (it &#061;&#061; _timers.end())<br \/>\n        {<br \/>\n            return; \/\/ \u6ca1\u627e\u7740\u5b9a\u65f6\u4efb\u52a1&#xff0c;\u6ca1\u6cd5\u5237\u65b0&#xff0c;\u6ca1\u6cd5\u5ef6\u8fdf<br \/>\n        }<br \/>\n        PtrTask pt &#061; it-&gt;second.lock();<br \/>\n        int pos &#061; (_tick &#043; pt-&gt;DelayTime()) % _capacity; \/\/ \u627e\u5230\u8981\u63d2\u5165\u5230\u65f6\u95f4\u8f6e\u7684\u4f4d\u7f6e<br \/>\n        _timeWheel[pos].push_back(pt);                   \/\/ \u63d2\u5165\u65f6\u95f4\u8f6e<br \/>\n    }<\/p>\n<p>    void TimerCancel(uint64_t id)<br \/>\n    {<br \/>\n        auto it &#061; _timers.find(id);<br \/>\n        if (it &#061;&#061; _timers.end())<br \/>\n        {<br \/>\n            return; \/\/ \u6ca1\u627e\u7740\u5b9a\u65f6\u4efb\u52a1&#xff0c;\u6ca1\u6cd5\u5237\u65b0&#xff0c;\u6ca1\u6cd5\u5ef6\u8fdf<br \/>\n        }<\/p>\n<p>        PtrTask pt&#061;it-&gt;second.lock();<br \/>\n        pt-&gt;Cancel();<\/p>\n<p>    }<\/p>\n<p>    void RunTimerTask()<br \/>\n    {<br \/>\n        _tick&#061;(_tick&#043;1)%_capacity;<br \/>\n        _timeWheel[_tick].clear();<br \/>\n    }<br \/>\n};<\/p>\n<p>\/\/\u6d4b\u8bd5\u4ee3\u7801<br \/>\n\/*<br \/>\nclass Test {<br \/>\n    public:<br \/>\n        Test() {std::cout &lt;&lt; &#034;\u6784\u9020&#034; &lt;&lt; std::endl;}<br \/>\n        ~Test() {std::cout &lt;&lt; &#034;\u6790\u6784&#034; &lt;&lt; std::endl;}<br \/>\n};<\/p>\n<p>void DelTest(Test *t) {<br \/>\n    delete t;<br \/>\n}<\/p>\n<p>int main()<br \/>\n{<br \/>\n    TimeWheel tw;<\/p>\n<p>    Test *t &#061; new Test();<br \/>\n    std::cout&lt;&lt;1&lt;&lt;std::endl;<br \/>\n    tw.TimerAdd(888, 5, std::bind(DelTest, t));<\/p>\n<p>    for(int i &#061; 0; i &lt; 5; i&#043;&#043;) {<br \/>\n        sleep(1);<br \/>\n        \/\/std::cout&lt;&lt;1&lt;&lt;std::endl;<br \/>\n        tw.TimerRefresh(888);\/\/\u5237\u65b0\u5b9a\u65f6\u4efb\u52a1<br \/>\n        \/\/std::cout&lt;&lt;2&lt;&lt;std::endl;<br \/>\n        tw.RunTimerTask();\/\/\u5411\u540e\u79fb\u52a8\u79d2\u9488<\/p>\n<p>        std::cout &lt;&lt; &#034;\u5237\u65b0\u4e86\u4e00\u4e0b\u5b9a\u65f6\u4efb\u52a1&#xff0c;\u91cd\u65b0\u9700\u89815s\u4e2d\u540e\u624d\u4f1a\u9500\u6bc1\\\\n&#034;;<br \/>\n    }<br \/>\n    \/\/tw.TimerCancel(888);<br \/>\n    while(1) {<br \/>\n        sleep(1);<br \/>\n        std::cout &lt;&lt; &#034;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-\\\\n&#034;;<br \/>\n        tw.RunTimerTask();\/\/\u5411\u540e\u79fb\u52a8\u79d2\u9488<br \/>\n    }<br \/>\n    return 0;<br \/>\n}*\/ <\/p>\n<h3><span style=\"color:#1f2329\">\u6b63\u5219\u5e93\u7684\u7b80\u5355\u4f7f\u2f64&#xff1a; <\/span><\/h3>\n<p>                 <span style=\"color:#1f2329\">\u6b63\u5219\u8868\u8fbe\u5f0f(regular expression)\u63cf\u8ff0\u4e86\u2f00\u79cd\u5b57\u7b26\u4e32\u5339\u914d\u7684\u6a21\u5f0f&#xff08;pattern&#xff09;&#xff0c;\u53ef\u4ee5\u2f64\u6765\u68c0\u67e5\u2f00\u4e2a\u4e32\u662f\u5426 \u542b\u6709\u67d0\u79cd\u2f26\u4e32\u3001\u5c06\u5339\u914d\u7684\u2f26\u4e32\u66ff\u6362\u6216\u8005\u4ece\u67d0\u4e2a\u4e32\u4e2d\u53d6\u51fa\u7b26\u5408\u67d0\u4e2a\u6761\u4ef6\u7684\u2f26\u4e32\u7b49\u3002 <\/span> <\/p>\n<p>                 <span style=\"color:#1f2329\">\u6b63\u5219\u8868\u8fbe\u5f0f\u7684\u4f7f\u2f64&#xff0c;\u53ef\u4ee5\u4f7f\u5f97HTTP\u8bf7\u6c42\u7684\u89e3\u6790\u66f4\u52a0\u7b80\u5355&#xff08;\u8fd9\u2fa5\u6307\u7684\u65f6\u7a0b\u5e8f\u5458\u7684\u2f2f\u4f5c\u53d8\u5f97\u7684\u7b80\u5355&#xff0c;\u8fd9\u5e76 \u4e0d\u4ee3\u8868\u5904\u7406\u6548\u7387\u4f1a\u53d8\u2fbc&#xff0c;\u5b9e\u9645\u4e0a\u6548\u7387\u4e0a\u662f\u4f4e\u4e8e\u76f4\u63a5\u7684\u5b57\u7b26\u4e32\u5904\u7406\u7684&#xff09;&#xff0c;\u4f7f\u6211\u4eec\u5b9e\u73b0\u7684HTTP\u7ec4\u4ef6\u5e93\u4f7f\u2f64 \u8d77\u6765\u66f4\u52a0\u7075\u6d3b\u3002<\/span> <\/p>\n<p>                 <img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"247\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250418141251-68025de30948d.png\" width=\"680\" \/>. <\/p>\n<p>                  \u4f8b\u5982\u4e0b\u56fe\u5c31\u662f\u4e00\u4e2a\u5173\u4e8e\u6b63\u5219\u8868\u8fbe\u5f0f\u4f7f\u7528\u7684\u6848\u4f8b&#xff0c;\u66f4\u591a\u7684\u89c4\u5219\u53ef\u4ee5\u6839\u636e\u9700\u6c42\u53bb\u67e5\u8be2\u3002 <\/p>\n<p>                 <img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"816\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250418141251-68025de34cf0e.png\" width=\"1200\" \/> <\/p>\n<h3 style=\"background-color:transparent\"><span style=\"color:#1f2329\">\u901a\u2f64\u7c7b\u578bany\u7c7b\u578b\u7684\u5b9e\u73b0&#xff1a; <\/span><\/h3>\n<p>                  <span style=\"color:#1f2329\">\u6bcf\u2f00\u4e2aConnection\u5bf9\u8fde\u63a5\u8fdb\u2f8f\u7ba1\u7406&#xff0c;\u6700\u7ec8\u90fd\u4e0d\u53ef\u907f\u514d\u9700\u8981\u6d89\u53ca\u5230\u5e94\u2f64\u5c42\u534f\u8bae\u7684\u5904\u7406&#xff0c;\u56e0\u6b64\u5728 <\/span> <\/p>\n<p>                  <span style=\"color:#1f2329\">Connection\u4e2d\u9700\u8981\u8bbe\u7f6e\u534f\u8bae\u5904\u7406\u7684\u4e0a\u4e0b\u2f42\u6765\u63a7\u5236\u5904\u7406\u8282\u594f\u3002\u4f46\u662f\u5e94\u2f64\u5c42\u534f\u8bae\u5343\u5343\u4e07&#xff0c;\u4e3a\u4e86\u964d\u4f4e\u8026\u5408 <\/span> <\/p>\n<p>                  <span style=\"color:#1f2329\">\u5ea6&#xff0c;\u8fd9\u4e2a\u534f\u8bae\u63a5\u6536\u89e3\u6790\u4e0a\u4e0b\u2f42\u5c31\u4e0d\u80fd\u6709\u660e\u663e\u7684\u534f\u8bae\u503e\u5411&#xff0c;\u5b83\u53ef\u4ee5\u662f\u4efb\u610f\u534f\u8bae\u7684\u4e0a\u4e0b\u2f42\u4fe1\u606f&#xff0c;\u56e0\u6b64\u5c31\u9700 \u8981\u2f00\u4e2a\u901a\u2f64\u7684\u7c7b\u578b\u6765\u4fdd\u5b58\u5404\u79cd\u4e0d\u540c\u7684\u6570\u636e\u7ed3\u6784\u3002 <\/span> <\/p>\n<p>                  <span style=\"color:#1f2329\">\u5728C\u8bed\u2f94\u4e2d&#xff0c;\u901a\u2f64\u7c7b\u578b\u53ef\u4ee5\u4f7f\u2f64void*\u6765\u7ba1\u7406&#xff0c;\u4f46\u662f\u5728C&#043;&#043;\u4e2d&#xff0c;boost\u5e93\u548cC&#043;&#043;17\u7ed9\u6211\u4eec\u63d0\u4f9b\u4e86\u2f00\u4e2a\u901a\u2f64 \u7c7b\u578bany\u6765\u7075\u6d3b\u4f7f\u2f64&#xff0c;\u5982\u679c\u8003\u8651\u589e\u52a0\u4ee3\u7801\u7684\u79fb\u690d\u6027&#xff0c;\u5c3d\u91cf\u51cf\u5c11\u7b2c\u4e09\u2f45\u5e93\u7684\u4f9d\u8d56&#xff0c;\u5219\u53ef\u4ee5\u4f7f\u2f64C&#043;&#043;17\u7279\u6027\u4e2d\u7684any&#xff0c;\u6216\u8005\u2f83\u2f30\u6765\u5b9e\u73b0\u3002\u2f7d\u8fd9\u4e2aany\u901a\u2f64\u7c7b\u578b\u7c7b\u7684\u5b9e\u73b0\u5176\u5b9e\u5e76\u4e0d\u590d\u6742&#xff0c;\u4ee5\u4e0b\u662f\u7b80\u5355\u7684\u90e8\u5206\u5b9e\u73b0\u3002 <\/span> <\/p>\n<p>                  <span style=\"color:#1f2329\">\u4e3b\u8981\u8bbe\u8ba1\u601d\u8def\u5982\u4e0b\u56fe<\/span> <\/p>\n<p>                  <img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"675\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250418141251-68025de3a92f7.png\" width=\"1200\" \/> <\/p>\n<p>                   <span style=\"color:#a0a1a7\">\u2fb8\u5148<\/span><span style=\"color:#a0a1a7\">Any<\/span><span style=\"color:#a0a1a7\">\u7c7b\u80af\u5b9a\u4e0d\u80fd\u662f\u2f00\u4e2a\u6a21\u677f\u7c7b&#xff0c;\u5426\u5219\u7f16\u8bd1\u7684\u65f6\u5019<\/span><span style=\"color:#a0a1a7\"> Any&lt;int&gt; a, Any&lt;float&gt;b,<\/span><span style=\"color:#a0a1a7\">\u9700\u8981\u4f20\u7c7b\u578b\u4f5c <\/span> <\/p>\n<p>                   <span style=\"color:#a0a1a7\">\u4e3a\u6a21\u677f\u53c2\u6570&#xff0c;\u4e5f\u5c31\u662f\u8bf4\u5728\u4f7f\u2f64\u7684\u65f6\u5019\u5c31\u8981\u786e\u5b9a\u5176\u7c7b\u578b<\/span> <\/p>\n<p>                   <span style=\"color:#a0a1a7\">\u8fd9\u662f\u2f8f\u4e0d\u901a\u7684&#xff0c;\u56e0\u4e3a\u4fdd\u5b58\u5728<\/span><span style=\"color:#a0a1a7\">Content<\/span><span style=\"color:#a0a1a7\">\u4e2d\u7684\u534f\u8bae\u4e0a\u4e0b\u2f42&#xff0c;\u6211\u4eec\u5728\u5b9a\u4e49<\/span><span style=\"color:#a0a1a7\">any<\/span><span style=\"color:#a0a1a7\">\u5bf9\u8c61\u7684\u65f6\u5019\u662f\u4e0d\u77e5\u9053\u4ed6\u4eec\u7684\u534f <\/span><br \/>\n                   <span style=\"color:#a0a1a7\">\u8bae\u7c7b\u578b\u7684&#xff0c;\u56e0\u6b64\u2f46\u6cd5\u4f20\u9012\u7c7b\u578b\u4f5c\u4e3a\u6a21\u677f\u53c2\u6570<\/span> <\/p>\n<p>                   <span style=\"color:#a0a1a7\">\u56e0\u6b64\u8003\u8651<\/span><span style=\"color:#a0a1a7\">Any<\/span><span style=\"color:#a0a1a7\">\u5185\u90e8\u8bbe\u8ba1\u2f00\u4e2a\u6a21\u677f\u5bb9\u5668<\/span><span style=\"color:#a0a1a7\">holder<\/span><span style=\"color:#a0a1a7\">\u7c7b&#xff0c;\u53ef\u4ee5\u4fdd\u5b58\u5404\u79cd\u7c7b\u578b\u6570\u636e<\/span> <\/p>\n<p>                   <span style=\"color:#a0a1a7\">\u2f7d\u56e0\u4e3a\u5728<\/span><span style=\"color:#a0a1a7\">Any<\/span><span style=\"color:#a0a1a7\">\u7c7b\u4e2d\u2f46\u6cd5\u5b9a\u4e49\u8fd9\u4e2a<\/span><span style=\"color:#a0a1a7\">holder<\/span><span style=\"color:#a0a1a7\">\u5bf9\u8c61\u6216\u6307\u9488&#xff0c;\u56e0\u4e3a<\/span><span style=\"color:#a0a1a7\">any<\/span><span style=\"color:#a0a1a7\">\u4e5f\u4e0d\u77e5\u9053\u8fd9\u4e2a\u7c7b\u8981\u4fdd\u5b58\u4ec0\u4e48\u7c7b\u578b\u7684\u6570 <\/span> <\/p>\n<p>                   <span style=\"color:#a0a1a7\">\u636e&#xff0c;\u56e0\u6b64\u2f46\u6cd5\u4f20\u9012\u7c7b\u578b\u53c2\u6570<\/span><br \/>\n                   <span style=\"color:#a0a1a7\">\u6240\u4ee5&#xff0c;\u5b9a\u4e49\u2f00\u4e2a\u57fa\u7c7b<\/span><span style=\"color:#a0a1a7\">placehoder<\/span><span style=\"color:#a0a1a7\">&#xff0c;\u8ba9<\/span><span style=\"color:#a0a1a7\">holder<\/span><span style=\"color:#a0a1a7\">\u7ee7\u627f\u4e8e<\/span><span style=\"color:#a0a1a7\">placeholde<\/span><span style=\"color:#a0a1a7\">&#xff0c;\u2f7d<\/span><span style=\"color:#a0a1a7\">Any<\/span><span style=\"color:#a0a1a7\">\u7c7b\u4fdd\u5b58\u2f57\u7c7b\u6307\u9488\u5373\u53ef<\/span><br \/>\n                   <span style=\"color:#a0a1a7\">\u5f53\u9700\u8981\u4fdd\u5b58\u6570\u636e\u65f6&#xff0c;\u5219<\/span><span style=\"color:#a0a1a7\">new<\/span><span style=\"color:#a0a1a7\">\u2f00\u4e2a\u5e26\u6709\u6a21\u677f\u53c2\u6570\u7684\u2f26\u7c7b<\/span><span style=\"color:#a0a1a7\">holder<\/span><span style=\"color:#a0a1a7\">\u5bf9\u8c61\u51fa\u6765\u4fdd\u5b58\u6570\u636e&#xff0c;\u7136\u540e\u8ba9<\/span><span style=\"color:#a0a1a7\">Any<\/span><span style=\"color:#a0a1a7\">\u7c7b\u4e2d\u7684\u2f57 <\/span><span style=\"color:#a0a1a7\">\u7c7b\u6307\u9488&#xff0c;\u6307\u5411\u8fd9\u4e2a\u2f26\u7c7b\u5bf9\u8c61\u5c31\u641e\u5b9a\u4e86<\/span> <\/p>\n<p>                   #include &lt;iostream&gt;<br \/>\n#include &lt;typeinfo&gt;<br \/>\n#include &lt;string&gt;<br \/>\nclass Any<br \/>\n{<br \/>\nprivate:<br \/>\n    class holder<br \/>\n    {<br \/>\n    public:<br \/>\n        holder(){}<br \/>\n        virtual const std::type_info &amp;type() &#061; 0; \/\/ \u8fd4\u56de\u4fdd\u5b58\u6570\u636e\u7684\u7c7b\u578b<br \/>\n        virtual holder *clone() &#061; 0;              \/\/ \u514b\u9686\u81ea\u8eab<br \/>\n    };<\/p>\n<p>    template &lt;class T&gt;<br \/>\n    class placeHolder : public holder<br \/>\n    {<br \/>\n    public:<br \/>\n        placeHolder(const T &amp;val)<br \/>\n            : _val(val)<br \/>\n        {<br \/>\n        }<\/p>\n<p>        virtual const std::type_info &amp;type()<br \/>\n        {<br \/>\n            return typeid(_val);<br \/>\n        }<\/p>\n<p>        virtual placeHolder *clone()<br \/>\n        {<br \/>\n            return new placeHolder(_val);<br \/>\n        }<\/p>\n<p>        T _val;<br \/>\n    };<br \/>\n    holder *_content;<\/p>\n<p>public:<br \/>\n    \/\/\u65e0\u53c2\u6784\u9020<br \/>\n    Any() : _content(nullptr) {}<br \/>\n    \/\/\u6709\u53c2\u6784\u9020<br \/>\n    template &lt;class T&gt;<br \/>\n    Any(const T val)<br \/>\n        : _content(new placeHolder&lt;T&gt;(val))<br \/>\n    {<br \/>\n    }<\/p>\n<p>    \/\/\u514b\u9686\u51fd\u6570<br \/>\n    Any(const Any &amp;other)<br \/>\n        : _content(other._content &#061;&#061; nullptr ? nullptr : other._content-&gt;clone()) {} \/\/ \u8fd9\u4e2a\u5730\u65b9\u7528\u5230\u4e86\u591a\u6001&#xff0c;\u7236\u7c7b\u6307\u9488\u8c03\u7528\u5b50\u7c7b\u7684clone\u51fd\u6570<\/p>\n<p>    \/\/\u6790\u6784<br \/>\n    ~Any()<br \/>\n    {<br \/>\n        delete _content;<br \/>\n    }<\/p>\n<p>    \/\/\u4ea4\u6362\u81ea\u8eab\u548c\u4f20\u5165\u5bf9\u8c61\u4fdd\u5b58\u7684\u5185\u5bb9<br \/>\n    Any &amp;Swap(Any &amp;other)<br \/>\n    {<br \/>\n        std::swap(_content, other._content);<br \/>\n        return *this;<br \/>\n    }<\/p>\n<p>    template &lt;class T&gt;<br \/>\n    T *get()<br \/>\n    {<br \/>\n        if (typeid(T) !&#061; _content-&gt;type())<br \/>\n            return nullptr;<br \/>\n        else<br \/>\n            return &amp;(((placeHolder&lt;T&gt;*)_content)-&gt;_val);<br \/>\n    }<\/p>\n<p>    Any &amp;operator&#061;(const Any &amp;other)<br \/>\n    {<br \/>\n        \/\/ \u4e3aval\u6784\u9020\u4e00\u4e2a\u4e34\u65f6\u7684\u901a\u7528\u5bb9\u5668&#xff0c;\u7136\u540e\u4e0e\u5f53\u524d\u5bb9\u5668\u81ea\u8eab\u8fdb\u884c\u6307\u9488\u4ea4\u6362&#xff0c;\u4e34\u65f6\u5bf9\u8c61\u91ca\u653e\u7684\u65f6\u5019&#xff0c;\u539f\u5148\u4fdd\u5b58\u7684\u6570\u636e\u4e5f\u5c31\u88ab\u91ca\u653e<br \/>\n        Any(other).Swap(*this);<br \/>\n        return *this;<br \/>\n    }<br \/>\n    template &lt;class T&gt;<br \/>\n    Any &amp;operator&#061;(const T val)<br \/>\n    {<br \/>\n        Any(val).Swap(*this);<br \/>\n        return *this;<br \/>\n    }<br \/>\n};<\/p>\n<p>\/\/\u6d4b\u8bd5\u7528\u4f8b<br \/>\n\/*<br \/>\nclass Test{<br \/>\n    public:<br \/>\n        Test() {std::cout &lt;&lt; &#034;\u6784\u9020&#034; &lt;&lt; std::endl;}<br \/>\n        Test(const Test &amp;t) {std::cout &lt;&lt; &#034;\u62f7\u8d1d&#034; &lt;&lt; std::endl;}<br \/>\n        ~Test() {std::cout &lt;&lt; &#034;\u6790\u6784&#034; &lt;&lt; std::endl;}<br \/>\n};<br \/>\nint main()<br \/>\n{<\/p>\n<p>    Any a;<\/p>\n<p>    a &#061; 10;<br \/>\n    int *pa &#061; a.get&lt;int&gt;();<br \/>\n    std::cout &lt;&lt; *pa &lt;&lt; std::endl;<br \/>\n    a &#061; std::string(&#034;nihao&#034;);<br \/>\n    std::string *ps &#061; a.get&lt;std::string&gt;();<br \/>\n    std::cout &lt;&lt; *ps &lt;&lt; std::endl;<\/p>\n<p>    return 0;<br \/>\n}*\/ <\/p>\n<h3><\/h3>\n<h3><span style=\"color:#1f2329\">HTTP\u534f\u8bae\u6a21\u5757&#xff1a; <\/span><\/h3>\n<p>                    <span style=\"color:#1f2329\">HTTP\u534f\u8bae\u6a21\u5757\u2f64\u4e8e\u5bf9\u2fbc\u5e76\u53d1\u670d\u52a1\u5668\u6a21\u5757\u8fdb\u2f8f\u534f\u8bae\u2f40\u6301&#xff0c;\u57fa\u4e8e\u63d0\u4f9b\u7684\u534f\u8bae\u2f40\u6301\u80fd\u591f\u66f4\u2f45\u4fbf\u7684\u5b8c\u6210\u6307\u5b9a\u534f \u8bae\u670d\u52a1\u5668\u7684\u642d\u5efa\u3002 <\/span> <\/p>\n<p>                    <span style=\"color:#1f2329\">\u2f7dHTTP\u534f\u8bae\u2f40\u6301\u6a21\u5757\u7684\u5b9e\u73b0&#xff0c;\u53ef\u4ee5\u7ec6\u5206\u4e3a\u4ee5\u4e0b\u2f0f\u4e2a\u6a21\u5757\u3002 <\/span> <\/p>\n<h4><span style=\"color:#1f2329\">Util\u6a21\u5757&#xff1a; <\/span><\/h4>\n<p>                    <span style=\"color:#1f2329\">\u8fd9\u4e2a\u6a21\u5757\u662f\u2f00\u4e2a\u2f2f\u5177\u6a21\u5757&#xff0c;\u4e3b\u8981\u63d0\u4f9bHTTP\u534f\u8bae\u6a21\u5757\u6240\u2f64\u5230\u7684\u2f00\u4e9b\u2f2f\u5177\u51fd\u6570&#xff0c;\u2f50\u5982url\u7f16\u89e3\u7801&#xff0c;\u2f42\u4ef6\u8bfb \u5199&#8230;.\u7b49\u3002 HttpRequest\u6a21\u5757&#xff1a; <\/span> <\/p>\n<p>                    <span style=\"color:#1f2329\">\u8fd9\u4e2a\u6a21\u5757\u662fHTTP\u8bf7\u6c42\u6570\u636e\u6a21\u5757&#xff0c;\u2f64\u4e8e\u4fdd\u5b58HTTP\u8bf7\u6c42\u6570\u636e\u88ab\u89e3\u6790\u540e\u7684\u5404\u9879\u8bf7\u6c42\u5143\u7d20\u4fe1\u606f\u3002 <\/span> <\/p>\n<h4><span style=\"color:#1f2329\">HttpResponse\u6a21\u5757&#xff1a; <\/span><\/h4>\n<p>                    <span style=\"color:#1f2329\">\u8fd9\u4e2a\u6a21\u5757\u662fHTTP\u54cd\u5e94\u6570\u636e\u6a21\u5757&#xff0c;\u2f64\u4e8e\u4e1a\u52a1\u5904\u7406\u540e\u8bbe\u7f6e\u5e76\u4fdd\u5b58HTTP\u54cd\u5e94\u6570\u636e\u7684\u7684\u5404\u9879\u5143\u7d20\u4fe1\u606f&#xff0c;\u6700\u7ec8 \u4f1a\u88ab\u6309\u7167HTTP\u534f\u8bae\u54cd\u5e94\u683c\u5f0f\u7ec4\u7ec7\u6210\u4e3a\u54cd\u5e94\u4fe1\u606f\u53d1\u9001\u7ed9\u5ba2\u2f3e\u7aef\u3002<\/span> <\/p>\n<h4><span style=\"color:#1f2329\">HttpContext\u6a21\u5757&#xff1a; <\/span><\/h4>\n<p>                     <span style=\"color:#1f2329\">\u8fd9\u4e2a\u6a21\u5757\u662f\u2f00\u4e2aHTTP\u8bf7\u6c42\u63a5\u6536\u7684\u4e0a\u4e0b\u2f42\u6a21\u5757&#xff0c;\u4e3b\u8981\u662f\u4e3a\u4e86\u9632\u2f4c\u5728\u2f00\u6b21\u63a5\u6536\u7684\u6570\u636e\u4e2d&#xff0c;\u4e0d\u662f\u2f00\u4e2a\u5b8c\u6574\u7684 HTTP\u8bf7\u6c42&#xff0c;\u5219\u89e3\u6790\u8fc7\u7a0b\u5e76\u672a\u5b8c\u6210&#xff0c;\u2f46\u6cd5\u8fdb\u2f8f\u5b8c\u6574\u7684\u8bf7\u6c42\u5904\u7406&#xff0c;\u9700\u8981\u5728\u4e0b\u6b21\u63a5\u6536\u5230\u65b0\u6570\u636e\u540e\u7ee7\u7eed\u6839\u636e\u4e0a \u4e0b\u2f42\u8fdb\u2f8f\u89e3\u6790&#xff0c;\u6700\u7ec8\u5f97\u5230\u2f00\u4e2aHttpRequest\u8bf7\u6c42\u4fe1\u606f\u5bf9\u8c61&#xff0c;\u56e0\u6b64\u5728\u8bf7\u6c42\u6570\u636e\u7684\u63a5\u6536\u4ee5\u53ca\u89e3\u6790\u90e8\u5206\u9700\u8981\u2f00 \u4e2a\u4e0a\u4e0b\u2f42\u6765\u8fdb\u2f8f\u63a7\u5236\u63a5\u6536\u548c\u5904\u7406\u8282\u594f\u3002 <\/span> <\/p>\n<h4><span style=\"color:#1f2329\">HttpServer\u6a21\u5757&#xff1a; <\/span><\/h4>\n<p>                     <span style=\"color:#1f2329\">\u8fd9\u4e2a\u6a21\u5757\u662f\u6700\u7ec8\u7ed9\u7ec4\u4ef6\u4f7f\u2f64\u8005\u63d0\u4f9b\u7684HTTP\u670d\u52a1\u5668\u6a21\u5757\u4e86&#xff0c;\u2f64\u4e8e\u4ee5\u7b80\u5355\u7684\u63a5\u2f1d\u5b9e\u73b0HTTP\u670d\u52a1\u5668\u7684\u642d \u5efa\u3002 <\/span> <\/p>\n<p>                     <span style=\"color:#1f2329\">HttpServer\u6a21\u5757\u5185\u90e8\u5305\u542b\u6709\u2f00\u4e2aTcpServer\u5bf9\u8c61&#xff1a;TcpServer\u5bf9\u8c61\u5b9e\u73b0\u670d\u52a1\u5668\u7684\u642d\u5efa <\/span> <\/p>\n<p>                     <span style=\"color:#1f2329\">HttpServer\u6a21\u5757\u5185\u90e8\u5305\u542b\u6709\u4e24\u4e2a\u63d0\u4f9b\u7ed9TcpServer\u5bf9\u8c61\u7684\u63a5\u2f1d&#xff1a;\u8fde\u63a5\u5efa\u2f74\u6210\u529f\u8bbe\u7f6e\u4e0a\u4e0b\u2f42\u63a5\u2f1d&#xff0c;\u6570\u636e\u5904 \u7406\u63a5\u2f1d\u3002 <\/span> <\/p>\n<p>                     <span style=\"color:#1f2329\">HttpServer\u6a21\u5757\u5185\u90e8\u5305\u542b\u6709\u2f00\u4e2ahash-map\u8868\u5b58\u50a8\u8bf7\u6c42\u4e0e\u5904\u7406\u51fd\u6570\u7684\u6620\u5c04\u8868&#xff1a;\u7ec4\u4ef6\u4f7f\u2f64\u8005\u5411 <\/span> <\/p>\n<p>                     <span style=\"color:#1f2329\">HttpServer\u8bbe\u7f6e\u54ea\u4e9b\u8bf7\u6c42\u5e94\u8be5\u4f7f\u2f64\u54ea\u4e9b\u51fd\u6570\u8fdb\u2f8f\u5904\u7406&#xff0c;\u7b49TcpServer\u6536\u5230\u5bf9\u5e94\u7684\u8bf7\u6c42\u5c31\u4f1a\u4f7f\u2f64\u5bf9\u5e94\u7684\u51fd \u6570\u8fdb\u2f8f\u5904\u7406\u3002<\/span> <\/p>\n<h2>\u4e09&#xff1a;\u6a21\u5757\u5b9e\u73b0<\/h2>\n<h3><span style=\"color:#1f2329\">SERVER\u670d\u52a1\u5668\u6a21\u5757\u5b9e\u73b0&#xff1a; <\/span><\/h3>\n<h4 style=\"background-color:transparent\"><span style=\"color:#1f2329\">\u7f13\u51b2\u533aBuffer\u7c7b\u5b9e\u73b0&#xff1a; <\/span><\/h4>\n<p>                    <span style=\"color:#1f2329\">Buffer\u7c7b\u2f64\u4e8e\u5b9e\u73b0\u2f64\u2f3e\u6001\u7f13\u51b2\u533a&#xff0c;\u63d0\u4f9b\u6570\u636e\u7f13\u51b2&#xff0c;\u53d6\u51fa\u7b49\u529f\u80fd\u3002 <\/span> <\/p>\n<p>                    <img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"855\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250418141252-68025de404ebf.png\" width=\"1200\" \/> <\/p>\n<p>                    <img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"870\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250418141252-68025de4a3d1b.png\" width=\"639\" \/> <\/p>\n<p>                    class Buffer<br \/>\n{<br \/>\n#define BUFFER_DEFAULT_SIZE 1024<br \/>\nprivate:<br \/>\n    std::vector&lt;char&gt; _buffer;<br \/>\n    uint64_t _reader_idx;\/\/\u8bfb\u4f4d\u7f6e\u7d22\u5f15<br \/>\n    uint64_t _writer_idx;\/\/\u5199\u4f4d\u7f6e\u7d22\u5f15<\/p>\n<p>public:<br \/>\n    Buffer()<br \/>\n        : _reader_idx(0),<br \/>\n          _writer_idx(0),<br \/>\n          _buffer(BUFFER_DEFAULT_SIZE)<br \/>\n    {<br \/>\n    }<br \/>\n    \/\/ \u8fd4\u56de\u8d77\u59cb\u4f4d\u7f6e<br \/>\n    char *Begin()<br \/>\n    {<br \/>\n        return &amp;*_buffer.begin();<br \/>\n    }<\/p>\n<p>    \/\/ \u83b7\u53d6\u5199\u5165\u4f4d\u7f6e<br \/>\n    char *WritePosition()<br \/>\n    {<br \/>\n        return Begin() &#043; _writer_idx;<br \/>\n    }<br \/>\n    \/\/ \u83b7\u53d6\u8bfb\u53d6\u4f4d\u7f6e<br \/>\n    char *ReadPosition()<br \/>\n    {<br \/>\n        return Begin() &#043; _reader_idx;<br \/>\n    }<br \/>\n    \/\/ \u83b7\u53d6\u5934\u5269\u4f59\u7a7a\u95f4<br \/>\n    uint64_t HeadIdleSize()<br \/>\n    {<br \/>\n        return _reader_idx;<br \/>\n    }<br \/>\n    \/\/ \u83b7\u53d6\u5c3e\u90e8\u5269\u4f59\u7a7a\u95f4<br \/>\n    uint64_t TailIdleSize()<br \/>\n    {<br \/>\n        return _buffer.size() &#8211; _writer_idx;<br \/>\n    }<br \/>\n    \/\/ \u83b7\u53d6\u53ef\u8bfb\u6570\u636e\u5927\u5c0f<br \/>\n    uint64_t ReadAbleSize()<br \/>\n    {<br \/>\n        return _writer_idx &#8211; _reader_idx;<br \/>\n    }<br \/>\n    \/\/ \u5c06\u8bfb\u504f\u79fb\u5411\u540e\u79fb\u52a8<br \/>\n    void MoveReadOffset(uint64_t len)<br \/>\n    {<br \/>\n        if (len &#061;&#061; 0)<br \/>\n            return;<br \/>\n        \/\/ \u5411\u540e\u79fb\u52a8\u7684\u5927\u5c0f&#xff0c;\u5fc5\u987b\u5c0f\u4e8e\u53ef\u8bfb\u6570\u636e\u5927\u5c0f<br \/>\n        if(len &lt;&#061; ReadAbleSize())<br \/>\n        _reader_idx &#043;&#061; len;<br \/>\n        else ERR_LOG(&#034;MoveReadOffset ERROR&#034;);<br \/>\n    }<br \/>\n    \/\/ \u5c06\u5199\u504f\u79fb\u5411\u540e\u79fb\u52a8<br \/>\n    void MoveWriteOffset(uint64_t len)<br \/>\n    {<br \/>\n        \/\/ \u5411\u540e\u79fb\u52a8\u7684\u5927\u5c0f&#xff0c;\u5fc5\u987b\u5c0f\u4e8e\u5f53\u524d\u540e\u8fb9\u7684\u7a7a\u95f2\u7a7a\u95f4\u5927\u5c0f<br \/>\n        if(len &lt;&#061; TailIdleSize())<br \/>\n        _writer_idx &#043;&#061; len;<br \/>\n        else ERR_LOG(&#034;MoveWriteOffset ERROR&#034;);<br \/>\n    }<br \/>\n    \/\/ \u786e\u4fdd\u53ef\u4ee5\u7a7a\u95f4\u8db3\u591f&#xff0c;\u5426\u5219\u5c31\u6269\u5bb9<br \/>\n    void EnsureWriteSpace(uint64_t len)<br \/>\n    {<br \/>\n        if (TailIdleSize() &gt;&#061; len)<br \/>\n        {<br \/>\n            return;<br \/>\n        }<br \/>\n        else<br \/>\n        {<br \/>\n            if (len &lt;&#061; HeadIdleSize() &#043; TailIdleSize())<br \/>\n            {<br \/>\n                \/\/ \u5982\u679c\u5934\u5c3e\u7a7a\u95f4\u8db3\u591f&#xff0c;\u5c31\u5c3d\u91cf\u8282\u7ea6\u7a7a\u95f4\u4e0d\u6269\u5bb9&#xff0c;\u53ea\u5c06\u7f13\u51b2\u533a\u91cd\u65b0\u6574\u7406\u5373\u53ef<br \/>\n                \/\/ \u5c06\u6570\u636e\u79fb\u52a8\u5230\u5934\u90e8&#xff0c;\u5c06\u5934\u90e8\u548c\u5c3e\u90e8\u5269\u4f59\u7a7a\u95f4\u7ed3\u5408<br \/>\n                uint64_t rsz &#061; ReadAbleSize();<br \/>\n                std::copy(ReadPosition(), ReadPosition() &#043; rsz, Begin());<br \/>\n                _reader_idx &#061; 0;<br \/>\n                _writer_idx &#061; rsz;<br \/>\n            }<br \/>\n            else<br \/>\n            {<br \/>\n                \/\/ \u603b\u4f53\u7a7a\u95f4\u4e0d\u591f\u5c31\u8fdb\u884c\u6269\u5bb9<br \/>\n                _buffer.resize(_writer_idx &#043; len);<br \/>\n            }<br \/>\n        }<br \/>\n    }<br \/>\n    \/\/ \u5199\u5165\u6570\u636e<br \/>\n    void Write(const void *data, int len)<br \/>\n    {<br \/>\n        \/\/ 1.\u4fdd\u8bc1\u6709\u8db3\u591f\u7a7a\u95f4 2.\u5c06\u6570\u636e\u62f7\u5165\u7f13\u51b2\u533a<br \/>\n        EnsureWriteSpace(len);<br \/>\n        const char *d &#061; (const char *)data;<br \/>\n        std::copy(d, d &#043; len, WritePosition());<br \/>\n    }<br \/>\n    void WriteAndPush(const void *data, int len)<br \/>\n    {<br \/>\n        Write(data, len);<br \/>\n        MoveWriteOffset(len);<br \/>\n    }<br \/>\n    \/\/ \u5199\u5165\u5b57\u7b26\u4e32<br \/>\n    void WriteString(std::string &amp;data)<br \/>\n    {<br \/>\n        Write(data.c_str(), data.size());<br \/>\n    }<br \/>\n    void WriteStringAndPush(std::string &amp;data)<br \/>\n    {<br \/>\n        WriteString(data);<br \/>\n        MoveWriteOffset(data.size());<br \/>\n    }<br \/>\n    \/\/ \u4ece\u5176\u4ed6\u7f13\u51b2\u533a\u5199\u5165<br \/>\n    void WriteBuffer(Buffer &amp;buf)<br \/>\n    {<br \/>\n        Write((const void *)buf.ReadPosition(), buf.ReadAbleSize());<br \/>\n    }<br \/>\n    void WriteBufferAndPush(Buffer &amp;buf)<br \/>\n    {<br \/>\n        Write((const void *)buf.ReadPosition(), buf.ReadAbleSize());<br \/>\n        MoveWriteOffset(buf.ReadAbleSize());<br \/>\n    }<br \/>\n    \/\/ \u8bfb\u53d6\u6570\u636e<br \/>\n    void Read(void *rec, int len)<br \/>\n    {<br \/>\n        if (len &lt;&#061; ReadAbleSize())<br \/>\n        {<br \/>\n            \/\/ std::copy(Begin() &#043; _reader_size, Begin() &#043; _writer_size, (char *)rec);<br \/>\n            std::copy(ReadPosition(), ReadPosition() &#043; len, (char*)rec);<br \/>\n        }<br \/>\n        else<br \/>\n        {<br \/>\n            ERR_LOG(&#034;\u8bfb\u53d6\u6570\u636e\u51fa\u9519&#034;);<br \/>\n        }<br \/>\n    }<br \/>\n    void ReadAndPop(void *rec, int len)<br \/>\n    {<br \/>\n        if (len &lt;&#061; ReadAbleSize())<br \/>\n        {<br \/>\n            Read(rec, len);<br \/>\n            MoveReadOffset(len);<br \/>\n        }<br \/>\n        else<br \/>\n        {<br \/>\n            ERR_LOG(&#034;ReadAndPop ERROR&#034;);<br \/>\n        }<br \/>\n    }<br \/>\n    \/\/ \u4ee5\u5b57\u7b26\u4e32\u7684\u5f62\u5f0f\u8bfb\u53d6\u6570\u636e<br \/>\n    std::string ReadAsString(int len)<br \/>\n    {<br \/>\n        if (len &lt;&#061; ReadAbleSize())<br \/>\n        {<br \/>\n            std::string str;<br \/>\n            str.resize(len);<br \/>\n            Read(&amp;str[0], len);<br \/>\n            return str;<br \/>\n        }<br \/>\n        return &#034;&#034;;<br \/>\n    }<\/p>\n<p>    std::string ReadAsStringAndpop(int len)<br \/>\n    {<br \/>\n        if(len &lt;&#061; ReadAbleSize())<br \/>\n        {<br \/>\n            std::string ret &#061; ReadAsString(len);<br \/>\n            MoveReadOffset(len);<br \/>\n            return ret;<br \/>\n        }<br \/>\n        else<br \/>\n        {<br \/>\n            ERR_LOG(&#034;ReadAsStringAndpop ERROR&#034;);<br \/>\n            return &#034;&#034;;<br \/>\n        }<br \/>\n    }<br \/>\n    \/\/ \u67e5\u627e\u4e00\u884c\u6570\u636e<br \/>\n    char *FindCRLF()<br \/>\n    {<br \/>\n        void *res &#061; memchr((void *)ReadPosition(), &#039;\\\\n&#039;, ReadAbleSize());<br \/>\n        return (char *)res;<br \/>\n    }<br \/>\n    \/\/ \u4ee5\u5b57\u7b26\u4e32\u5f62\u5f0f\u83b7\u53d6\u4e00\u884c\u6570\u636e<br \/>\n    std::string GetLine()<br \/>\n    {<br \/>\n        char *pos &#061; FindCRLF();<br \/>\n        if (pos &#061;&#061; nullptr)<br \/>\n        {<br \/>\n            return &#034;&#034;;<br \/>\n        }<br \/>\n        \/\/&#043;1\u662f\u628a\u6362\u884c\u7b26\u4e5f\u53d6\u51fa\u6765&#xff0c;\u56e0\u4e3apos\u662f\u4e0b\u4e00\u4e2a\u884c\u7684\u8d77\u59cb\u5730\u5740<br \/>\n        return ReadAsString(pos &#8211; ReadPosition() &#043; 1);<br \/>\n    }<br \/>\n    std::string GetLineAndPop()<br \/>\n    {<br \/>\n        \/\/ \u8c03\u7528GetLine\u51fd\u6570\u83b7\u53d6\u4e00\u884c\u5b57\u7b26\u4e32<br \/>\n        std::string ret &#061; GetLine();<br \/>\n        \/\/ \u6839\u636e\u83b7\u53d6\u7684\u5b57\u7b26\u4e32\u957f\u5ea6\u79fb\u52a8\u8bfb\u53d6\u504f\u79fb\u91cf<br \/>\n        MoveReadOffset(ret.size());<br \/>\n        \/\/ \u8fd4\u56de\u83b7\u53d6\u5230\u7684\u5b57\u7b26\u4e32<br \/>\n        return ret;<br \/>\n    }<br \/>\n    \/\/ \u6e05\u7a7a\u6570\u636e<br \/>\n    void Clear()<br \/>\n    {<br \/>\n        _writer_idx &#061; 0;<br \/>\n        _reader_idx &#061; 0;<br \/>\n    }<br \/>\n}; <\/p>\n<h4 style=\"background-color:transparent\"><span style=\"color:#1f2329\">\u2f47\u5fd7\u5b8f\u7684\u5b9e\u73b0&#xff1a;<\/span><\/h4>\n<p>                    #define INF 0<br \/>\n#define DBG 1<br \/>\n#define ERR 2<br \/>\n#define LOG_LEVEL DBG<\/p>\n<p>#define LOG(level, format, &#8230;) do{\\\\<br \/>\n        if (level &lt; LOG_LEVEL) break;\\\\<br \/>\n        time_t t &#061; time(NULL);\\\\<br \/>\n        struct tm *ltm &#061; localtime(&amp;t);\\\\<br \/>\n        char tmp[32] &#061; {0};\\\\<br \/>\n        strftime(tmp, 31, &#034;%H:%M:%S&#034;, ltm);\\\\<br \/>\n        fprintf(stdout, &#034;[%p %s %s:%d] &#034; format &#034;\\\\n&#034;, (void*)pthread_self(), tmp, __FILE__, __LINE__, ##__VA_ARGS__);\\\\<br \/>\n    }while(0)<\/p>\n<p>#define INF_LOG(format, &#8230;) LOG(INF, format, ##__VA_ARGS__)<br \/>\n#define DBG_LOG(format, &#8230;) LOG(DBG, format, ##__VA_ARGS__)<br \/>\n#define ERR_LOG(format, &#8230;) LOG(ERR, format, ##__VA_ARGS__) <\/p>\n<h4 style=\"background-color:transparent\"><span style=\"color:#1f2329\">\u5957\u63a5\u5b57Socket\u7c7b\u5b9e\u73b0&#xff1a;<\/span><\/h4>\n<p>                    #define MAX_LISEN 1024<br \/>\nclass Socket<br \/>\n{<br \/>\nprivate:<br \/>\n    int _socketfd;<\/p>\n<p>public:<br \/>\n    Socket() : _socketfd(-1) {}<br \/>\n    Socket(int fd) : _socketfd(fd) {}<br \/>\n    ~Socket() {}<br \/>\n    int Fd()<br \/>\n    {<br \/>\n        return _socketfd;<br \/>\n    }<br \/>\n    \/\/ \u521b\u5efa\u5957\u63a5\u5b57<br \/>\n    bool Create()<br \/>\n    {<br \/>\n        _socketfd &#061; socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);<br \/>\n        if (_socketfd &lt; 0)<br \/>\n        {<br \/>\n            ERR_LOG(&#034;CREATED SOCKET ERROR&#034;);<br \/>\n            return false;<br \/>\n        }<br \/>\n        return true;<br \/>\n    }<br \/>\n    \/\/ \u7ed1\u5b9a\u7aef\u53e3\u53f7<br \/>\n    bool Bind(const std::string &amp;ip, uint16_t port)<br \/>\n    {<br \/>\n        struct sockaddr_in addr;<br \/>\n        addr.sin_family &#061; AF_INET;<br \/>\n        addr.sin_port &#061; htons(port);<br \/>\n        addr.sin_addr.s_addr &#061; inet_addr(ip.c_str());<br \/>\n        socklen_t len &#061; sizeof(struct sockaddr_in);<br \/>\n        int ret &#061; bind(_socketfd, (struct sockaddr *)&amp;addr, len);<br \/>\n        if (ret &lt; 0)<br \/>\n        {<br \/>\n            ERR_LOG(&#034;BIND ERROR&#034;);<br \/>\n            return false;<br \/>\n        }<br \/>\n        return true;<br \/>\n    }<br \/>\n    \/\/ \u76d1\u542c\u5957\u63a5\u5b57<br \/>\n    bool Listen(int backLog &#061; MAX_LISEN)<br \/>\n    {<br \/>\n        int ret &#061; listen(_socketfd, backLog);<br \/>\n        if (ret &lt; 0)<br \/>\n        {<br \/>\n            ERR_LOG(&#034;LISTEN ERROR&#034;);<br \/>\n            return false;<br \/>\n        }<br \/>\n        return true;<br \/>\n    }<br \/>\n    \/\/ \u5411\u670d\u52a1\u5668\u53d1\u8d77\u8fde\u63a5<br \/>\n    bool Connect(const std::string &amp;ip, uint16_t port)<br \/>\n    {<br \/>\n        struct sockaddr_in addr;<br \/>\n        addr.sin_family &#061; AF_INET;<br \/>\n        addr.sin_port &#061; htons(port);<br \/>\n        addr.sin_addr.s_addr &#061; inet_addr(ip.c_str());<br \/>\n        socklen_t len &#061; sizeof(struct sockaddr_in);<br \/>\n        int ret &#061; connect(_socketfd, (struct sockaddr *)&amp;addr, len);<br \/>\n        if (ret &lt; 0)<br \/>\n        {<br \/>\n            ERR_LOG(&#034;CONNECT FAILED&#034;);<br \/>\n            return false;<br \/>\n        }<br \/>\n        return true;<br \/>\n    }<br \/>\n    \/\/ \u83b7\u53d6\u65b0\u8fde\u63a5<br \/>\n    int Accept()<br \/>\n    {<br \/>\n        int newfd &#061; accept(_socketfd, nullptr, nullptr);<br \/>\n        if (newfd &lt; 0)<br \/>\n        {<br \/>\n            ERR_LOG(&#034;ACCEPT FAILED&#034;);<br \/>\n            return -1;<br \/>\n        }<br \/>\n        return newfd;<br \/>\n    }<br \/>\n    \/\/ \u63a5\u6536\u6570\u636e<br \/>\n    ssize_t Recv(void *buf, size_t len, int flag &#061; 0)<br \/>\n    {<br \/>\n        ssize_t ret &#061; recv(_socketfd, buf, len, flag);<br \/>\n        if (ret &lt;&#061; 0)<br \/>\n        {<br \/>\n            if (errno &#061;&#061; EAGAIN || errno &#061;&#061; EINTR)<br \/>\n            {<br \/>\n                ERR_LOG(&#034;RECEIVE AGAIN&#034;);<br \/>\n                return 0;<br \/>\n            }<br \/>\n            ERR_LOG(&#034;RECEIVE FAILED:%d&#034;, errno);<br \/>\n            return -1;<br \/>\n        }<\/p>\n<p>        return ret;<br \/>\n    }<br \/>\n    ssize_t NoBlockRecv(void *buf, size_t len)<br \/>\n    {<br \/>\n        \/\/ \u4f7f\u7528Recv\u51fd\u6570\u63a5\u6536\u6570\u636e&#xff0c;\u5e76\u8bbe\u7f6e\u6807\u5fd7\u4f4d\u4e3aMSG_DONTWAIT\u4ee5\u5b9e\u73b0\u975e\u963b\u585e\u63a5\u6536<br \/>\n        return Recv(buf, len, MSG_DONTWAIT);<br \/>\n    }<br \/>\n    \/\/ \u53d1\u9001\u6570\u636e<br \/>\n    int Send(const void *buf, size_t len, int flag &#061; 0)<br \/>\n    {<br \/>\n        DBG_LOG(&#034;SEND:%ld&#034;, len);<br \/>\n        ssize_t ret &#061; send(_socketfd, buf, len, flag);<br \/>\n        if (ret &lt;&#061; 0)<br \/>\n        {<br \/>\n            if (ret &lt; 0)<br \/>\n            {<br \/>\n                if (errno &#061;&#061; EAGAIN || errno &#061;&#061; EINTR)<br \/>\n                {<br \/>\n                    return 0;<br \/>\n                }<br \/>\n            }<br \/>\n            ERR_LOG(&#034;SEND FAILED&#034;);<br \/>\n            return -1;<br \/>\n        }<\/p>\n<p>        return ret;<br \/>\n    }<br \/>\n    ssize_t NoBlockSend(void *buf, size_t len)<br \/>\n    {<br \/>\n        return Send(buf, len, MSG_DONTWAIT);<br \/>\n    }<br \/>\n    \/\/ \u5173\u95ed\u5957\u63a5\u5b57<br \/>\n    void Close()<br \/>\n    {<br \/>\n        if (_socketfd !&#061; -1)<br \/>\n        {<br \/>\n            close(_socketfd);<br \/>\n            _socketfd &#061; -1;<br \/>\n        }<br \/>\n    }<br \/>\n    \/\/ \u521b\u5efa\u4e00\u4e2a\u670d\u52a1\u7aef\u8fde\u63a5<br \/>\n    bool CreateServer(uint16_t port, const std::string &amp;ip &#061; &#034;0.0.0.0&#034;, bool block_flag &#061; false)<br \/>\n    {<br \/>\n        if (Create() &#061;&#061; false)<br \/>\n            return false;<br \/>\n        if (block_flag)<br \/>\n            NoBlock();<br \/>\n        if (Bind(ip, port) &#061;&#061; false)<br \/>\n            return false;<br \/>\n        if (Listen() &#061;&#061; false)<br \/>\n            return false;<br \/>\n        ReuseAdress();<br \/>\n        return true;<br \/>\n    }<br \/>\n    \/\/ \u521b\u5efa\u4e00\u4e2a\u5ba2\u6237\u7aef\u8fde\u63a5<br \/>\n    bool CreateClient(uint16_t port, const std::string &amp;ip)<br \/>\n    {<br \/>\n        if (Create() &#061;&#061; false)<br \/>\n            return false;<br \/>\n        if (Connect(ip, port) &#061;&#061; false)<br \/>\n            return false;<br \/>\n        return true;<br \/>\n    }<br \/>\n    \/\/ \u5f00\u542f\u5730\u5740\u7aef\u53e3\u91cd\u7528<br \/>\n    void ReuseAdress()<br \/>\n    {<br \/>\n        int val &#061; 1;<br \/>\n        \/\/ \u8bbe\u7f6e\u5957\u63a5\u5b57\u9009\u9879 SO_REUSEADDR&#xff0c;\u5141\u8bb8\u5730\u5740\u91cd\u7528<br \/>\n            setsockopt(_socketfd, SOL_SOCKET, SO_REUSEADDR, (void*)&amp;val, sizeof(int));<\/p>\n<p>            val &#061; 1;<br \/>\n        \/\/ \u8bbe\u7f6e\u5957\u63a5\u5b57\u9009\u9879 SO_REUSEPORT&#xff0c;\u5141\u8bb8\u7aef\u53e3\u91cd\u7528<br \/>\n            setsockopt(_socketfd, SOL_SOCKET, SO_REUSEPORT, (void*)&amp;val, sizeof(int));<br \/>\n    }<br \/>\n    \/\/ \u5957\u63a5\u5b57\u8bbe\u7f6e\u4e3a\u975e\u963b\u585e<br \/>\n    void NoBlock()<br \/>\n    {<br \/>\n        \/\/\u83b7\u53d6\u539f\u672c\u7684flag\u503c<br \/>\n        int flag &#061; fcntl(_socketfd, F_GETFL, 0);<br \/>\n        fcntl(_socketfd, F_SETFL, flag | O_NONBLOCK);\/\/\u65b0\u589e\u975e\u963b\u585e<br \/>\n    }<br \/>\n};<\/p>\n<h4 style=\"background-color:transparent\"><span style=\"color:#1f2329\">\u4e8b\u4ef6\u7ba1\u7406Channel\u7c7b\u5b9e\u73b0&#xff1a;<\/span><\/h4>\n<p>                    \/*<br \/>\n\u4e00\u4e2achannel\u5bf9\u5e94\u4e00\u4e2afd&#xff0c;\u53bb\u76d1\u7ba1\u4e00\u4e2afd\u4e0a\u53d1\u751f\u7684\u6240\u6709\u4e8b\u4ef6<br \/>\npoller\u8d1f\u8d23\u76d1\u7ba1\u6240\u6709channel&#xff0c;poller\u624d\u5177\u6709\u5b9e\u9645\u7684epoll&#xff0c;poller\u624d\u662f\u5b9e\u9645\u7684\u76d1\u63a7\u8005&#xff0c;\u8d1f\u8d23\u76d1\u7ba1\u6240\u6709channel<br \/>\nchannel\u4fdd\u5b58\u4e00\u4e2aenvent\u8868\u548c\u76f8\u5e94\u7684\u56de\u8c03\u51fd\u6570,\u8fd9\u4e5fpoller\u624d\u53ef\u4ee5\u6839\u636echannel\u8fdb\u884c\u76f8\u5e94\u7684\u76d1\u63a7&#xff08;\u6839\u636eevent\u5224\u65ad\u662f\u5426\u8981\u76d1\u63a7\u8bfb&#xff0c;\u5199\u7b49&#xff09;\u548c\u6b63\u786e\u7684\u56de\u8c03&#xff08;\u8bfb&#xff0c;\u5199\u7b49\u89e6\u53d1\u600e\u4e48\u6837\u7684\u56de\u8c03&#xff09;<br \/>\n*\/<br \/>\nclass Poller;<br \/>\nclass EventLoop;<br \/>\nclass Channel<br \/>\n{<br \/>\nprivate:<br \/>\n    int _fd;<br \/>\n    EventLoop *_loop;<br \/>\n    uint32_t _events;  \/\/ \u5f53\u524d\u8981\u76d1\u63a7\u7684\u4e8b\u4ef6<br \/>\n    uint32_t _revents; \/\/ \u5bf9\u89e6\u53d1\u4e8b\u4ef6\u7684\u76d1\u63a7<br \/>\n    using EventCallBack &#061; std::function&lt;void()&gt;;<br \/>\n    EventCallBack _read_callback;  \/\/ \u53ef\u8bfb\u4e8b\u4ef6\u7684\u56de\u8c03\u51fd\u6570<br \/>\n    EventCallBack _write_callback; \/\/ \u53ef\u5199\u4e8b\u4ef6\u7684\u56de\u8c03\u51fd\u6570<br \/>\n    EventCallBack _error_callback; \/\/ \u9519\u8bef\u4e8b\u4ef6\u7684\u56de\u8c03\u51fd\u6570<br \/>\n    EventCallBack _close_callback; \/\/ \u5173\u95ed\u4e8b\u4ef6\u7684\u56de\u8c03\u51fd\u6570<br \/>\n    EventCallBack _event_callback; \/\/ \u4efb\u610f\u4e8b\u4ef6\u89e6\u53d1\u7684\u56de\u8c03\u51fd\u6570<\/p>\n<p>public:<br \/>\n    Channel(EventLoop *Loop, int fd)<br \/>\n        : _loop(Loop),<br \/>\n          _fd(fd),<br \/>\n          _events(0),<br \/>\n          _revents(0)<br \/>\n    {<br \/>\n    }<\/p>\n<p>    int Fd()<br \/>\n    {<br \/>\n        return _fd;<br \/>\n    }<br \/>\n    \/\/ \u8bbe\u7f6e\u5b9e\u9645\u5c31\u7eea\u7684\u4e8b\u4ef6<br \/>\n    void SetRevents(uint32_t events)<br \/>\n    {<br \/>\n        _revents &#061; events;<br \/>\n    }<br \/>\n    \/\/ \u83b7\u53d6\u60f3\u8981\u76d1\u63a7\u7684\u4e8b\u4ef6<br \/>\n    uint32_t Event()<br \/>\n    {<br \/>\n        return _events;<br \/>\n    }<br \/>\n    \/\/ \u8bbe\u7f6e\u53ef\u8bfb\u4e8b\u4ef6\u56de\u8c03<br \/>\n    void SetReadCallBack(const EventCallBack cb)<br \/>\n    {<br \/>\n        _read_callback &#061; cb;<br \/>\n    }<br \/>\n    \/\/ \u8bbe\u7f6e\u53ef\u5199\u4e8b\u4ef6\u56de\u8c03<br \/>\n    void SetWriteCallBack(const EventCallBack cb)<br \/>\n    {<br \/>\n        _write_callback &#061; cb;<br \/>\n    }<br \/>\n    \/\/ \u8bbe\u7f6e\u9519\u8bef\u4e8b\u4ef6\u56de\u8c03<br \/>\n    void SetErrorCallBack(const EventCallBack cb)<br \/>\n    {<br \/>\n        _error_callback &#061; cb;<br \/>\n    }<br \/>\n    \/\/ \u8bbe\u7f6e\u5173\u95ed\u4e8b\u4ef6\u56de\u8c03<br \/>\n    void SetCloseCallBack(const EventCallBack cb)<br \/>\n    {<br \/>\n        _close_callback &#061; cb;<br \/>\n    }<br \/>\n    \/\/ \u8bbe\u7f6e\u4efb\u610f\u4e8b\u4ef6\u56de\u8c03<br \/>\n    void SetEventCallBack(const EventCallBack cb)<br \/>\n    {<br \/>\n        _event_callback &#061; cb;<br \/>\n    }<br \/>\n    \/\/ \u5f53\u524d\u662f\u5426\u53ef\u8bfb<br \/>\n    bool ReadAble()<br \/>\n    {<br \/>\n        return _events &amp; EPOLLIN;<br \/>\n    }<br \/>\n    \/\/ \u5f53\u524d\u662f\u5426\u53ef\u5199<br \/>\n    bool WriteAble()<br \/>\n    {<br \/>\n        return _events &amp; EPOLLOUT;<br \/>\n    }<br \/>\n    \/\/ \u542f\u52a8\u8bfb\u4e8b\u4ef6\u76d1\u63a7<br \/>\n    void EnableRead()<br \/>\n    {<br \/>\n        _events |&#061; EPOLLIN;<br \/>\n        Update();<br \/>\n    }<br \/>\n    \/\/ \u542f\u52a8\u5199\u4e8b\u4ef6\u76d1\u63a7<br \/>\n    void EnableWrite()<br \/>\n    {<br \/>\n        _events |&#061; EPOLLOUT;<br \/>\n        Update();<br \/>\n    }<br \/>\n    \/\/ \u5173\u95ed\u5199\u4e8b\u4ef6\u76d1\u63a7<br \/>\n    void DisableWrite()<br \/>\n    {<br \/>\n        _events &amp;&#061; ~EPOLLOUT;<br \/>\n        Update();<br \/>\n    }<br \/>\n    \/\/ \u5173\u95ed\u8bfb\u4e8b\u4ef6\u76d1\u63a7<br \/>\n    void DisableRead()<br \/>\n    {<br \/>\n        _events &amp;&#061; ~EPOLLIN;<br \/>\n        Update();<br \/>\n    }<br \/>\n    \/\/ \u5173\u95ed\u6240\u6709\u4e8b\u4ef6\u76d1\u63a7<br \/>\n    void DisableAll()<br \/>\n    {<br \/>\n        _events &#061; 0;<br \/>\n        Update();<br \/>\n    }<br \/>\n    \/\/ \u79fb\u9664\u5bf9\u4e8b\u4ef6\u7684\u76d1\u63a7<br \/>\n    void Remove();<br \/>\n    void Update();<br \/>\n    \/\/ \u4e8b\u4ef6\u5904\u7406&#xff0c;\u4e00\u65e6\u89e6\u53d1\u5c31\u8c03\u7528\u8be5\u51fd\u6570&#xff0c;\u8ba9\u89e6\u53d1\u7684\u4e8b\u4ef6\u81ea\u5df1\u51b3\u5b9a\u5982\u4f55\u5904\u7406<br \/>\n    void HandleEvent()<br \/>\n    {<br \/>\n        \/\/\u53ef\u8bfb\u53ef\u5199\u4e8b\u4ef6\u7531\u4e8e\u53ef\u80fd\u8017\u65f6\u6bd4\u8f83\u957f&#xff0c;\u6240\u4ee5\u9632\u6b62\u5148\u5237\u65b0\u6d3b\u8dc3\u5ea6\u5bfc\u81f4\u5904\u7406\u4e8b\u4ef6\u7684\u65f6\u5019\u8d85\u65f6&#xff0c;\u6240\u4ee5\u5148\u5904\u7406\u4e8b\u4ef6\u518d\u5237\u65b0\u6d3b\u8dc3\u5ea6\u9632\u6b62\u8d85\u65f6<br \/>\n        \/\/ \u53ef\u8bfb\u4e8b\u4ef6\u8c03\u7528<br \/>\n        if ((_revents &amp; EPOLLIN) || (_revents &amp; EPOLLRDHUP) || (_revents &amp; EPOLLPRI))<br \/>\n        {<br \/>\n            if (_read_callback)<br \/>\n                _read_callback();<br \/>\n            \/\/ \u4efb\u4f55\u4e8b\u4ef6\u90fd\u8c03\u7528&#xff0c;\u5237\u65b0\u6d3b\u8dc3\u5ea6<br \/>\n            if (_event_callback)<br \/>\n            _event_callback();<br \/>\n        }<br \/>\n        \/\/ \u53ef\u5199\u4e8b\u4ef6\u8c03\u7528<br \/>\n        if (_revents &amp; EPOLLOUT)<br \/>\n        {<br \/>\n            if (_write_callback)<br \/>\n                _write_callback();<br \/>\n            \/\/ \u4efb\u4f55\u4e8b\u4ef6\u90fd\u8c03\u7528&#xff0c;\u5237\u65b0\u6d3b\u8dc3\u5ea6<br \/>\n            if (_event_callback)<br \/>\n            _event_callback();<br \/>\n        }<br \/>\n        \/\/\u9519\u8bef\u6216\u8005\u5173\u95ed\u4e8b\u4ef6\u7531\u4e8e\u53ef\u80fd\u4f1a\u5bfc\u81f4\u8fde\u63a5\u5173\u95ed&#xff0c;\u6240\u4ee5\u5148\u5237\u65b0\u6d3b\u8dc3\u5ea6\u9632\u6b62\u8fde\u63a5\u88ab\u91ca\u653e\u4ee5\u540e\u518d\u5237\u65b0\u5bfc\u81f4\u9519\u8bef<br \/>\n        \/\/\u5e76\u4e14\u7531\u4e8e\u53ef\u80fd\u5bfc\u81f4\u8fde\u63a5\u5173\u95ed&#xff0c;\u6240\u4ee5\u4e00\u6b21\u53ea\u5904\u7406\u4e00\u4e2a<br \/>\n        \/\/ \u9519\u8bef\u4e8b\u4ef6\u8c03\u7528<br \/>\n        if (_revents &amp; EPOLLERR)<br \/>\n        {<br \/>\n            \/\/ \u4efb\u4f55\u4e8b\u4ef6\u90fd\u8c03\u7528&#xff0c;\u5237\u65b0\u6d3b\u8dc3\u5ea6<br \/>\n            if (_event_callback)<br \/>\n            _event_callback();<br \/>\n            if (_error_callback)<br \/>\n                _error_callback();<br \/>\n        }\/\/ \u5173\u95ed\u4e8b\u4ef6\u8c03\u7528<br \/>\n        else if (_revents &amp; EPOLLHUP)<br \/>\n        {<br \/>\n            \/\/ \u4efb\u4f55\u4e8b\u4ef6\u90fd\u8c03\u7528&#xff0c;\u5237\u65b0\u6d3b\u8dc3\u5ea6<br \/>\n            if (_event_callback)<br \/>\n            _event_callback();<br \/>\n            DBG_LOG(&#034;_CLOSE_CALLBACK&#034;);<br \/>\n            if (_close_callback)<br \/>\n            {<br \/>\n                _close_callback();<br \/>\n            }<br \/>\n        }<\/p>\n<p>    }<br \/>\n};<\/p>\n<p>#define MAX_EPOLLEVENTS 1024<br \/>\n\/\/\u5b9e\u9645\u7684\u76d1\u63a7\u8005&#xff0c;\u8d1f\u8d23\u76d1\u63a7\u6240\u6709\u4e8b\u4ef6&#xff08;\u5e76\u6839\u636echannel\u8fdb\u884c\u4e8b\u4ef6\u7ba1\u7406&#xff09;<br \/>\nclass Poller<br \/>\n{<br \/>\nprivate:<br \/>\n    int _epfd;<br \/>\n    struct epoll_event _evs[MAX_EPOLLEVENTS];<br \/>\n    std::unordered_map&lt;int, Channel *&gt; _channels;<\/p>\n<p>private:<br \/>\n    \/\/ \u5bf9epoll\u76f4\u63a5\u64cd\u4f5c<br \/>\n    void Update(Channel *channel, int op)<br \/>\n    {<br \/>\n        \/\/ \u83b7\u53d6Channel\u5bf9\u8c61\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26<br \/>\n        int fd &#061; channel-&gt;Fd();<\/p>\n<p>        \/\/ \u521b\u5efaepoll\u4e8b\u4ef6\u7ed3\u6784\u4f53<br \/>\n        struct epoll_event ev;<br \/>\n        \/\/ \u8bbe\u7f6e\u4e8b\u4ef6\u7ed3\u6784\u4f53\u4e2d\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26<br \/>\n        ev.data.fd &#061; fd;<br \/>\n        \/\/ \u8bbe\u7f6e\u4e8b\u4ef6\u7ed3\u6784\u4f53\u4e2d\u7684\u4e8b\u4ef6\u7c7b\u578b<br \/>\n        ev.events &#061; channel-&gt;Event();<\/p>\n<p>        \/\/ \u8c03\u7528epoll_ctl\u51fd\u6570\u66f4\u65b0epoll\u4e8b\u4ef6<br \/>\n        int ret &#061; epoll_ctl(_epfd, op, fd, &amp;ev);<br \/>\n        \/\/ \u5982\u679cepoll_ctl\u51fd\u6570\u6267\u884c\u5931\u8d25<br \/>\n        if (ret &lt; 0)<br \/>\n        {<br \/>\n            \/\/ \u6253\u5370\u9519\u8bef\u4fe1\u606f<br \/>\n            DBG_LOG(&#034;EPOLL_CTL FAILED&#034;);<br \/>\n        }<br \/>\n    }<br \/>\n    \/\/ \u5224\u65adchannel\u662f\u5426\u5df2\u7ecf\u88abpoller\u7ba1\u7406<br \/>\n    bool HasChannel(Channel *channel)<br \/>\n    {<br \/>\n        auto it &#061; _channels.find(channel-&gt;Fd());<\/p>\n<p>        if (it !&#061; _channels.end())<br \/>\n            return true;<br \/>\n        else<br \/>\n            return false;<br \/>\n    }<\/p>\n<p>public:<br \/>\n    Poller()<br \/>\n    {<br \/>\n        _epfd &#061; epoll_create(MAX_EPOLLEVENTS);<br \/>\n        if (_epfd &lt; 0)<br \/>\n        {<br \/>\n            DBG_LOG(&#034;EPOLL_CREATE ERROR&#034;);<br \/>\n            abort();<br \/>\n        }<br \/>\n    }<\/p>\n<p>    \/\/ \u6dfb\u52a0&#xff0c;\u4fee\u6539\u76d1\u63a7\u4e8b\u4ef6<br \/>\n    void UpdateEvent(Channel *channel)<br \/>\n    {<br \/>\n        bool ret &#061; HasChannel(channel);<br \/>\n        if (ret)<br \/>\n        {<br \/>\n            \/\/ \u5b58\u5728\u5c31\u4fee\u6539<br \/>\n            Update(channel, EPOLL_CTL_MOD);<br \/>\n        }<br \/>\n        else<br \/>\n        {<br \/>\n            _channels[channel-&gt;Fd()] &#061; channel;<br \/>\n            Update(channel, EPOLL_CTL_ADD);<br \/>\n        }<br \/>\n    }<br \/>\n    \/\/ \u79fb\u9664\u76d1\u63a7<br \/>\n    void RemoveEvent(Channel *channel)<br \/>\n    {<br \/>\n        auto it &#061; _channels.find(channel-&gt;Fd());<br \/>\n        if (it !&#061; _channels.end())<br \/>\n        {<br \/>\n            _channels.erase(it);<br \/>\n            Update(channel, EPOLL_CTL_DEL);<br \/>\n            return;<br \/>\n        }<br \/>\n        DBG_LOG(&#034;Remove Event Error&#034;);<br \/>\n    }<br \/>\n    \/\/ \u5f00\u59cb\u76d1\u63a7&#xff0c;\u83b7\u53d6\u6d3b\u8dc3\u8fde\u63a5<br \/>\n    \/\/ epoll\u4f1a\u8fd4\u56de\u5c31\u7eea\u4e8b\u4ef6\u7684fd&#xff0c;\u7136\u540e\u6839\u636efd\u518d\u67e5\u627e\u5bf9\u5e94\u7684channel,\u518d\u7531EventLoop\u8c03\u7528HandleEvent<br \/>\n    void Poll(std::vector&lt;Channel *&gt; *active)<br \/>\n    {<br \/>\n        int _nfds &#061; epoll_wait(_epfd, _evs, MAX_EPOLLEVENTS, -1);<br \/>\n        if (_nfds &lt; 0)<br \/>\n        {<br \/>\n            if (errno &#061;&#061; EINTR)<br \/>\n            {<br \/>\n                return;<br \/>\n            }<br \/>\n            ERR_LOG(&#034;EPOLL_WAIT FAILED&#034;);<br \/>\n            abort();<br \/>\n        }<\/p>\n<p>        for (int i &#061; 0; i &lt; _nfds; i&#043;&#043;)<br \/>\n        {<br \/>\n            auto it &#061; _channels.find(_evs[i].data.fd);<br \/>\n            if (it !&#061; _channels.end())<br \/>\n            {<br \/>\n                it-&gt;second-&gt;SetRevents(_evs[i].events); \/\/ \u8bbe\u7f6e\u5b9e\u9645\u5c31\u7eea\u4e8b\u4ef6\u7c7b\u578b<br \/>\n                active-&gt;push_back(it-&gt;second);<br \/>\n            }<br \/>\n            else<br \/>\n            {<br \/>\n                DBG_LOG(&#034;_CHANNELS FIND ERROR&#034;);<br \/>\n            }<br \/>\n        }<br \/>\n    }<br \/>\n}; <\/p>\n<h4 style=\"background-color:transparent\"><span style=\"color:#1f2329\">\u63cf\u8ff0\u7b26\u4e8b\u4ef6\u76d1\u63a7Poller\u7c7b\u5b9e\u73b0&#xff1a;<\/span><\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"616\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250418141252-68025de4c54c1.png\" width=\"555\" \/><\/p>\n<p>                    #define MAX_EPOLLEVENTS 1024<br \/>\n\/\/\u5b9e\u9645\u7684\u76d1\u63a7\u8005&#xff0c;\u8d1f\u8d23\u76d1\u63a7\u6240\u6709\u4e8b\u4ef6&#xff08;\u5e76\u6839\u636echannel\u8fdb\u884c\u4e8b\u4ef6\u7ba1\u7406&#xff09;<br \/>\nclass Poller<br \/>\n{<br \/>\nprivate:<br \/>\n    int _epfd;<br \/>\n    struct epoll_event _evs[MAX_EPOLLEVENTS];<br \/>\n    std::unordered_map&lt;int, Channel *&gt; _channels;<\/p>\n<p>private:<br \/>\n    \/\/ \u5bf9epoll\u76f4\u63a5\u64cd\u4f5c<br \/>\n    void Update(Channel *channel, int op)<br \/>\n    {<br \/>\n        \/\/ \u83b7\u53d6Channel\u5bf9\u8c61\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26<br \/>\n        int fd &#061; channel-&gt;Fd();<\/p>\n<p>        \/\/ \u521b\u5efaepoll\u4e8b\u4ef6\u7ed3\u6784\u4f53<br \/>\n        struct epoll_event ev;<br \/>\n        \/\/ \u8bbe\u7f6e\u4e8b\u4ef6\u7ed3\u6784\u4f53\u4e2d\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26<br \/>\n        ev.data.fd &#061; fd;<br \/>\n        \/\/ \u8bbe\u7f6e\u4e8b\u4ef6\u7ed3\u6784\u4f53\u4e2d\u7684\u4e8b\u4ef6\u7c7b\u578b<br \/>\n        ev.events &#061; channel-&gt;Event();<\/p>\n<p>        \/\/ \u8c03\u7528epoll_ctl\u51fd\u6570\u66f4\u65b0epoll\u4e8b\u4ef6<br \/>\n        int ret &#061; epoll_ctl(_epfd, op, fd, &amp;ev);<br \/>\n        \/\/ \u5982\u679cepoll_ctl\u51fd\u6570\u6267\u884c\u5931\u8d25<br \/>\n        if (ret &lt; 0)<br \/>\n        {<br \/>\n            \/\/ \u6253\u5370\u9519\u8bef\u4fe1\u606f<br \/>\n            DBG_LOG(&#034;EPOLL_CTL FAILED&#034;);<br \/>\n        }<br \/>\n    }<br \/>\n    \/\/ \u5224\u65adchannel\u662f\u5426\u5df2\u7ecf\u88abpoller\u7ba1\u7406<br \/>\n    bool HasChannel(Channel *channel)<br \/>\n    {<br \/>\n        auto it &#061; _channels.find(channel-&gt;Fd());<\/p>\n<p>        if (it !&#061; _channels.end())<br \/>\n            return true;<br \/>\n        else<br \/>\n            return false;<br \/>\n    }<\/p>\n<p>public:<br \/>\n    Poller()<br \/>\n    {<br \/>\n        _epfd &#061; epoll_create(MAX_EPOLLEVENTS);<br \/>\n        if (_epfd &lt; 0)<br \/>\n        {<br \/>\n            DBG_LOG(&#034;EPOLL_CREATE ERROR&#034;);<br \/>\n            abort();<br \/>\n        }<br \/>\n    }<\/p>\n<p>    \/\/ \u6dfb\u52a0&#xff0c;\u4fee\u6539\u76d1\u63a7\u4e8b\u4ef6<br \/>\n    void UpdateEvent(Channel *channel)<br \/>\n    {<br \/>\n        bool ret &#061; HasChannel(channel);<br \/>\n        if (ret)<br \/>\n        {<br \/>\n            \/\/ \u5b58\u5728\u5c31\u4fee\u6539<br \/>\n            Update(channel, EPOLL_CTL_MOD);<br \/>\n        }<br \/>\n        else<br \/>\n        {<br \/>\n            _channels[channel-&gt;Fd()] &#061; channel;<br \/>\n            Update(channel, EPOLL_CTL_ADD);<br \/>\n        }<br \/>\n    }<br \/>\n    \/\/ \u79fb\u9664\u76d1\u63a7<br \/>\n    void RemoveEvent(Channel *channel)<br \/>\n    {<br \/>\n        auto it &#061; _channels.find(channel-&gt;Fd());<br \/>\n        if (it !&#061; _channels.end())<br \/>\n        {<br \/>\n            _channels.erase(it);<br \/>\n            Update(channel, EPOLL_CTL_DEL);<br \/>\n            return;<br \/>\n        }<br \/>\n        DBG_LOG(&#034;Remove Event Error&#034;);<br \/>\n    }<br \/>\n    \/\/ \u5f00\u59cb\u76d1\u63a7&#xff0c;\u83b7\u53d6\u6d3b\u8dc3\u8fde\u63a5<br \/>\n    \/\/ epoll\u4f1a\u8fd4\u56de\u5c31\u7eea\u4e8b\u4ef6\u7684fd&#xff0c;\u7136\u540e\u6839\u636efd\u518d\u67e5\u627e\u5bf9\u5e94\u7684channel,\u518d\u7531EventLoop\u8c03\u7528HandleEvent<br \/>\n    void Poll(std::vector&lt;Channel *&gt; *active)<br \/>\n    {<br \/>\n        int _nfds &#061; epoll_wait(_epfd, _evs, MAX_EPOLLEVENTS, -1);<br \/>\n        if (_nfds &lt; 0)<br \/>\n        {<br \/>\n            if (errno &#061;&#061; EINTR)<br \/>\n            {<br \/>\n                return;<br \/>\n            }<br \/>\n            ERR_LOG(&#034;EPOLL_WAIT FAILED&#034;);<br \/>\n            abort();<br \/>\n        }<\/p>\n<p>        for (int i &#061; 0; i &lt; _nfds; i&#043;&#043;)<br \/>\n        {<br \/>\n            auto it &#061; _channels.find(_evs[i].data.fd);<br \/>\n            if (it !&#061; _channels.end())<br \/>\n            {<br \/>\n                it-&gt;second-&gt;SetRevents(_evs[i].events); \/\/ \u8bbe\u7f6e\u5b9e\u9645\u5c31\u7eea\u4e8b\u4ef6\u7c7b\u578b<br \/>\n                active-&gt;push_back(it-&gt;second);<br \/>\n            }<br \/>\n            else<br \/>\n            {<br \/>\n                DBG_LOG(&#034;_CHANNELS FIND ERROR&#034;);<br \/>\n            }<br \/>\n        }<br \/>\n    }<br \/>\n}; <\/p>\n<h3><\/h3>\n<h4 style=\"background-color:transparent\"><span style=\"color:#1f2329\">Reactor-EventLoop\u5b9e\u73b0&#xff1a; <\/span><\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"757\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250418141252-68025de4e412e.png\" width=\"1200\" \/><\/p>\n<p>                    class EventLoop<br \/>\n{<br \/>\n    using Functor &#061; std::function&lt;void()&gt;;<br \/>\n    std::thread::id _thread_id; \/\/ \u7ebf\u7a0bId<br \/>\n    int _event_fd;              \/\/ \u5524\u9192\u7531\u4e8eIO\u4e8b\u4ef6\u53ef\u80fd\u5bfc\u81f4\u7684\u963b\u585e<br \/>\n    std::unique_ptr&lt;Channel&gt; _event_channel;<br \/>\n    Poller _poller;              \/\/ \u5bf9\u63cf\u8ff0\u7b26\u8fdb\u884c\u76d1\u63a7<br \/>\n    std::vector&lt;Functor&gt; _tasks; \/\/ \u4efb\u52a1\u6c60<br \/>\n    std::mutex _mutex;           \/\/ \u4fdd\u969c\u5bf9\u4efb\u52a1\u6c60\u64cd\u4f5c\u7684\u5b89\u5168\u6027<br \/>\n    TimeWheel _timer_wheel;<\/p>\n<p>public:<br \/>\n    \/\/ \u6267\u884c\u4efb\u52a1\u6c60\u4e2d\u7684\u6240\u6709\u64cd\u4f5c<br \/>\n    void RunAllTask()<br \/>\n    {<br \/>\n        std::vector&lt;Functor&gt; tasks;<br \/>\n        {<br \/>\n            \/\/\u6267\u884c\u4efb\u52a1\u7684\u65f6\u5019\u76f4\u63a5\u5c06\u4efb\u52a1\u6c60\u4e2d\u7684\u4efb\u52a1\u7f6e\u6362\u51fa\u6765&#xff0c;\u518d\u5904\u7406&#xff0c;\u907f\u514d\u6267\u884c\u4efb\u52a1\u7684\u65f6\u5019\u963b\u585e\u4efb\u52a1\u6c60<br \/>\n            std::unique_lock&lt;std::mutex&gt; _lock(_mutex);<br \/>\n            tasks.swap(_tasks);<br \/>\n        }<br \/>\n        for (auto f : tasks)<br \/>\n        {<br \/>\n            f();<br \/>\n        }<br \/>\n        return;<br \/>\n    }<br \/>\n    static int CreateEventFd()<br \/>\n    {<br \/>\n        int efd &#061; eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);<br \/>\n        if (efd &lt; 0)<br \/>\n        {<br \/>\n            ERR_LOG(&#034;EVENT FD CREATE FAILED&#034;);<br \/>\n            abort();<br \/>\n        }<\/p>\n<p>        return efd;<br \/>\n    }<br \/>\n    void ReadEventFd()<br \/>\n    {<br \/>\n        uint64_t res &#061; 0;<br \/>\n        res &#061; read(_event_fd, &amp;res, sizeof(res));<br \/>\n        if (res &lt; 0)<br \/>\n        {<br \/>\n            if (errno &#061;&#061; EINTR)<br \/>\n            {<br \/>\n                return;<br \/>\n            }<br \/>\n            ERR_LOG(&#034;ReadEventFd ERROR&#034;);<br \/>\n        }<br \/>\n    }<br \/>\n    \/**<br \/>\n     * &#064;brief \u5524\u9192\u4e8b\u4ef6\u6587\u4ef6\u63cf\u8ff0\u7b26<br \/>\n     *<br \/>\n     * \u901a\u8fc7\u5411\u4e8b\u4ef6\u6587\u4ef6\u63cf\u8ff0\u7b26\u5199\u5165\u6570\u636e\u6765\u5524\u9192\u7b49\u5f85\u8be5\u63cf\u8ff0\u7b26\u7684\u7ebf\u7a0b\u3002<br \/>\n     *<br \/>\n     * &#064;return \u65e0\u8fd4\u56de\u503c<br \/>\n     *\/<br \/>\n    void WakeUpEventFd()<br \/>\n    {<br \/>\n        \/\/ \u8bbe\u7f6e\u5199\u5165\u7684\u503c<br \/>\n        uint64_t val &#061; 1;<br \/>\n        \/\/ \u5c06\u503c\u5199\u5165\u5230\u4e8b\u4ef6\u6587\u4ef6\u63cf\u8ff0\u7b26<br \/>\n        int ret &#061; write(_event_fd, &amp;val, sizeof(val));<br \/>\n        if (ret &lt; 0)<br \/>\n        {<br \/>\n            \/\/ \u5224\u65ad\u9519\u8bef\u7801\u662f\u5426\u4e3aEINTR\u6216EAGAIN<br \/>\n            \/\/ EINTR:\u88ab\u4fe1\u53f7\u6253\u65ad EAGAIN:\u65e0\u6570\u636e\u53ef\u8bfb<br \/>\n            if (errno &#061;&#061; EINTR || errno &#061;&#061; EAGAIN)<br \/>\n            {<br \/>\n                \/\/ \u5982\u679c\u662f\u8fd9\u4e24\u79cd\u9519\u8bef\u7801\u4e4b\u4e00&#xff0c;\u5219\u76f4\u63a5\u8fd4\u56de<br \/>\n                return;<br \/>\n            }<br \/>\n            \/\/ \u5982\u679c\u4e0d\u662f\u8fd9\u4e24\u79cd\u9519\u8bef\u7801&#xff0c;\u5219\u8bb0\u5f55\u9519\u8bef\u65e5\u5fd7<br \/>\n            ERR_LOG(&#034;ReadEventFd ERROR&#034;);<br \/>\n        }<br \/>\n    }<\/p>\n<p>public:<br \/>\n    EventLoop()<br \/>\n        : _thread_id(std::this_thread::get_id()),<br \/>\n          _event_fd(CreateEventFd()),<br \/>\n          _event_channel(new Channel(this, _event_fd)),<br \/>\n          _timer_wheel(this)<br \/>\n    {<br \/>\n        \/\/ \u7ed9Event_fd\u6dfb\u52a0\u56de\u8c03\u51fd\u6570\u8bfb\u53d6eventfd&#xff0c;\u901a\u8fc7readEventfd\u6765\u6253\u65adIO\u963b\u585e<br \/>\n        \/\/\u7531\u4e8eepoll\u7684\u4e8b\u4ef6\u76d1\u63a7&#xff0c;\u6709\u53ef\u80fd\u4f1a\u56e0\u4e3a\u6ca1\u6709\u4e8b\u4ef6\u5230\u6765\u2f7d\u6301\u7eed\u963b\u585e&#xff0c;\u5bfc\u81f4\u4efb\u52a1\u961f\u5217\u4e2d\u7684\u4efb\u52a1\u4e0d\u80fd\u53ca\u65f6\u5f97<br \/>\n        \/\/\u5230\u6267\u2f8f&#xff0c;\u56e0\u6b64\u521b\u5efa\u4e86eventfd&#xff0c;\u6dfb\u52a0\u5230Poller\u7684\u4e8b\u4ef6\u76d1\u63a7\u4e2d&#xff0c;\u2f64\u4e8e\u5b9e\u73b0\u6bcf\u6b21\u5411\u4efb\u52a1\u961f\u5217\u6dfb\u52a0\u4efb\u52a1\u7684\u65f6<br \/>\n        \/\/\u5019&#xff0c;\u901a\u8fc7\u5411eventfd\u5199\u2f0a\u6570\u636e\u6765\u5524\u9192epoll\u7684\u963b\u585e\u3002<br \/>\n        _event_channel-&gt;SetReadCallBack(std::bind(&amp;EventLoop::ReadEventFd, this));<br \/>\n        _event_channel-&gt;EnableRead();<br \/>\n    }<br \/>\n    \/\/ \u5224\u65ad\u8981\u6267\u884c\u7684\u4efb\u52a1\u662f\u5426\u5728\u5f53\u524d\u7ebf\u7a0b\u4e2d&#xff0c;\u5982\u679c\u662f\u5c31\u76f4\u63a5\u6267\u884c&#xff0c;\u5426\u5219\u5c31\u538b\u5165\u961f\u5217<br \/>\n    void RunInLoop(const Functor &amp;cb)<br \/>\n    {<br \/>\n        if (IsInLoop())<br \/>\n        {<br \/>\n            cb();<br \/>\n        }<br \/>\n        else<br \/>\n        {<br \/>\n            QueueInLoop(cb);<br \/>\n        }<br \/>\n    }<br \/>\n    \/\/ \u5f00\u59cb\u8fd0\u884c\u4e09\u6b65\u8d70&#8211;\u4e8b\u4ef6\u76d1\u63a7&#061;\u300b\u5c31\u7eea\u4e8b\u4ef6\u5904\u7406&#061;\u300b\u6267\u884c\u4efb\u52a1<br \/>\n    void Start()<br \/>\n    {<br \/>\n        while (1)<br \/>\n        {<br \/>\n            std::vector&lt;Channel *&gt; actives;<br \/>\n            _poller.Poll(&amp;actives);<\/p>\n<p>            \/\/\u5148\u5904\u7406\u4e8b\u4ef6\u89e6\u53d1\u7684\u56de\u8c03&#xff08;\u8bfb\u4e8b\u4ef6\u56de\u8c03&#xff0c;\u5199\u4e8b\u4ef6\u56de\u8c03&#8230;..&#xff09;<br \/>\n            for (auto &amp;channel : actives)<br \/>\n            {<br \/>\n                channel-&gt;HandleEvent();<br \/>\n            }<br \/>\n            \/\/\u7136\u540e\u518d\u6267\u884c\u4efb\u52a1\u6c60\u4e2d\u7684\u4efb\u52a1<br \/>\n            RunAllTask();<br \/>\n        }<br \/>\n    }<br \/>\n    \/\/ \u5c06\u4efb\u52a1\u538b\u5165\u961f\u5217<br \/>\n    void QueueInLoop(const Functor &amp;cb)<br \/>\n    {<br \/>\n        {<br \/>\n            std::unique_lock&lt;std::mutex&gt; _lock(_mutex);<br \/>\n            _tasks.push_back(cb);<br \/>\n        }<br \/>\n        \/\/ \u5524\u9192\u56e0\u4e3a\u6ca1\u6709\u4e8b\u4ef6\u5c31\u7eea\u4ece\u800c\u5bfc\u81f4\u7684epoll\u963b\u585e<br \/>\n        \/\/ \u5176\u5b9e\u5c31\u662f\u7ed9eventfd\u5199\u5165\u4e00\u4e2a\u6570\u636e&#xff0c;\u4ece\u800c\u89e6\u53d1\u53ef\u8bfb\u4e8b\u4ef6\u6253\u65ad\u963b\u585e<br \/>\n        \/\/ \u56e0\u4e3a\u4efb\u52a1\u6c60\u7684\u5904\u7406\u662f\u5728\u6709IO\u4e8b\u4ef6\u88ab\u89e6\u53d1\u4ee5\u540e\u624d\u4f1a\u88ab\u5904\u7406\u7684&#xff0c;\u6240\u6709\u5982\u679c\u5b8c\u5168\u6ca1\u6709IO\u4e8b\u4ef6\u5bfc\u81f4\u963b\u585e\u5c31\u4f1a\u5bfc\u81f4\u4efb\u52a1\u6c60\u7684\u4efb\u52a1\u4e5f\u4e00\u76f4\u4e0d\u88ab\u6267\u884c<br \/>\n        WakeUpEventFd();<br \/>\n    }<br \/>\n    \/\/ \u5224\u65ad\u5f53\u524d\u7ebf\u7a0b\u662f\u5426\u662fEventLoop\u5bf9\u5e94\u7684\u7ebf\u7a0b<br \/>\n    bool IsInLoop()<br \/>\n    {<br \/>\n        return (_thread_id &#061;&#061; std::this_thread::get_id());<br \/>\n    }<br \/>\n    \/\/ \u66f4\u65b0\u4e8b\u4ef6\u76d1\u63a7<br \/>\n    void UpdateEvent(Channel *channel)<br \/>\n    {<br \/>\n        _poller.UpdateEvent(channel);<br \/>\n    }<br \/>\n    \/\/ \u79fb\u9664\u4e8b\u4ef6\u76d1\u63a7<br \/>\n    void RemoveEvent(Channel *channel)<br \/>\n    {<br \/>\n        _poller.RemoveEvent(channel);<br \/>\n    }<br \/>\n    \/\/\u5bf9\u5b9a\u65f6\u5668\u7684\u64cd\u4f5c\u5c01\u88c5&#xff0c;\u65b9\u4fbf\u4e0a\u5c42\u8c03\u7528<br \/>\n    void TimerAdd(uint64_t id, uint32_t delay, const TaskFunc &amp;cb)<br \/>\n    {<br \/>\n        return _timer_wheel.TimerAdd(id, delay, cb);<br \/>\n    }<br \/>\n    void TimerRefresh(uint64_t id)<br \/>\n    {<br \/>\n        return _timer_wheel.TimerRefresh(id);<br \/>\n    }<br \/>\n    void TimerCancel(uint64_t id)<br \/>\n    {<br \/>\n        return _timer_wheel.TimerCancel(id);<br \/>\n    }<br \/>\n    bool HasTimer(uint64_t id)<br \/>\n    {<br \/>\n        return _timer_wheel.HasTimer(id);<br \/>\n    }<br \/>\n}; <\/p>\n<h4 style=\"background-color:transparent\">\u5b9a\u65f6\u5668\u6a21\u5757\u7684\u6574\u5408<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"385\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250418141253-68025de559edb.png\" width=\"1200\" \/><\/p>\n<p>                    using TaskFunc &#061; std::function&lt;void()&gt;;<br \/>\nusing ReleaseFunc &#061; std::function&lt;void()&gt;;<br \/>\nclass TimerTask<br \/>\n{<br \/>\n    uint64_t _id;         \/\/ \u5b9a\u65f6\u5668\u7684ID<br \/>\n    uint64_t _timeout;    \/\/ \u8d85\u65f6\u65f6\u95f4<br \/>\n    bool _canceled;       \/\/ \u53d6\u6d88\u5b9a\u65f6\u4efb\u52a1<br \/>\n    TaskFunc _task_cb;    \/\/ \u56de\u8c03\u51fd\u6570\u7684\u4efb\u52a1<br \/>\n    ReleaseFunc _release; \/\/ \u6e05\u9664\u65f6\u95f4\u8f6e\u4e2d\u7684\u8bb0\u5f55<\/p>\n<p>public:<br \/>\n    TimerTask(uint64_t id, uint64_t timeout, TaskFunc cb)<br \/>\n        : _id(id),<br \/>\n          _timeout(timeout),<br \/>\n          _task_cb(cb),<br \/>\n          _canceled(false)<br \/>\n    {<br \/>\n    }<\/p>\n<p>    uint64_t ID()<br \/>\n    {<br \/>\n        return _id;<br \/>\n    }<\/p>\n<p>    void SetRelease(ReleaseFunc release)<br \/>\n    {<br \/>\n        _release &#061; release;<br \/>\n    }<\/p>\n<p>    ~TimerTask()<br \/>\n    {<br \/>\n        if (!_canceled)<br \/>\n            _task_cb();<br \/>\n        _release();<br \/>\n    }<\/p>\n<p>    void Cancel()<br \/>\n    {<br \/>\n        DBG_LOG(&#034;TIMER CANCEL&#034;);<br \/>\n        _canceled &#061; true;<br \/>\n    }<br \/>\n    \/\/\u83b7\u53d6\u8d85\u65f6\u65f6\u95f4<br \/>\n    uint32_t DelayTime()<br \/>\n    {<br \/>\n        return _timeout;<br \/>\n    }<br \/>\n};<\/p>\n<p>class TimeWheel<br \/>\n{<br \/>\nprivate:<br \/>\n    using WeakTask &#061; std::weak_ptr&lt;TimerTask&gt;;<br \/>\n    using PtrTask &#061; std::shared_ptr&lt;TimerTask&gt;;<br \/>\n    int _tick;                                      \/\/ \u79d2\u9488<br \/>\n    int _capacity;                                  \/\/ \u6700\u5927\u5b9a\u65f6\u65f6\u95f4<br \/>\n    std::vector&lt;std::vector&lt;PtrTask&gt;&gt; _timeWheel;   \/\/ \u65f6\u95f4\u8f6e<br \/>\n    std::unordered_map&lt;uint32_t, WeakTask&gt; _timers; \/\/ \u7528\u6765\u4fdd\u5b58\u5b9a\u65f6\u5668\u7684\u4fe1\u606f<\/p>\n<p>    EventLoop *_loop;<br \/>\n    int _timerfd; \/\/ \u5b9a\u65f6\u5668\u63cf\u8ff0\u7b26&#8211;\u53ef\u8bfb\u4e8b\u4ef6\u56de\u8c03\u5c31\u662f\u8bfb\u53d6\u8ba1\u65f6\u5668\u6267\u884c\u5b9a\u65f6\u4efb\u52a1<br \/>\n    std::unique_ptr&lt;Channel&gt; _timer_channel;<\/p>\n<p>private:<br \/>\n    void RemoveTimer(uint64_t id)<br \/>\n    {<br \/>\n        DBG_LOG(&#034;REMOVE TIMER&#034;);<br \/>\n        auto it &#061; _timers.find(id);<br \/>\n        if (it !&#061; _timers.end())<br \/>\n        {<br \/>\n            _timers.erase(it);<br \/>\n        }<br \/>\n    }<br \/>\n    \/\/\u901a\u8fc7\u5b9a\u65f6\u5668\u6765\u8fdb\u884c\u5b9a\u65f6&#xff0c;\u89e6\u53d1\u4e00\u6b21\u8bfbIO\u4e8b\u4ef6&#xff0c;\u4fdd\u8bc1\u4e00\u79d2\u89e6\u53d1\u4e00\u6b21\u65f6\u95f4\u8f6e\u7684\u8d70\u52a8<br \/>\n    static int CreateTimerfd()<br \/>\n    {<br \/>\n        int timerfd &#061; timerfd_create(CLOCK_MONOTONIC, 0);<br \/>\n        if (timerfd &lt; 0)<br \/>\n        {<br \/>\n            ERR_LOG(&#034;CREATE TIMERFD FAILED&#034;);<br \/>\n            abort();<br \/>\n        }<\/p>\n<p>        struct itimerspec itime;<br \/>\n        itime.it_interval.tv_sec &#061; 1;<br \/>\n        itime.it_interval.tv_nsec &#061; 0;<br \/>\n        itime.it_value.tv_nsec &#061; 0;<br \/>\n        itime.it_value.tv_sec &#061; 1;<\/p>\n<p>        timerfd_settime(timerfd, 0, &amp;itime, nullptr);<br \/>\n        DBG_LOG(&#034;CREATE TIMERFD SUCCESS :%d&#034;,timerfd);<br \/>\n        return timerfd;<br \/>\n    }<br \/>\n    int ReadTimeFd()<br \/>\n    {<br \/>\n        uint64_t times;<br \/>\n        int ret &#061; read(_timerfd, &amp;times, 8);<br \/>\n        if (ret &lt; 0)<br \/>\n        {<br \/>\n            ERR_LOG(&#034;READ TIME FD:%d FAILED %s&#034;,_timerfd, strerror(errno));<br \/>\n            abort();<br \/>\n        }<\/p>\n<p>        return times;<br \/>\n    }<br \/>\n    void RunTimerTask()<br \/>\n    {<br \/>\n        \/\/ DBG_LOG(&#034;\u65f6\u95f4\u8f6e\u88ab\u9a71\u52a8&#034;);<br \/>\n        _tick &#061; (_tick &#043; 1) % _capacity;<br \/>\n        _timeWheel[_tick].clear();<br \/>\n    }<br \/>\n    \/\/\u5b9a\u65f6\u5668\u7684\u56de\u8c03\u8bfb\u4e8b\u4ef6&#xff0c;\u8bfb\u4e8b\u4ef6\u56de\u8c03\u4f1a\u88abIO\u4e8b\u4ef6\u89e6\u53d1\u5f15\u53d1\u8bfb\u56de\u8c03&#xff08;\u8bbe\u7f6e\u4e3a\u8be5OnTime\u51fd\u6570&#xff09;&#xff0c;\u6839\u636e\u8d85\u65f6\u65f6\u95f4&#xff0c;\u79fb\u52a8\u65f6\u95f4\u8f6e\u53bb\u6267\u884c\u5b9a\u65f6\u4efb\u52a1<br \/>\n    void OnTime()<br \/>\n    {<br \/>\n        int ret &#061; ReadTimeFd();<br \/>\n        for (int i &#061; 0; i &lt; ret; i&#043;&#043;)<br \/>\n            RunTimerTask();<br \/>\n    }<\/p>\n<p>public:<br \/>\n    TimeWheel(EventLoop *loop)<br \/>\n        : _tick(0),<br \/>\n          _capacity(60),<br \/>\n          _timeWheel(_capacity),<br \/>\n          _loop(loop),<br \/>\n          _timerfd(CreateTimerfd()),<br \/>\n          _timer_channel(new Channel(_loop, _timerfd))<br \/>\n    {<br \/>\n        _timer_channel-&gt;SetReadCallBack(std::bind(&amp;TimeWheel::OnTime, this));<br \/>\n        _timer_channel-&gt;EnableRead();<br \/>\n    }<\/p>\n<p>    void TimerAdd(uint64_t id, uint64_t delay, TaskFunc cb);<\/p>\n<p>    void TimerRefresh(uint64_t id);<\/p>\n<p>    void TimerCancel(uint64_t id);<br \/>\n    \/\/ \u8be5\u63a5\u53e3\u5b58\u5728\u7ebf\u7a0b\u5b89\u5168\u95ee\u9898&#xff0c;\u53ea\u80fd\u5728\u5bf9\u5e94\u7684EventLoop\u7ebf\u7a0b\u4e2d\u88ab\u8c03\u7528<br \/>\n    bool HasTimer(uint64_t id)<br \/>\n    {<br \/>\n        auto it &#061; _timers.find(id);<br \/>\n        if (it !&#061; _timers.end())<br \/>\n        {<br \/>\n            return true;<br \/>\n        }<br \/>\n        return false;<br \/>\n    }<\/p>\n<p>    void TimerAddInLoop(uint64_t id, uint64_t timeout, TaskFunc cb)<br \/>\n    {<br \/>\n        PtrTask pt(new TimerTask(id, timeout, cb)); \/\/ \u521b\u5efa\u4efb\u52a1<\/p>\n<p>        pt-&gt;SetRelease(std::bind(&amp;TimeWheel::RemoveTimer, this, id)); \/\/ \u8bbe\u7f6e\u5220\u9664\u51fd\u6570\u56de\u8c03<br \/>\n        int pos &#061; (_tick &#043; pt-&gt;DelayTime()) % _capacity;              \/\/ \u627e\u5230\u8981\u63d2\u5165\u5230\u65f6\u95f4\u8f6e\u7684\u4f4d\u7f6e<br \/>\n        _timeWheel[pos].push_back(pt);                                \/\/ \u63d2\u5165\u65f6\u95f4\u8f6e<br \/>\n        _timers[id] &#061; WeakTask(pt);                                   \/\/ \u4fdd\u5b58\u5b9a\u65f6\u5668\u7684\u4fe1\u606f<br \/>\n    }<\/p>\n<p>    void TimerRefreshInLoop(uint64_t id)<br \/>\n    {<br \/>\n        auto it &#061; _timers.find(id);<br \/>\n        if (it &#061;&#061; _timers.end())<br \/>\n        {<br \/>\n            return; \/\/ \u6ca1\u627e\u7740\u5b9a\u65f6\u4efb\u52a1&#xff0c;\u6ca1\u6cd5\u5237\u65b0&#xff0c;\u6ca1\u6cd5\u5ef6\u8fdf<br \/>\n        }<br \/>\n        PtrTask pt &#061; it-&gt;second.lock();<br \/>\n        int pos &#061; (_tick &#043; pt-&gt;DelayTime()) % _capacity; \/\/ \u627e\u5230\u8981\u63d2\u5165\u5230\u65f6\u95f4\u8f6e\u7684\u4f4d\u7f6e<br \/>\n        _timeWheel[pos].push_back(pt);                   \/\/ \u63d2\u5165\u65f6\u95f4\u8f6e<br \/>\n        \/\/ DBG_LOG(&#034;\u65f6\u95f4\u8f6e\u88ab\u5237\u65b0&#034;);<br \/>\n    }<\/p>\n<p>    void TimerCancelInLoop(uint64_t id)<br \/>\n    {<br \/>\n        auto it &#061; _timers.find(id);<br \/>\n        if (it &#061;&#061; _timers.end())<br \/>\n        {<br \/>\n            return; \/\/ \u6ca1\u627e\u7740\u5b9a\u65f6\u4efb\u52a1&#xff0c;\u6ca1\u6cd5\u5237\u65b0&#xff0c;\u6ca1\u6cd5\u5ef6\u8fdf<br \/>\n        }<\/p>\n<p>        PtrTask pt &#061; it-&gt;second.lock();<br \/>\n        if(pt)<br \/>\n        pt-&gt;Cancel();<br \/>\n        else DBG_LOG(&#034;TIMER CANCEL ERROR! PT IS NULL&#034;);<br \/>\n        DBG_LOG(&#034;TIMER CANCEL IN LOOP&#034;);<br \/>\n    }<br \/>\n}; <\/p>\n<h4 style=\"background-color:transparent\">Connection\u6a21\u5757<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"840\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250418141253-68025de5b50b6.png\" width=\"1200\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"195\" src=\"2025-04-18a3dipalbate.png\" width=\"1200\" \/><\/p>\n<p>                    \/\/ DISCONNECTED \u5df2\u7ecf\u5173\u95ed<br \/>\n\/\/ CONNECTING \u8fde\u63a5\u5efa\u7acb\u6210\u529f-\u5f85\u5904\u7406\u72b6\u6001<br \/>\n\/\/ CONNECTED \u8fde\u63a5\u5df2\u7ecf\u5efa\u7acb\u5b8c\u6210&#xff0c;\u5404\u9879\u8bbe\u7f6e\u5df2\u5c31\u7eea&#xff0c;\u53ef\u4ee5\u901a\u4fe1<br \/>\n\/\/ DISCONNECTING \u51c6\u5907\u65ad\u5f00\u8fde\u63a5<br \/>\ntypedef enum<br \/>\n{<br \/>\n    DISCONNECTED,<br \/>\n    CONNECTING,<br \/>\n    CONNECTED,<br \/>\n    DISCONNECTING<br \/>\n} ConnStatu;<\/p>\n<p>class Connection;<br \/>\nusing PtrConnection &#061; std::shared_ptr&lt;Connection&gt;;<br \/>\nclass Connection : public std::enable_shared_from_this&lt;Connection&gt;<br \/>\n    \/\/\u7ee7\u627f\u81eastd::enable_shared_from_this&lt;Connection&gt;&#xff0c;\u8fd9\u6837\u5c31\u53ef\u4ee5\u5728Connection\u5185\u90e8\u83b7\u53d6\u81ea\u5df1\u7684shared_ptr\u7ba1\u7406\u5bf9\u8c61<br \/>\n{<\/p>\n<p>    int _conn_id; \/\/ Connection\u7684id<br \/>\n    \/\/ _tiemr_id \u5b9a\u65f6\u5668id&#xff0c;\u8fd9\u91cc\u4f7f\u7528conn_id\u4ee3\u66ff<br \/>\n    int _sockfd;                           \/\/ \u8fde\u63a5\u5173\u8054\u7684\u63cf\u8ff0\u7b26<br \/>\n    ConnStatu _statu;                      \/\/ \u8fde\u63a5\u72b6\u6001<br \/>\n    EventLoop *_loop;                      \/\/ \u8fde\u63a5\u5173\u8054\u4e00\u4e2aEventLoop<br \/>\n    bool _enable_inactive_release &#061; false; \/\/ \u662f\u5426\u542f\u52a8\u975e\u6d3b\u8dc3\u81ea\u52a8\u9500\u6bc1&#xff0c;\u9ed8\u8ba4\u5173\u95ed<br \/>\n    Socket _socket;                        \/\/ \u5bf9\u5957\u63a5\u5b57\u7684\u7ba1\u7406<br \/>\n    Channel _channel;                      \/\/ \u5bf9\u8fde\u63a5\u4e8b\u4ef6\u7684\u7ba1\u7406<br \/>\n    Buffer _in_buffer;                     \/\/ \u8f93\u5165\u7f13\u51b2\u533a<br \/>\n    Buffer _out_buffer;                    \/\/ \u8f93\u51fa\u7f13\u51b2\u533a<br \/>\n    Any _context;                          \/\/ \u8fde\u63a5\u7684\u4e0a\u4e0b\u6587<\/p>\n<p>    using ConnectedCallBack &#061; std::function&lt;void(const PtrConnection &amp;)&gt;;<br \/>\n    using MessageCallBack &#061; std::function&lt;void(const PtrConnection &amp;, Buffer *)&gt;;<br \/>\n    using ClosedCallBack &#061; std::function&lt;void(const PtrConnection &amp;)&gt;;<br \/>\n    using AnyEventCallBack &#061; std::function&lt;void(const PtrConnection &amp;)&gt;;<br \/>\n    ConnectedCallBack _connected_callback;<br \/>\n    MessageCallBack _message_callback;<br \/>\n    ClosedCallBack _closed_callback;<br \/>\n    AnyEventCallBack _event_callback;<br \/>\n    \/\/ \u670d\u52a1\u5668\u7684\u8fde\u63a5\u5173\u95ed\u56de\u8c03\u51fd\u6570&#8211;\u7ec4\u4ef6\u5185\u8bbe\u7f6e&#xff0c;\u670d\u52a1\u5668\u4f1a\u628a\u6240\u6709\u8fde\u63a5\u7ba1\u7406\u8d77\u6765<br \/>\n    \/\/ \u4e00\u65e6\u67d0\u4e2a\u8fde\u63a5\u8981\u5173\u95ed&#xff0c;\u5c31\u5e94\u8be5\u628a\u81ea\u5df1\u7684\u4fe1\u606f\u4ece\u7ba1\u7406\u7684\u5730\u65b9\u79fb\u9664<br \/>\n    ClosedCallBack _server_closed_callback;<\/p>\n<p>private:<br \/>\n    \/\/ \u76d1\u63a7\u53ef\u8bfb\u4e8b\u4ef6\u7684\u56de\u8c03\u51fd\u6570&#xff0c;\u8bfb\u53d6\u7f13\u51b2\u533a\u7684\u6570\u636e\u8c03\u7528_read_callback<br \/>\n    void HandleRead()<br \/>\n    {<br \/>\n        DBG_LOG(&#034;HANDLE READ&#034;);<br \/>\n        \/\/ 1. \u63a5\u6536socket\u7684\u6570\u636e&#xff0c;\u653e\u5230\u7f13\u51b2\u533a<br \/>\n        char buf[65536];<br \/>\n        ssize_t ret &#061; _socket.NoBlockRecv(buf, 65535);<br \/>\n        if (ret &lt; 0)<br \/>\n        {<br \/>\n            \/\/ \u51fa\u9519\u4e86,\u4e0d\u80fd\u76f4\u63a5\u5173\u95ed\u8fde\u63a5<br \/>\n            DBG_LOG(&#034;RECV ERROR AND SHUT DOWN&#034;);<br \/>\n            return ShutDownInLoop();<br \/>\n        }<br \/>\n        \/\/ \u8fd9\u91cc\u7684\u7b49\u4e8e0\u8868\u793a\u7684\u662f\u6ca1\u6709\u8bfb\u53d6\u5230\u6570\u636e&#xff0c;\u800c\u5e76\u4e0d\u662f\u8fde\u63a5\u65ad\u5f00\u4e86&#xff0c;\u8fde\u63a5\u65ad\u5f00\u8fd4\u56de\u7684\u662f-1<br \/>\n        \/\/ \u5c06\u6570\u636e\u653e\u5165\u8f93\u5165\u7f13\u51b2\u533a,\u5199\u5165\u4e4b\u540e\u987a\u4fbf\u5c06\u5199\u504f\u79fb\u5411\u540e\u79fb\u52a8<br \/>\n        _in_buffer.WriteAndPush(buf, ret);<br \/>\n        \/\/ 2. \u8c03\u7528message_callback\u8fdb\u884c\u4e1a\u52a1\u5904\u7406<br \/>\n        if (_in_buffer.ReadAbleSize() &gt; 0)<br \/>\n        {<br \/>\n            DBG_LOG(&#034;_message_callback()&#034;);<br \/>\n            \/\/ shared_from_this&#8211;\u4ece\u5f53\u524d\u5bf9\u8c61\u81ea\u8eab\u83b7\u53d6\u81ea\u8eab\u7684shared_ptr\u7ba1\u7406\u5bf9\u8c61<br \/>\n            if (_message_callback)<br \/>\n                return _message_callback(shared_from_this(), &amp;_in_buffer);<br \/>\n            DBG_LOG(&#034;_message_callback()&#034;);<br \/>\n        }<br \/>\n        DBG_LOG(&#034;HANDLE READ END&#034;);<br \/>\n    }<br \/>\n    \/\/ \u76d1\u63a7\u53ef\u5199\u4e8b\u4ef6\u7684\u56de\u8c03\u51fd\u6570&#xff0c;\u53d1\u9001\u7f13\u51b2\u533a\u4e2d\u7684\u6570\u636e<br \/>\n    void HandleWrite()<br \/>\n    {<br \/>\n        DBG_LOG(&#034;HANDLE WRITE&#034;);<br \/>\n        int ret &#061; _socket.NoBlockSend(_out_buffer.ReadPosition(), _out_buffer.ReadAbleSize());<br \/>\n        if (ret &lt; 0)<br \/>\n        {<br \/>\n            \/\/ \u53d1\u9001\u9519\u8bef\u5c31\u8981\u5173\u95ed\u8fde\u63a5&#xff0c;\u4f46\u662f\u8981\u5148\u628a\u7f13\u51b2\u533a\u63a5\u6536\u5230\u5269\u4f59\u6570\u636e\u5904\u7406\u5b8c\u6bd5<br \/>\n            if (_in_buffer.ReadAbleSize() &gt; 0)<br \/>\n            {<br \/>\n                _message_callback(shared_from_this(), &amp;_in_buffer);<br \/>\n            }<br \/>\n            return Release();<br \/>\n        }<br \/>\n        _out_buffer.MoveReadOffset(ret); \/\/ \u8fd9\u91cc\u5e94\u8be5\u662f\u5c06\u8bfb\u53d6\u6570\u636e\u4f4d\u7f6e\u5411\u540e\u504f\u79fb&#xff0c;\u800c\u4e0d\u662f\u53ef\u5199&#xff0c;\u53ef\u5199\u662f\u5199\u5165\u6570\u636e\u65f6\u79fb\u52a8\u7684<br \/>\n        DBG_LOG(&#034;\u5269\u4f59\u6570\u636e\u91cf&#xff1a;%ld,status:%d&#034;, _out_buffer.ReadAbleSize(), _statu);<\/p>\n<p>        if (_out_buffer.ReadAbleSize() &#061;&#061; 0)<br \/>\n        {<br \/>\n            _channel.DisableWrite(); \/\/ \u6ca1\u6709\u6570\u636e\u8981\u53d1\u9001&#xff0c;\u5173\u95ed\u5199\u4e8b\u4ef6\u76d1\u63a7&#xff0c;\u907f\u514d\u88ab\u91cd\u590d\u89e6\u53d1<br \/>\n            \/\/ \u5982\u679c\u5f53\u524d\u662f\u8fde\u63a5\u5f85\u5173\u95ed\u72b6\u6001&#xff0c;\u5219\u6709\u6570\u636e&#xff0c;\u53d1\u9001\u5b8c\u6570\u636e\u91ca\u653e\u8fde\u63a5&#xff0c;\u6ca1\u6709\u6570\u636e\u5219\u76f4\u63a5\u91ca\u653e<br \/>\n            if (_statu &#061;&#061; DISCONNECTING)<br \/>\n            {<br \/>\n                return Release();<br \/>\n            }<br \/>\n        }<\/p>\n<p>        \/\/ \u5982\u679c\u662f\u5f85\u5173\u95ed\u8fde\u63a5\u72b6\u6001&#xff0c;\u90a3\u4e48\u6709\u6570\u636e\u5c31\u5148\u5904\u7406\u6570\u636e&#xff0c;\u6ca1\u6709\u5219\u76f4\u63a5\u91ca\u653e<br \/>\n    }<br \/>\n    \/\/ \u76d1\u63a7\u5173\u95ed\u4e8b\u4ef6\u7684\u56de\u8c03\u51fd\u6570<br \/>\n    void HandleClose()<br \/>\n    {<br \/>\n        DBG_LOG(&#034;HANDLE CLOSE&#034;);<br \/>\n        if (_in_buffer.ReadAbleSize() &gt; 0)<br \/>\n        {<br \/>\n            _message_callback(shared_from_this(), &amp;_in_buffer);<br \/>\n        }<br \/>\n        return Release();<br \/>\n    }<br \/>\n    \/\/ \u76d1\u63a7\u9519\u8bef\u4e8b\u4ef6\u7684\u56de\u8c03\u51fd\u6570<br \/>\n    void HandleError()<br \/>\n    {<br \/>\n        return HandleClose();<br \/>\n    }<br \/>\n    \/\/ \u76d1\u63a7\u4efb\u610f\u4e8b\u4ef6\u7684\u56de\u8c03\u51fd\u6570 1.\u5237\u65b0\u6d3b\u8dc3\u5ea6 2.\u8c03\u7528\u56de\u8c03<br \/>\n    void HandleEvent()<br \/>\n    {<br \/>\n        if (_enable_inactive_release &#061;&#061; true)<br \/>\n        {<br \/>\n            _loop-&gt;TimerRefresh(_conn_id);<br \/>\n        }<br \/>\n        if (_event_callback)<br \/>\n        {<br \/>\n            _event_callback(shared_from_this());<br \/>\n        }<br \/>\n    }<br \/>\n    \/\/ \u8fde\u63a5\u83b7\u53d6\u4ee5\u540e\u8981\u8fdb\u884c\u5404\u79cd\u8bbe\u7f6e&#xff08;\u7ed9channel\u8bbe\u7f6e\u56de\u8c03&#xff0c;\u542f\u52a8\u8bfb\u76d1\u63a7&#xff09;<br \/>\n    void EstablishedInLoop()<br \/>\n    {<br \/>\n        \/\/ 1.\u4fee\u6539\u8fde\u63a5\u72b6\u6001 2.\u542f\u52a8\u8bfb\u4e8b\u4ef6\u76d1\u63a7 3.\u8c03\u7528\u56de\u8c03\u51fd\u6570<br \/>\n        \/\/ \u5f53\u524d\u6b65\u9aa4\u4e00\u5b9a\u662f\u5904\u4e8e\u534a\u8fde\u63a5\u72b6\u6001&#xff0c;\u5426\u5219\u5fc5\u7136\u662f\u51fa\u9519\u4e86<br \/>\n        if (_statu !&#061; CONNECTING)<br \/>\n        {<br \/>\n            ERR_LOG(&#034;ESTABLISHED IN LOOP ERROR&#034;);<br \/>\n            abort();<br \/>\n        }<br \/>\n        _statu &#061; CONNECTED;<br \/>\n        _channel.EnableRead();<br \/>\n        if (_connected_callback)<br \/>\n            _connected_callback(shared_from_this());<br \/>\n    }<br \/>\n    \/\/ \u5b9e\u9645\u7684\u91ca\u653e\u63a5\u53e3<br \/>\n    void ReleaseInLoop()<br \/>\n    {<br \/>\n        DBG_LOG(&#034;REALEASE IN LOOP&#034;);<br \/>\n        \/\/ 1.\u4fee\u6539\u8fde\u63a5\u72b6\u6001&#xff0c;\u8bbe\u4e3aDISCONNECTED<br \/>\n        _statu &#061; DISCONNECTED;<br \/>\n        \/\/ 2.\u79fb\u9664\u8fde\u63a5\u4e8b\u4ef6\u76d1\u63a7<br \/>\n        _channel.Remove();<br \/>\n        \/\/ 3.\u5173\u95ed\u63cf\u8ff0\u7b26<br \/>\n        _socket.Close();<br \/>\n        \/\/ DBG_LOG(&#034;REALEASE IN LOOP MIDDLE&#034;);<br \/>\n        \/\/ 4.\u5982\u679c\u5f53\u524d\u5b9a\u65f6\u5668\u961f\u5217\u4e2d\u8fd8\u6709\u4efb\u52a1&#xff0c;\u5219\u53d6\u6d88\u4efb\u52a1<br \/>\n        if (_loop-&gt;HasTimer(_conn_id))<br \/>\n        {<br \/>\n            CancelInactiveReleaseInLoop();<br \/>\n        }<br \/>\n        DBG_LOG(&#034;REALEASE IN LOOP MIDDLE&#034;);<br \/>\n        \/\/ 5.\u5148\u8c03\u7528\u5173\u95ed\u56de\u8c03\u51fd\u6570&#xff0c;\u907f\u514d\u5148\u79fb\u9664\u670d\u52a1\u5668\u5185\u90e8\u4fe1\u606f\u5bfc\u81f4Connection\u88ab\u9500\u6bc1&#xff0c;\u518d\u5904\u7406\u4f1a\u51fa\u9519<br \/>\n        if (_closed_callback)<br \/>\n            _closed_callback(shared_from_this());<br \/>\n        \/\/ \u79fb\u9664\u670d\u52a1\u5668\u5185\u90e8\u7684\u8fde\u63a5\u4fe1\u606f<br \/>\n        if (_server_closed_callback)<br \/>\n            _server_closed_callback(shared_from_this());<br \/>\n        DBG_LOG(&#034;REALEASE IN LOOP END&#034;);<br \/>\n    }<br \/>\n    \/\/ \u5e76\u975e\u5b9e\u9645\u7684\u6570\u636e\u53d1\u9001\u63a5\u53e3&#xff0c;\u53ea\u662f\u5c06\u6570\u636e\u5199\u5165\u7f13\u51b2\u533a&#xff0c;\u542f\u52a8\u5199\u4e8b\u4ef6<br \/>\n    void SendInLoop(Buffer &amp;buf)<br \/>\n    {<br \/>\n        if (_statu &#061;&#061; DISCONNECTED)<br \/>\n            return;<br \/>\n        _out_buffer.WriteBufferAndPush(buf);<br \/>\n        if (_channel.WriteAble() &#061;&#061; false)<br \/>\n        {<br \/>\n            _channel.EnableWrite();<br \/>\n        }<br \/>\n    }<br \/>\n    \/\/ \u5e76\u975e\u5b9e\u9645\u7684\u5173\u95ed\u8fde\u63a5\u63a5\u53e3&#xff0c;\u8fd8\u9700\u8981\u5224\u65ad\u6570\u636e\u662f\u5426\u5904\u7406\u5b8c\u6bd5<br \/>\n    void ShutDownInLoop()<br \/>\n    {<br \/>\n        DBG_LOG(&#034;SHUT DWON IN LOOP&#034;);<br \/>\n        _statu &#061; DISCONNECTING;<br \/>\n        if (_in_buffer.ReadAbleSize() &gt; 0)<br \/>\n        {<br \/>\n            if (_message_callback)<br \/>\n                _message_callback(shared_from_this(), &amp;_in_buffer);<br \/>\n        }<\/p>\n<p>        \/\/ \u8981\u4e48\u5199\u5165\u6570\u636e\u51fa\u9519\u5173\u95ed&#xff0c;\u8981\u4e48\u6570\u636e\u53d1\u9001\u5b8c\u7136\u540e\u518d\u5173\u95ed<br \/>\n        if (_out_buffer.ReadAbleSize() &gt; 0)<br \/>\n        {<br \/>\n            if (_channel.WriteAble() &#061;&#061; false)<br \/>\n            {<br \/>\n                _channel.EnableWrite();<br \/>\n            }<br \/>\n        }<\/p>\n<p>        if (_out_buffer.ReadAbleSize() &#061;&#061; 0)<br \/>\n        {<br \/>\n            DBG_LOG(&#034;BUFFER EMPTY AND RELEASE IN LOOP&#034;);<br \/>\n            Release();<br \/>\n        }<br \/>\n        DBG_LOG(&#034;SHUT DOWN IN LOOP:%ld&#034;, _out_buffer.ReadAbleSize());<br \/>\n    }<br \/>\n    \/\/ \u542f\u52a8\u975e\u6d3b\u8dc3\u8fde\u63a5\u8d85\u65f6<br \/>\n    void EnableInactiveReleaseInLoop(int sec)<br \/>\n    {<br \/>\n        _enable_inactive_release &#061; true;<br \/>\n        \/\/ \u5982\u679c\u5b9a\u65f6\u9500\u6bc1\u4efb\u52a1\u5df2\u7ecf\u5b58\u5728&#xff0c;\u5219\u9700\u8981\u5148\u5237\u65b0\u4efb\u52a1\u4e00\u4e0b<br \/>\n        if (_loop-&gt;HasTimer(_conn_id))<br \/>\n        {<br \/>\n            return _loop-&gt;TimerRefresh(_conn_id);<br \/>\n        }<br \/>\n        \/\/ \u5982\u679c\u4e0d\u5b58\u5728\u5b9a\u65f6\u9500\u6bc1\u4efb\u52a1\u5219\u65b0\u589e<br \/>\n        DBG_LOG(&#034;ENABLE INACTIVE RELEASE IN LOOP&#034;);<br \/>\n        _loop-&gt;TimerAdd(_conn_id, sec, std::bind(&amp;Connection::Release, this));<br \/>\n    }<br \/>\n    void CancelInactiveReleaseInLoop()<br \/>\n    {<br \/>\n        _enable_inactive_release &#061; false;<br \/>\n        if (_loop-&gt;HasTimer(_conn_id))<br \/>\n        {<br \/>\n            return _loop-&gt;TimerCancel(_conn_id);<br \/>\n        }<br \/>\n    }<br \/>\n    void UpgradeInLoop(const Any &amp;context, const ConnectedCallBack &amp;con, const MessageCallBack &amp;msg, const ClosedCallBack &amp;clo, const AnyEventCallBack &amp;evt)<br \/>\n    {<br \/>\n        _context &#061; context;<br \/>\n        _connected_callback &#061; con;<br \/>\n        _message_callback &#061; msg;<br \/>\n        _closed_callback &#061; clo;<br \/>\n        _event_callback &#061; evt;<br \/>\n    }<\/p>\n<p>public:<br \/>\n    Connection(EventLoop *loop, uint64_t coon_id, int sockfd) : _conn_id(coon_id), _sockfd(sockfd), _enable_inactive_release(false), _loop(loop),<br \/>\n                                                                _statu(CONNECTING), _socket(sockfd), _channel(loop, _sockfd)<br \/>\n    {<br \/>\n        _channel.SetReadCallBack(std::bind(&amp;Connection::HandleRead, this));<br \/>\n        _channel.SetWriteCallBack(std::bind(&amp;Connection::HandleWrite, this));<br \/>\n        _channel.SetCloseCallBack(std::bind(&amp;Connection::HandleClose, this));<br \/>\n        _channel.SetErrorCallBack(std::bind(&amp;Connection::HandleError, this));<br \/>\n        _channel.SetEventCallBack(std::bind(&amp;Connection::HandleEvent, this));<br \/>\n    }<br \/>\n    ~Connection() { DBG_LOG(&#034;RELEASE CONNECTION :%p&#034;, this); }<br \/>\n    \/\/ \u53d1\u9001\u6570\u636e&#xff0c;\u5c06\u6570\u636e\u653e\u5230\u7f13\u51b2\u533a&#xff0c;\u542f\u52a8\u5199\u4e8b\u4ef6\u76d1\u63a7<br \/>\n    void Send(const char *data, size_t len)<br \/>\n    {<br \/>\n        Buffer buf;<br \/>\n        buf.WriteAndPush(data, len);<br \/>\n        _loop-&gt;RunInLoop(std::bind(&amp;Connection::SendInLoop, this, std::move(buf)));<br \/>\n    }<br \/>\n    int Fd()<br \/>\n    {<br \/>\n        return _sockfd;<br \/>\n    }<br \/>\n    int Id()<br \/>\n    {<br \/>\n        return _conn_id;<br \/>\n    }<br \/>\n    \/\/ \u8fdb\u884cchannel\u56de\u8c03&#xff0c;\u542f\u52a8\u8bfb\u76d1\u63a7&#xff0c;\u8c03\u7528_connected_callback<br \/>\n    void Establish()<br \/>\n    {<br \/>\n        _loop-&gt;RunInLoop(std::bind(&amp;Connection::EstablishedInLoop, this));<br \/>\n    }<br \/>\n    \/\/ \u662f\u5426\u5904\u4e8e\u8fde\u63a5\u72b6\u6001<br \/>\n    bool Connected()<br \/>\n    {<br \/>\n        return _statu;<br \/>\n    }<br \/>\n    \/\/ \u8bbe\u7f6e\u4e0a\u4e0b\u6587<br \/>\n    void SetContext(const Any &amp;context)<br \/>\n    {<br \/>\n        _context &#061; context;<br \/>\n    }<br \/>\n    \/\/ \u83b7\u53d6\u4e0a\u4e0b\u6587<br \/>\n    Any *GetContext()<br \/>\n    {<br \/>\n        return &amp;_context;<br \/>\n    }<br \/>\n    \/\/ \u8bbe\u7f6e\u56de\u8c03<br \/>\n    void SetConnectedCallBack(const ConnectedCallBack &amp;cb)<br \/>\n    {<br \/>\n        _connected_callback &#061; cb;<br \/>\n    }<br \/>\n    void SetMessageCallBack(const MessageCallBack &amp;cb)<br \/>\n    {<br \/>\n        _message_callback &#061; cb;<br \/>\n    }<br \/>\n    void SetClosedCallBack(const ClosedCallBack &amp;cb)<br \/>\n    {<br \/>\n        _closed_callback &#061; cb;<br \/>\n    }<br \/>\n    void SetAnyEventCallBack(const AnyEventCallBack &amp;cb)<br \/>\n    {<br \/>\n        _event_callback &#061; cb;<br \/>\n    }<br \/>\n    void SetSrvClosedCallBack(const ClosedCallBack &amp;cb)<br \/>\n    {<br \/>\n        _server_closed_callback &#061; cb;<br \/>\n    }<br \/>\n    \/\/ \u63d0\u4f9b\u7ed9\u7ec4\u4ef6\u4f7f\u7528\u8005\u7684\u5173\u95ed\u63a5\u53e3&#xff0c;\u5e76\u4e0d\u5b9e\u9645\u5173\u95ed&#xff0c;\u8fd8\u9700\u8981\u5224\u65ad\u6570\u636e\u5b9e\u9645\u662f\u5426\u5904\u7406\u5b8c\u6bd5<br \/>\n    void ShutDown()<br \/>\n    {<br \/>\n        _loop-&gt;RunInLoop(std::bind(&amp;Connection::ShutDownInLoop, this));<br \/>\n    }<br \/>\n    void Release()<br \/>\n    {<br \/>\n        _loop-&gt;QueueInLoop(std::bind(&amp;Connection::ReleaseInLoop, this));<br \/>\n    }<br \/>\n    \/\/ \u542f\u52a8\u975e\u6d3b\u8dc3\u9500\u6bc1<br \/>\n    void EnableInactiveRelease(int sec)<br \/>\n    {<br \/>\n        _loop-&gt;RunInLoop(std::bind(&amp;Connection::EnableInactiveReleaseInLoop, this, sec));<br \/>\n    }<br \/>\n    \/\/ \u53d6\u6d88\u975e\u6d3b\u8dc3\u9500\u6bc1<br \/>\n    void CancelInactiveRelease()<br \/>\n    {<br \/>\n        _loop-&gt;RunInLoop(std::bind(&amp;Connection::CancelInactiveReleaseInLoop, this));<br \/>\n    }<br \/>\n    \/\/ \u5207\u6362\u534f\u8bae-\u91cd\u7f6e\u4e0a\u4e0b\u6587\u53ca\u5904\u7406\u9636\u6bb5\u6027\u6570\u636e \u975e\u7ebf\u7a0b\u5b89\u5168<br \/>\n    void Upgrade(const Any &amp;context, const ConnectedCallBack &amp;con, const MessageCallBack &amp;msg, const ClosedCallBack &amp;clo, const AnyEventCallBack &amp;evt)<br \/>\n    {<br \/>\n        _loop-&gt;RunInLoop(std::bind(&amp;Connection::UpgradeInLoop, this, context, con, msg, clo, evt));<br \/>\n    }<br \/>\n}; <\/p>\n<h4 style=\"background-color:transparent\">Accepter\u6a21\u5757<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"480\" src=\"2025-04-181zrozjghkhc.png\" width=\"1200\" \/><\/p>\n<p>                    class Accepter<br \/>\n{<br \/>\nprivate:<br \/>\n    Socket _socket;   \/\/ \u521b\u5efa\u76d1\u542c\u5957\u63a5\u5b57<br \/>\n    EventLoop *_loop; \/\/ \u5bf9\u76d1\u542c\u5957\u63a5\u5b57\u8fdb\u884c\u4e8b\u4ef6\u76d1\u63a7<br \/>\n    Channel _channel; \/\/ \u5bf9\u76d1\u542c\u4e8b\u4ef6\u8fdb\u884c\u4e8b\u4ef6\u7ba1\u7406<\/p>\n<p>    using AcceptCallBack &#061; std::function&lt;void(int)&gt;;<br \/>\n    AcceptCallBack _accept_callback;<\/p>\n<p>private:<br \/>\n    \/\/ \u76d1\u542c\u5957\u63a5\u5b57\u8bfb\u4e8b\u4ef6\u7684\u56de\u8c03&#8211;\u83b7\u53d6\u65b0\u8fde\u63a5 \u56de\u8c03_accept_callback<br \/>\n    void HandleRead()<br \/>\n    {<br \/>\n        int newfd &#061; _socket.Accept();<br \/>\n        if (newfd &lt; 0)<br \/>\n        {<br \/>\n            return;<br \/>\n        }<br \/>\n        if (_accept_callback)<br \/>\n            _accept_callback(newfd);<br \/>\n    }<br \/>\n    int CreateServer(int port)<br \/>\n    {<br \/>\n        bool ret &#061; _socket.CreateServer(port);<br \/>\n        if (ret &#061;&#061; false)<br \/>\n        {<br \/>\n            abort();<br \/>\n        }<br \/>\n        return _socket.Fd();<br \/>\n    }<\/p>\n<p>public:<br \/>\n    Accepter(EventLoop *loop, int port)<br \/>\n        : _socket(CreateServer(port)),<br \/>\n          _loop(loop),<br \/>\n          _channel(loop, _socket.Fd())<br \/>\n    {<br \/>\n        _channel.SetReadCallBack(std::bind(&amp;Accepter::HandleRead, this));<br \/>\n    }<br \/>\n    void SetAcceptCallBack(const AcceptCallBack &amp;cb)<br \/>\n    {<br \/>\n        _accept_callback &#061; cb;<br \/>\n    }<br \/>\n     \/*\u4e0d\u80fd\u5c06\u542f\u52a8\u8bfb\u4e8b\u4ef6\u76d1\u63a7&#xff0c;\u653e\u5230\u6784\u9020\u51fd\u6570\u4e2d&#xff0c;\u5fc5\u987b\u5728\u8bbe\u7f6e\u56de\u8c03\u51fd\u6570\u540e&#xff0c;\u518d\u53bb\u542f\u52a8<br \/>\n        \u5426\u5219\u6709\u53ef\u80fd\u9020\u6210\u542f\u52a8\u76d1\u63a7\u540e&#xff0c;\u7acb\u5373\u6709\u4e8b\u4ef6&#xff0c;\u5904\u7406\u7684\u65f6\u5019&#xff0c;\u56de\u8c03\u51fd\u6570\u8fd8\u6ca1\u8bbe\u7f6e&#xff1a;\u65b0\u8fde\u63a5\u5f97\u4e0d\u5230\u5904\u7406&#xff0c;\u4e14\u8d44\u6e90\u6cc4\u6f0f*\/<br \/>\n    void Listen()<br \/>\n    {<br \/>\n        _channel.EnableRead();<br \/>\n    }<br \/>\n}; <\/p>\n<h4 style=\"background-color:transparent\">LoopThread\u6a21\u5757<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"577\" src=\"2025-04-180fmeogluzd0.png\" width=\"1200\" \/><\/p>\n<p>                    class LoopThread<br \/>\n{<br \/>\nprivate:<br \/>\n    \/\/ \u7528\u4e8e\u5b9e\u73b0\u83b7\u53d6Loop\u7684\u540c\u6b65,\u907f\u514d\u7ebf\u7a0b\u5df2\u7ecf\u88ab\u521b\u5efa\u4e86&#xff0c;\u4f46\u662fEventLoop\u6ca1\u6709\u88ab\u5b9e\u4f8b\u5316\u4e4b\u524d\u5c31\u88ab\u83b7\u53d6\u5bfc\u81f4\u7684\u95ee\u9898<br \/>\n    std::mutex _mutex;             \/\/ \u4e92\u65a5\u9501<br \/>\n    std::condition_variable _cond; \/\/ \u6761\u4ef6\u53d8\u91cf<br \/>\n    EventLoop *_loop;              \/\/ \u5b9e\u4f8b\u5bf9\u8c61\u9700\u8981\u5728\u7ebf\u7a0b\u5185\u518d\u5b9e\u4f8b\u5316<br \/>\n    std::thread _thread;           \/\/ EventLoop\u5bf9\u5e94\u7684\u7ebf\u7a0b<\/p>\n<p>private:<br \/>\n    \/\/ \u5b9e\u4f8b\u5316EventLoop\u5bf9\u8c61&#xff0c;\u5f00\u59cb\u8fd0\u884cEventLoop\u6a21\u5757\u7684\u529f\u80fd<br \/>\n    void ThreadEntry()<br \/>\n    {<br \/>\n        \/\/ \u5b9e\u4f8b\u5316\u5bf9\u8c61&#xff0c;\u5524\u9192\u6240\u6709\u88ab_cond.wait\u963b\u585e\u7684\u7ebf\u7a0b<br \/>\n        EventLoop loop;<br \/>\n        {<br \/>\n            std::unique_lock&lt;std::mutex&gt; lock(_mutex);<br \/>\n            _loop &#061; &amp;loop;<br \/>\n            _cond.notify_all();<br \/>\n        }<br \/>\n        loop.Start();<br \/>\n    }<\/p>\n<p>public:<br \/>\n    \/\/ \u521b\u5efa\u7ebf\u7a0b&#xff0c;\u8bbe\u5b9a\u7ebf\u7a0b\u5165\u53e3\u51fd\u6570<br \/>\n    LoopThread()<br \/>\n        : _loop(nullptr),<br \/>\n          _thread(std::thread(&amp;LoopThread::ThreadEntry, this))<br \/>\n    {<br \/>\n    }<br \/>\n    \/\/ \u83b7\u53d6EventLoop<br \/>\n    EventLoop *GetLoop()<br \/>\n    {<br \/>\n        \/\/ \u7b49\u5f85_loop\u4e0d\u4e3a\u7a7a&#xff0c;\u4e5f\u5c31\u662f\u7ebf\u7a0b\u5df2\u7ecf\u88ab\u521b\u5efa\u5e76\u4e14EventLoop\u5bf9\u8c61\u5df2\u7ecf\u5b9e\u4f8b\u5316<br \/>\n        \/\/ \u4f8b\u5982\u4e3bReactor\u7ebf\u7a0b\u5728\u521b\u5efa\u4e86LoopThread\u4e4b\u540e\u5c31\u7acb\u523b\u83b7\u53d6EventLoop\u5bf9\u8c61&#xff0c;\u8fd9\u65f6\u5019\u5bf9\u8c61\u8fd8\u6ca1\u6709\u5b9e\u4f8b\u5316\u5c31\u4f1a\u5bfc\u81f4\u95ee\u9898<br \/>\n        EventLoop *loop &#061; nullptr;<br \/>\n        {<br \/>\n            std::unique_lock&lt;std::mutex&gt; lock(_mutex);<br \/>\n            _cond.wait(lock, [&amp;](){ return _loop !&#061; nullptr; });<br \/>\n            loop &#061; _loop;<br \/>\n        }<\/p>\n<p>        return loop;<br \/>\n    }<br \/>\n}; <\/p>\n<p>\u7ed3\u5408\u4e0a\u8ff0\u7684\u5206\u6790\u6240\u4ee5\u6211\u4eec\u8981\u6784\u9020\u4e00\u4e2a\u65b0\u6a21\u5757<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"280\" src=\"2025-04-18ofetygfjmui.png\" width=\"697\" \/><\/p>\n<h4 style=\"background-color:transparent\">LoopThreadPool\u6a21\u5757<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"525\" src=\"2025-04-18nfsj4fqkxbe.png\" width=\"1200\" \/><\/p>\n<p>                    \/\/ \u7ebf\u7a0b\u6c60&#xff0c;\u7528\u4e8e\u5206\u53d1\u4efb\u52a1\u5230\u4e0d\u540c\u7684IO\u7ebf\u7a0b<br \/>\n\/\/ baseloop\u662f\u4e3bReactor\u6240\u5728\u7684\u7ebf\u7a0b\u7684EventLoop\u5bf9\u8c61&#xff0c;\u7528\u4e8e\u5206\u53d1\u5230\u5176\u4ed6IO\u7ebf\u7a0b<br \/>\n\/\/ _threads\u662f\u6240\u6709\u4eceReactor\u7ebf\u7a0b\u7684LoopThread\u5bf9\u8c61<br \/>\n\/\/ _loops\u662f\u6240\u6709\u4eceReactor\u7ebf\u7a0b\u7684EventLoop\u5bf9\u8c61<br \/>\nclass LoopThreadPool<br \/>\n{<br \/>\nprivate:<br \/>\n    int _thread_count;<br \/>\n    int _next_idx;<br \/>\n    EventLoop *_baseloop;<br \/>\n    std::vector&lt;LoopThread *&gt; _threads;<br \/>\n    std::vector&lt;EventLoop *&gt; _loops;<\/p>\n<p>public:<br \/>\n    LoopThreadPool(EventLoop *baseloop)<br \/>\n        : _thread_count(0),<br \/>\n          _next_idx(0),<br \/>\n          _baseloop(baseloop)<br \/>\n    {<br \/>\n    }<br \/>\n    void SetThreadCount(int count)<br \/>\n    {<br \/>\n        _thread_count &#061; count;<br \/>\n    }<br \/>\n    void Create()<br \/>\n    {<br \/>\n        if (_thread_count &gt; 0)<br \/>\n        {<br \/>\n            _threads.resize(_thread_count);<br \/>\n            _loops.resize(_thread_count);<br \/>\n            for (int i &#061; 0; i &lt; _thread_count; i&#043;&#043;)<br \/>\n            {<br \/>\n                _threads[i] &#061; new LoopThread();<br \/>\n                _loops[i] &#061; _threads[i]-&gt;GetLoop();<br \/>\n            }<br \/>\n        }<br \/>\n    }<br \/>\n    \/\/\u91c7\u7528\u516c\u5e73\u8f6e\u8f6c\u5206\u914d(RR\u8f6e\u8f6c)<br \/>\n    EventLoop *NextLoop()<br \/>\n    {<br \/>\n        if (_thread_count &#061;&#061; 0)<br \/>\n        {<br \/>\n            return _baseloop;<br \/>\n        }<br \/>\n        _next_idx &#061; (_next_idx &#043; 1) % _thread_count;<br \/>\n        return _loops[_next_idx];<br \/>\n    }<br \/>\n}; <\/p>\n<h4 style=\"background-color:transparent\">TcpServer\u6a21\u5757<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"579\" src=\"2025-04-18obutb25h03v.png\" width=\"1200\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"423\" src=\"2025-04-18mezzgbzrebe.png\" width=\"1200\" \/><\/p>\n<p>                    class TcpServer<br \/>\n{<br \/>\n    using Functor &#061; std::function&lt;void()&gt;;<\/p>\n<p>private:<br \/>\n    uint64_t _next_id; \/\/ \u81ea\u589eid<br \/>\n    int _port;<br \/>\n    int _timeout;                                       \/\/ \u975e\u6d3b\u8dc3\u8fde\u63a5\u7684\u8d85\u65f6\u65f6\u95f4<br \/>\n    bool _Enable_Inactive_Release;                      \/\/ \u662f\u5426\u542f\u52a8\u975e\u6d3b\u8dc3\u6d88\u8017\u6807\u5fd7<br \/>\n    Accepter _accepter;                                 \/\/ \u76d1\u542c\u5957\u63a5\u5b57\u7684\u7ba1\u7406\u5bf9\u8c61<br \/>\n    EventLoop _baseloop;                                \/\/ \u4e3b\u7ebf\u7a0b\u7684EventLoop<br \/>\n    LoopThreadPool _pool;                               \/\/ \u4ece\u7ebf\u7a0bloop\u7684\u7ebf\u7a0b\u6c60<br \/>\n    std::unordered_map&lt;uint64_t, PtrConnection&gt; _coons; \/\/ \u4fdd\u5b58\u7ba1\u7406\u6240\u6709\u5bf9\u5e94\u8fde\u63a5\u7684shared_ptr\u5bf9\u8c61<\/p>\n<p>    using ConnectedCallBack &#061; std::function&lt;void(const PtrConnection &amp;)&gt;;<br \/>\n    using MessageCallBack &#061; std::function&lt;void(const PtrConnection &amp;, Buffer *)&gt;;<br \/>\n    using ClosedCallBack &#061; std::function&lt;void(const PtrConnection &amp;)&gt;;<br \/>\n    using AnyEventCallBack &#061; std::function&lt;void(const PtrConnection &amp;)&gt;;<br \/>\n    ConnectedCallBack _connected_callback;<br \/>\n    MessageCallBack _message_callback;<br \/>\n    ClosedCallBack _closed_callback;<br \/>\n    AnyEventCallBack _event_callback;<\/p>\n<p>private:<br \/>\n    \/\/ \u4e3a\u65b0\u8fde\u63a5\u6784\u5efa\u4e00\u4e2aConnection\u8fdb\u884c\u7ba1\u7406<br \/>\n    void NewConnection(int fd)<br \/>\n    {<br \/>\n        _next_id&#043;&#043;;<br \/>\n        PtrConnection coon(new Connection(_pool.NextLoop(), _next_id, fd));<br \/>\n        coon-&gt;SetMessageCallBack(_message_callback);<br \/>\n        coon-&gt;SetClosedCallBack(_closed_callback);<br \/>\n        coon-&gt;SetConnectedCallBack(_connected_callback);<br \/>\n        coon-&gt;SetAnyEventCallBack(_event_callback);<br \/>\n        coon-&gt;SetSrvClosedCallBack(std::bind(&amp;TcpServer::RemoveConnection, this, std::placeholders::_1));<br \/>\n        if (_Enable_Inactive_Release)<br \/>\n            coon-&gt;EnableInactiveRelease(_timeout);<br \/>\n        coon-&gt;Establish();<br \/>\n        _coons[_next_id] &#061; coon;<br \/>\n    }<br \/>\n    void RemoveConnectionInLoop(const PtrConnection &amp;coon)<br \/>\n    {<br \/>\n        int id &#061; coon-&gt;Id();<br \/>\n        auto it &#061; _coons.find(id);<br \/>\n        if (it !&#061; _coons.end())<br \/>\n        {<br \/>\n            _coons.erase(it);<br \/>\n        }<br \/>\n    }<br \/>\n    \/\/ \u4ece\u7ba1\u7406Connection\u7684_conns\u79cd\u79fb\u9664\u8fde\u63a5\u4fe1\u606f<br \/>\n    void RemoveConnection(const PtrConnection &amp;coon)<br \/>\n    {<br \/>\n        _baseloop.RunInLoop(std::bind(&amp;TcpServer::RemoveConnectionInLoop, this, coon));<br \/>\n    }<br \/>\n    void RunAfterInLoop(const Functor &amp;task, int delay)<br \/>\n    {<br \/>\n        _next_id&#043;&#043;;<br \/>\n        _baseloop.TimerAdd(_next_id, delay, task);<br \/>\n    }<\/p>\n<p>public:<br \/>\n    TcpServer(int port)<br \/>\n        : _port(port),<br \/>\n          _next_id(0),<br \/>\n          _Enable_Inactive_Release(false),<br \/>\n          _accepter(&amp;_baseloop, port),<br \/>\n          _pool(&amp;_baseloop)<br \/>\n    {<\/p>\n<p>        _accepter.SetAcceptCallBack(std::bind(&amp;TcpServer::NewConnection, this, std::placeholders::_1));<br \/>\n        _accepter.Listen(); \/\/ \u5c06\u76d1\u542c\u4e8b\u4ef6\u6302\u5230baseloop\u4e0a\u5f00\u59cb\u76d1\u63a7<br \/>\n    }<br \/>\n    void SetThreadCount(int count)<br \/>\n    {<br \/>\n        return _pool.SetThreadCount(count);<br \/>\n    }<br \/>\n    void SetConnectedCallBack(const ConnectedCallBack &amp;cb)<br \/>\n    {<br \/>\n        _connected_callback &#061; cb;<br \/>\n    }<br \/>\n    void SetMessageCallBack(const MessageCallBack &amp;cb)<br \/>\n    {<br \/>\n        _message_callback &#061; cb;<br \/>\n    }<br \/>\n    void SetClosedCallBack(const ClosedCallBack &amp;cb)<br \/>\n    {<br \/>\n        _closed_callback &#061; cb;<br \/>\n    }<br \/>\n    void SetAnyEventCallBack(const AnyEventCallBack &amp;cb)<br \/>\n    {<br \/>\n        _event_callback &#061; cb;<br \/>\n    }<br \/>\n    void EnableInactiveRelease(int timeout)<br \/>\n    {<br \/>\n        _timeout &#061; timeout;<br \/>\n        _Enable_Inactive_Release &#061; true;<br \/>\n    }<\/p>\n<p>    \/\/ \u7528\u4e8e\u6dfb\u52a0\u4e00\u4e2a\u5b9a\u65f6\u4efb\u52a1<br \/>\n    void RunAfter(const Functor &amp;task, int delay)<br \/>\n    {<br \/>\n        _baseloop.RunInLoop(std::bind(&amp;TcpServer::RunAfterInLoop, this, task, delay));<br \/>\n    }<br \/>\n    void Start()<br \/>\n    {<br \/>\n        _pool.Create(); \/\/ \u521b\u5efa\u4ece\u5c5e\u7ebf\u7a0b<br \/>\n        _baseloop.Start();<br \/>\n    }<br \/>\n}; <\/p>\n<h3>Http\u534f\u8bae\u6a21\u5757\u5b9e\u73b0<\/h3>\n<h4 style=\"background-color:transparent\">Util\u6a21\u5757<\/h4>\n<p>                    class Util<br \/>\n{<br \/>\npublic:<br \/>\n    \/\/ \u5b57\u7b26\u4e32\u5206\u5272\u51fd\u6570 \u5c06src\u6309\u7167sep\u8fdb\u884c\u5206\u5272&#xff0c;\u5c06\u7ed3\u679c\u653e\u5165array&#xff0c;\u8fd4\u56de\u5206\u5272\u4e4b\u540e\u7684\u5b57\u7b26\u4e32\u6570\u91cf<br \/>\n    static size_t Split(const std::string &amp;src, const std::string &amp;sep, std::vector&lt;std::string&gt; *array)<br \/>\n    {<br \/>\n        size_t offset &#061; 0;<br \/>\n        while (offset &lt; src.size())<br \/>\n        {<br \/>\n            \/\/ \u5728src\u504f\u79fb\u91cfoffset\u5904\u5411\u540e\u67e5\u627e\u5b57\u7b26sep&#xff0c;\u8fd4\u56de\u67e5\u5230\u7684\u4f4d\u7f6e<br \/>\n            size_t pos &#061; src.find(sep, offset);<br \/>\n            if (pos &#061;&#061; std::string::npos)<br \/>\n            {<br \/>\n                if (pos &#061;&#061; src.size())<br \/>\n                    break;<br \/>\n                array-&gt;push_back(src.substr(offset));<br \/>\n                return array-&gt;size();<br \/>\n            }<br \/>\n            if (pos &#061;&#061; offset)<br \/>\n            {<br \/>\n                offset &#061; pos &#043; sep.size();<br \/>\n                continue; \/\/ \u7a7a\u4e32\u4e0d\u6dfb\u52a0<br \/>\n            }<br \/>\n            array-&gt;push_back(src.substr(offset, pos &#8211; offset));<br \/>\n            offset &#061; pos &#043; sep.size();<br \/>\n        }<\/p>\n<p>        return array-&gt;size();<br \/>\n    }<br \/>\n    \/\/ \u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9<br \/>\n    static bool ReadFile(const std::string filename, std::string *buf)<br \/>\n    {<br \/>\n        std::ifstream ifs(filename, std::ios::binary);<br \/>\n        if (ifs.is_open() &#061;&#061; false)<br \/>\n        {<br \/>\n            ERR_LOG(&#034;FILE %s OPEN FAILED&#034;, filename.c_str());<br \/>\n            return false;<br \/>\n        }<br \/>\n        size_t fsize &#061; 0;<br \/>\n        ifs.seekg(0, ifs.end);<br \/>\n        fsize &#061; ifs.tellg(); \/\/ \u83b7\u53d6\u8bfb\u5199\u4f4d\u7f6e\u4e0e\u6587\u4ef6\u5f00\u5934\u7684\u504f\u79fb\u91cf&#xff0c;\u5c31\u662f\u6587\u4ef6\u5927\u5c0f<br \/>\n        ifs.seekg(0, ifs.beg);<br \/>\n        buf-&gt;resize(fsize);<br \/>\n        ifs.read(&amp;((*buf)[0]), fsize);<br \/>\n        if (ifs.good() &#061;&#061; false)<br \/>\n        {<br \/>\n            ERR_LOG(&#034;READ %s FILE FAILED&#034;, filename.c_str());<br \/>\n            ifs.close();<br \/>\n            return false;<br \/>\n        }<br \/>\n        ifs.close();<br \/>\n        return true;<br \/>\n    }<br \/>\n    \/\/ \u5199\u5165\u6587\u4ef6\u5185\u5bb9<br \/>\n    static bool WriteFile(const std::string &amp;filename, const std::string &amp;buf)<br \/>\n    {<br \/>\n        std::ofstream ofs(filename, std::ios::binary | std::ios::trunc);<br \/>\n        if (ofs.is_open() &#061;&#061; false)<br \/>\n        {<br \/>\n            ERR_LOG(&#034;FILE %s OPEN FAILED&#034;, filename.c_str());<br \/>\n            return false;<br \/>\n        }<br \/>\n        ofs.write(buf.c_str(), buf.size());<br \/>\n        if (ofs.good() &#061;&#061; false)<br \/>\n        {<br \/>\n            ERR_LOG(&#034;WRITE %s FILE FAILED&#034;, filename.c_str());<br \/>\n            ofs.close();<br \/>\n            return false;<br \/>\n        }<br \/>\n        ofs.close();<br \/>\n        return true;<br \/>\n    }<br \/>\n    \/\/ Url\u7f16\u7801 \u907f\u514dURL\u4e2d\u8d44\u6e90\u8def\u5f84\u4e0e\u67e5\u8be2\u5b57\u7b26\u4e32\u4e2d\u7684\u7279\u6b8a\u5b57\u7b26\u4e0ehttp\u8bf7\u6c42\u4e2d\u7684\u7279\u6b8a\u5b57\u7b26\u4ea7\u751f\u6b67\u4e49<br \/>\n    \/\/ RFC3986\u6587\u6863\u89c4\u5b9a&#xff0c;\u7f16\u7801\u683c\u5f0f\u4e3a%HH,\u5176\u4e2d\u4e5f\u89c4\u5b9a . &#8211; _ ~ \u6570\u5b57&#xff0c;\u5b57\u6bcd\u4e3a\u7edd\u5bf9\u4e0d\u7f16\u7801\u5b57\u7b26 \u5982C&#043;&#043; -&gt; C%2B%2B<br \/>\n    \/\/ W3C\u6587\u6863\u89c4\u5b9a&#xff0c;\u67e5\u8be2\u5b57\u7b26\u4e32\u4e2d\u7684\u7a7a\u683c&#xff0c;\u9700\u8981\u7f16\u7801\u4e3a&#043;&#xff0c;\u67e5\u8be2\u5219\u662f&#043;\u8f6c\u7a7a\u683c<\/p>\n<p>    static std::string UrlEncode(const std::string &amp;url, bool convert_space_to_plus)<br \/>\n    {<br \/>\n        std::string ret;<br \/>\n        for (auto c : url)<br \/>\n        {<br \/>\n            if (c &#061;&#061; &#039;.&#039; || c &#061;&#061; &#039;-&#039; || c &#061;&#061; &#039;_&#039; || c &#061;&#061; &#039;~&#039; || isalnum(c))<br \/>\n            {<br \/>\n                ret &#043;&#061; c;<br \/>\n                continue;<br \/>\n            }<br \/>\n            if (c &#061;&#061; &#039; &#039;)<br \/>\n            {<br \/>\n                if (convert_space_to_plus &#061;&#061; true)<br \/>\n                {<br \/>\n                    ret &#043;&#061; &#039;&#043;&#039;;<br \/>\n                    continue;<br \/>\n                }<br \/>\n                else<br \/>\n                {<br \/>\n                    ret &#043;&#061; &#039; &#039;;<br \/>\n                    continue;<br \/>\n                }<br \/>\n            }<br \/>\n            char tmp[4] &#061; {0};<br \/>\n            snprintf(tmp, 4, &#034;%%%02X&#034;, c);<br \/>\n            ret &#043;&#061; tmp;<br \/>\n        }<\/p>\n<p>        return ret;<br \/>\n    }<\/p>\n<p>    static char HEXTOI(char c)<br \/>\n    {<br \/>\n        if (c &gt;&#061; &#039;0&#039; &amp;&amp; c &lt;&#061; &#039;9&#039;)<br \/>\n        {<br \/>\n            return c &#8211; &#039;0&#039;;<br \/>\n        }<br \/>\n        if (c &gt;&#061; &#039;a&#039; &amp;&amp; c &lt;&#061; &#039;z&#039;)<br \/>\n        {<br \/>\n            return c &#8211; &#039;a&#039; &#043; 10;<br \/>\n        }<br \/>\n        if (c &gt;&#061; &#039;A&#039; &amp;&amp; c &lt;&#061; &#039;Z&#039;)<br \/>\n        {<br \/>\n            return c &#8211; &#039;A&#039; &#043; 10;<br \/>\n        }<br \/>\n        return -1;<br \/>\n    }<\/p>\n<p>    \/\/ Url\u89e3\u7801<br \/>\n    static std::string UrlDecode(const std::string &amp;url, bool convert_space_to_plus)<br \/>\n    {<br \/>\n        std::string ret;<br \/>\n        \/\/ \u9047\u5230\u767e\u5206\u53f7\u5c31\u5c06\u5176\u540e\u7684\u4e24\u4e2a\u5b57\u7b26\u91cd\u65b0\u8f6c\u5316\u4e3a\u6570\u5b57&#xff0c;\u7b2c\u4e00\u4e2a\u5b57\u7b26\u5411\u5de6\u79fb4\u4f4d&#043;\u7b2c\u4e8c\u4e2a\u5b57\u7b26<br \/>\n        for (int i &#061; 0; i &lt; url.size(); i&#043;&#043;)<br \/>\n        {<br \/>\n            if (url[i] &#061;&#061; &#039;&#043;&#039; &amp;&amp; convert_space_to_plus &#061;&#061; true)<br \/>\n            {<br \/>\n                ret &#043;&#061; &#039; &#039;;<br \/>\n                continue;<br \/>\n            }<br \/>\n            if (url[i] &#061;&#061; &#039;%&#039; &amp;&amp; i &#043; 2 &lt; url.size())<br \/>\n            {<br \/>\n                char val1 &#061; url[i &#043; 1];<br \/>\n                char val2 &#061; url[i &#043; 2];<\/p>\n<p>                char v &#061; (val1 &lt;&lt; 4) &#043; val2;<br \/>\n                ret &#043;&#061; v;<br \/>\n                i &#043;&#061; 2;<br \/>\n                continue;<br \/>\n            }<br \/>\n            ret &#043;&#061; url[i];<br \/>\n        }<\/p>\n<p>        return ret;<br \/>\n    }<br \/>\n    \/\/ \u54cd\u5e94\u72b6\u6001\u7801\u7684\u63cf\u8ff0\u4fe1\u606f\u83b7\u53d6<br \/>\n    static std::string StatuDesc(int statu)<br \/>\n    {<\/p>\n<p>        auto it &#061; stu_msg.find(statu);<br \/>\n        if (it &#061;&#061; stu_msg.end())<br \/>\n        {<br \/>\n            return &#034;UnKnow&#034;;<br \/>\n        }<\/p>\n<p>        return it-&gt;second;<br \/>\n    }<br \/>\n    \/\/ \u6839\u636e\u6587\u4ef6\u540e\u7f00\u540d\u83b7\u53d6mime<br \/>\n    \/**<br \/>\n     * &#064;brief \u6839\u636e\u6587\u4ef6\u540d\u83b7\u53d6\u6587\u4ef6\u7684MIME\u7c7b\u578b<br \/>\n     *<br \/>\n     * \u6839\u636e\u63d0\u4f9b\u7684\u6587\u4ef6\u540d&#xff0c;\u67e5\u627e\u5e76\u8fd4\u56de\u8be5\u6587\u4ef6\u5bf9\u5e94\u7684MIME\u7c7b\u578b\u3002<br \/>\n     *<br \/>\n     * &#064;param filename \u6587\u4ef6\u540d<br \/>\n     * &#064;return \u6587\u4ef6\u7684MIME\u7c7b\u578b&#xff0c;\u5982\u679c\u65e0\u6cd5\u786e\u5b9a\u5219\u8fd4\u56de &#034;application\/octet-stream&#034;<br \/>\n     *\/<br \/>\n    static std::string ExtMime(const std::string &amp;filename)<br \/>\n    {<\/p>\n<p>        size_t pos &#061; filename.find_last_of(&#039;.&#039;);<br \/>\n        if (pos &#061;&#061; std::string::npos)<br \/>\n        {<br \/>\n            return &#034;application\/ocet-stream&#034;;<br \/>\n        }<\/p>\n<p>        std::string ext &#061; filename.substr(pos);<br \/>\n        auto it &#061; mime_msg.find(ext);<br \/>\n        if (it &#061;&#061; mime_msg.end())<br \/>\n        {<br \/>\n            return &#034;application\/ocet-stream&#034;;<br \/>\n        }<\/p>\n<p>        return it-&gt;second;<br \/>\n    }<br \/>\n    \/\/ \u5224\u65ad\u4e00\u4e2a\u6587\u4ef6\u662f\u5426\u662f\u76ee\u5f55<br \/>\n    static bool IsDirectory(const std::string &amp;filename)<br \/>\n    {<br \/>\n        \/\/ \u5b9a\u4e49\u7ed3\u6784\u4f53stat\u53d8\u91cfst<br \/>\n        struct stat st;<\/p>\n<p>        \/\/ \u8c03\u7528stat\u51fd\u6570\u83b7\u53d6\u6587\u4ef6\u72b6\u6001\u4fe1\u606f&#xff0c;\u5c06\u7ed3\u679c\u5b58\u50a8\u5728st\u4e2d<br \/>\n        int ret &#061; stat(filename.c_str(), &amp;st);<\/p>\n<p>        \/\/ \u5982\u679cstat\u51fd\u6570\u8fd4\u56de\u5c0f\u4e8e0\u7684\u503c&#xff0c;\u8bf4\u660e\u83b7\u53d6\u6587\u4ef6\u72b6\u6001\u4fe1\u606f\u5931\u8d25<br \/>\n        if (ret &lt; 0)<br \/>\n        {<br \/>\n            \/\/ \u8fd4\u56defalse&#xff0c;\u8868\u793a\u8be5\u6587\u4ef6\u4e0d\u662f\u4e00\u4e2a\u76ee\u5f55<br \/>\n            return false;<br \/>\n        }<\/p>\n<p>        \/\/ \u8fd4\u56deS_ISDIR(st.st_mode)\u7684\u7ed3\u679c&#xff0c;\u5982\u679c\u6587\u4ef6\u662f\u4e00\u4e2a\u76ee\u5f55&#xff0c;\u5219\u8fd4\u56detrue&#xff0c;\u5426\u5219\u8fd4\u56defalse<br \/>\n        return S_ISDIR(st.st_mode);<br \/>\n    }<br \/>\n    \/\/ \u5224\u65ad\u4e00\u4e2a\u6587\u4ef6\u662f\u5426\u662f\u666e\u901a\u6587\u4ef6<br \/>\n    static bool IsRegular(const std::string &amp;filename)<br \/>\n    {<br \/>\n        struct stat st;<br \/>\n        int ret &#061; stat(filename.c_str(), &amp;st);<br \/>\n        if (ret &lt; 0)<br \/>\n        {<br \/>\n            return false;<br \/>\n        }<\/p>\n<p>        return S_ISREG(st.st_mode);<br \/>\n    }<br \/>\n    \/\/ \u5224\u65adhttp\u8bf7\u6c42\u7684\u8d44\u6e90\u8def\u5f84\u6709\u6548\u6027<br \/>\n    \/\/ \u9632\u6b62\u7528\u6237\u8bbf\u95ee\u5230\u76f8\u5bf9\u6839\u76ee\u5f55\u4e4b\u5916<br \/>\n    \/\/ \u4e3b\u8981\u601d\u8def\u662f\u63a7\u5236\u76ee\u5f55\u6df1\u5ea6<br \/>\n    static bool ValidPath(const std::string &amp;path)<br \/>\n    {<br \/>\n        int level &#061; 0;<br \/>\n        std::vector&lt;std::string&gt; subdir;<br \/>\n        Split(path, &#034;\/&#034;, &amp;subdir);<br \/>\n        for (auto dir : subdir)<br \/>\n        {<br \/>\n            if (dir &#061;&#061; &#034;..&#034;)<br \/>\n            {<br \/>\n                level&#8211;;<br \/>\n                if (level &lt; 0)<br \/>\n                {<br \/>\n                    return false;<br \/>\n                }<br \/>\n            }<br \/>\n            else<br \/>\n            {<br \/>\n                level&#043;&#043;;<br \/>\n            }<br \/>\n        }<\/p>\n<p>        return true;<br \/>\n    }<br \/>\n};<\/p>\n<p>class HttpRequest<br \/>\n{<br \/>\npublic:<br \/>\n    std::string _method;                                   \/\/ \u8bf7\u6c42\u65b9\u6cd5<br \/>\n    std::string _path;                                     \/\/ \u8bf7\u6c42\u8def\u5f84<br \/>\n    std::string _version;                                  \/\/ \u534f\u8bae\u7248\u672c<br \/>\n    std::string _body;                                     \/\/ \u6b63\u6587<br \/>\n    std::smatch _matches;                                  \/\/ \u8d44\u6e90\u8def\u5f84\u7684\u6b63\u5219\u63d0\u53d6\u8def\u5f84<br \/>\n    std::unordered_map&lt;std::string, std::string&gt; _headers; \/\/ \u5934\u90e8\u5b57\u6bb5<br \/>\n    std::unordered_map&lt;std::string, std::string&gt; _params;  \/\/ \u67e5\u8be2\u5b57\u7b26\u4e32<br \/>\npublic:<br \/>\n    HttpRequest() : _version(&#034;HTTP\/1.1&#034;) {}<br \/>\n    void ReSet()<br \/>\n    {<br \/>\n        _method.clear();<br \/>\n        _path.clear();<br \/>\n        _version&#061;&#034;HTTP\/1.1&#034;;<br \/>\n        _body.clear();<br \/>\n        std::smatch tmp;<br \/>\n        _matches.swap(tmp);<br \/>\n        _headers.clear();<br \/>\n        _params.clear();<br \/>\n    }<br \/>\n    \/\/ \u63d2\u5165\u5934\u90e8\u5b57\u6bb5<br \/>\n    void SetHeader(const std::string &amp;key, const std::string &amp;val)<br \/>\n    {<br \/>\n        DBG_LOG(&#034;REQ SET HEADER KEY:%s,Val:%s&#034;,key.c_str(),val.c_str());<br \/>\n        _headers[key] &#061; val;<br \/>\n    }<br \/>\n    \/\/ \u5224\u65ad\u662f\u5426\u6709\u5934\u90e8\u5b57\u6bb5<br \/>\n    bool HasHeader(const std::string &amp;key) const<br \/>\n    {<br \/>\n        auto it &#061; _headers.find(key);<br \/>\n        if (it &#061;&#061; _headers.end())<br \/>\n        {<br \/>\n            return false;<br \/>\n        }<\/p>\n<p>        return true;<br \/>\n    }<br \/>\n    \/\/ \u83b7\u53d6\u5934\u90e8\u5b57\u6bb5<br \/>\n    std::string GetHeader(const std::string &amp;key) const<br \/>\n    {<br \/>\n        auto it &#061; _headers.find(key.c_str());<br \/>\n        if (it &#061;&#061; _headers.end())<br \/>\n        {<br \/>\n            DBG_LOG(&#034;NOT FIND:%s&#034;,key.c_str());<br \/>\n            return &#034;&#034;;<br \/>\n        }<\/p>\n<p>        return it-&gt;second;<br \/>\n    }<br \/>\n    \/\/ \u63d2\u5165\u67e5\u8be2\u5b57\u7b26\u4e32<br \/>\n    void SetParam(const std::string &amp;key, const std::string &amp;val)<br \/>\n    {<br \/>\n        _params[key] &#061; val;<br \/>\n    }<br \/>\n    \/\/ \u5224\u65ad\u662f\u5426\u6709\u67d0\u4e2a\u67e5\u8be2\u5b57\u7b26\u4e32<br \/>\n    bool HasParam(const std::string &amp;key)<br \/>\n    {<br \/>\n        auto it &#061; _params.find(key);<br \/>\n        if (it &#061;&#061; _params.end())<br \/>\n        {<br \/>\n            return false;<br \/>\n        }<\/p>\n<p>        return true;<br \/>\n    }<br \/>\n    \/\/ \u83b7\u53d6\u6307\u5b9a\u67e5\u8be2\u5b57\u7b26\u4e32<br \/>\n    std::string GetParam(const std::string &amp;key)<br \/>\n    {<br \/>\n        auto it &#061; _params.find(key);<br \/>\n        if (it &#061;&#061; _params.end())<br \/>\n        {<br \/>\n            return &#034;&#034;;<br \/>\n        }<\/p>\n<p>        return it-&gt;second;<br \/>\n    }<br \/>\n    \/\/ \u83b7\u53d6\u6b63\u6587\u957f\u5ea6<br \/>\n    size_t ContentLenth()<br \/>\n    {<br \/>\n        bool ret &#061; HasHeader(&#034;Content-Length&#034;);<br \/>\n        if (ret &#061;&#061; false)<br \/>\n        {<br \/>\n            return 0;<br \/>\n        }<\/p>\n<p>        std::string len &#061; GetHeader(&#034;Content-Length&#034;);<br \/>\n        return std::stol(len);<br \/>\n    }<br \/>\n    \/\/ \u5224\u65ad\u662f\u5426\u662f\u77ed\u8fde\u63a5<br \/>\n    bool Close () const<br \/>\n    {<br \/>\n        \/\/ \u6ca1\u6709Connection \u6216\u8005Connection\u7684\u503c\u4e3afalse\u90fd\u662f\u77ed\u8fde\u63a5<br \/>\n        if (HasHeader(&#034;Connection&#034;) &#061;&#061; true &amp;&amp; GetHeader(&#034;Connection&#034;) &#061;&#061; &#034;keep-alive&#034;)<br \/>\n        {<br \/>\n            DBG_LOG(&#034;CLOSE RETURN FALSE&#034;);<br \/>\n            return false;<br \/>\n        }<br \/>\n        return true;<br \/>\n    }<br \/>\n}; <\/p>\n<h4 style=\"background-color:transparent\">HttpResquest\u6a21\u5757<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"741\" src=\"2025-04-18pq1f3czunlp.png\" width=\"1200\" \/><\/p>\n<p>                    class HttpRequest<br \/>\n{<br \/>\npublic:<br \/>\n    std::string _method;                                   \/\/ \u8bf7\u6c42\u65b9\u6cd5<br \/>\n    std::string _path;                                     \/\/ \u8bf7\u6c42\u8def\u5f84<br \/>\n    std::string _version;                                  \/\/ \u534f\u8bae\u7248\u672c<br \/>\n    std::string _body;                                     \/\/ \u6b63\u6587<br \/>\n    std::smatch _matches;                                  \/\/ \u8d44\u6e90\u8def\u5f84\u7684\u6b63\u5219\u63d0\u53d6\u8def\u5f84<br \/>\n    std::unordered_map&lt;std::string, std::string&gt; _headers; \/\/ \u5934\u90e8\u5b57\u6bb5<br \/>\n    std::unordered_map&lt;std::string, std::string&gt; _params;  \/\/ \u67e5\u8be2\u5b57\u7b26\u4e32<br \/>\npublic:<br \/>\n    HttpRequest() : _version(&#034;HTTP\/1.1&#034;) {}<br \/>\n    void ReSet()<br \/>\n    {<br \/>\n        _method.clear();<br \/>\n        _path.clear();<br \/>\n        _version&#061;&#034;HTTP\/1.1&#034;;<br \/>\n        _body.clear();<br \/>\n        std::smatch tmp;<br \/>\n        _matches.swap(tmp);<br \/>\n        _headers.clear();<br \/>\n        _params.clear();<br \/>\n    }<br \/>\n    \/\/ \u63d2\u5165\u5934\u90e8\u5b57\u6bb5<br \/>\n    void SetHeader(const std::string &amp;key, const std::string &amp;val)<br \/>\n    {<br \/>\n        DBG_LOG(&#034;REQ SET HEADER KEY:%s,Val:%s&#034;,key.c_str(),val.c_str());<br \/>\n        _headers[key] &#061; val;<br \/>\n    }<br \/>\n    \/\/ \u5224\u65ad\u662f\u5426\u6709\u5934\u90e8\u5b57\u6bb5<br \/>\n    bool HasHeader(const std::string &amp;key) const<br \/>\n    {<br \/>\n        auto it &#061; _headers.find(key);<br \/>\n        if (it &#061;&#061; _headers.end())<br \/>\n        {<br \/>\n            return false;<br \/>\n        }<\/p>\n<p>        return true;<br \/>\n    }<br \/>\n    \/\/ \u83b7\u53d6\u5934\u90e8\u5b57\u6bb5<br \/>\n    std::string GetHeader(const std::string &amp;key) const<br \/>\n    {<br \/>\n        auto it &#061; _headers.find(key.c_str());<br \/>\n        if (it &#061;&#061; _headers.end())<br \/>\n        {<br \/>\n            DBG_LOG(&#034;NOT FIND:%s&#034;,key.c_str());<br \/>\n            return &#034;&#034;;<br \/>\n        }<\/p>\n<p>        return it-&gt;second;<br \/>\n    }<br \/>\n    \/\/ \u63d2\u5165\u67e5\u8be2\u5b57\u7b26\u4e32<br \/>\n    void SetParam(const std::string &amp;key, const std::string &amp;val)<br \/>\n    {<br \/>\n        _params[key] &#061; val;<br \/>\n    }<br \/>\n    \/\/ \u5224\u65ad\u662f\u5426\u6709\u67d0\u4e2a\u67e5\u8be2\u5b57\u7b26\u4e32<br \/>\n    bool HasParam(const std::string &amp;key)<br \/>\n    {<br \/>\n        auto it &#061; _params.find(key);<br \/>\n        if (it &#061;&#061; _params.end())<br \/>\n        {<br \/>\n            return false;<br \/>\n        }<\/p>\n<p>        return true;<br \/>\n    }<br \/>\n    \/\/ \u83b7\u53d6\u6307\u5b9a\u67e5\u8be2\u5b57\u7b26\u4e32<br \/>\n    std::string GetParam(const std::string &amp;key)<br \/>\n    {<br \/>\n        auto it &#061; _params.find(key);<br \/>\n        if (it &#061;&#061; _params.end())<br \/>\n        {<br \/>\n            return &#034;&#034;;<br \/>\n        }<\/p>\n<p>        return it-&gt;second;<br \/>\n    }<br \/>\n    \/\/ \u83b7\u53d6\u6b63\u6587\u957f\u5ea6<br \/>\n    size_t ContentLenth()<br \/>\n    {<br \/>\n        bool ret &#061; HasHeader(&#034;Content-Length&#034;);<br \/>\n        if (ret &#061;&#061; false)<br \/>\n        {<br \/>\n            return 0;<br \/>\n        }<\/p>\n<p>        std::string len &#061; GetHeader(&#034;Content-Length&#034;);<br \/>\n        return std::stol(len);<br \/>\n    }<br \/>\n    \/\/ \u5224\u65ad\u662f\u5426\u662f\u77ed\u8fde\u63a5<br \/>\n    bool Close () const<br \/>\n    {<br \/>\n        \/\/ \u6ca1\u6709Connection \u6216\u8005Connection\u7684\u503c\u4e3afalse\u90fd\u662f\u77ed\u8fde\u63a5<br \/>\n        if (HasHeader(&#034;Connection&#034;) &#061;&#061; true &amp;&amp; GetHeader(&#034;Connection&#034;) &#061;&#061; &#034;keep-alive&#034;)<br \/>\n        {<br \/>\n            DBG_LOG(&#034;CLOSE RETURN FALSE&#034;);<br \/>\n            return false;<br \/>\n        }<br \/>\n        return true;<br \/>\n    }<br \/>\n}; <\/p>\n<h4 style=\"background-color:transparent\">HttpResponse\u6a21\u5757<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"612\" src=\"2025-04-18avluyn4f4yo.png\" width=\"745\" \/><\/p>\n<p>                    class HttpResponse<br \/>\n{<br \/>\npublic:<br \/>\n    int _statu;<br \/>\n    bool _redirect;<br \/>\n    std::string _body;<br \/>\n    std::string _redirect_url;<br \/>\n    std::unordered_map&lt;std::string, std::string&gt; _headers;<\/p>\n<p>public:<br \/>\n    HttpResponse()<br \/>\n        : _statu(200),<br \/>\n          _redirect(false)<br \/>\n    {<br \/>\n    }<br \/>\n    HttpResponse(int statu)<br \/>\n        : _statu(statu),<br \/>\n          _redirect(false)<br \/>\n    {<br \/>\n    }<br \/>\n    void ReSet()<br \/>\n    {<br \/>\n        _statu &#061; 200;<br \/>\n        _redirect &#061; false;<br \/>\n        _body.clear();<br \/>\n        _redirect_url.clear();<br \/>\n        _headers.clear();<br \/>\n    }<br \/>\n    void SetHeader(const std::string &amp;key, const std::string &amp;val)<br \/>\n    {<br \/>\n        DBG_LOG(&#034;RES SET HEADER KEY:%s,Val:%s&#034;,key.c_str(),val.c_str());<br \/>\n        _headers[key] &#061; val;<br \/>\n    }<br \/>\n    bool HasHeader(const std::string &amp;key)<br \/>\n    {<br \/>\n        auto it &#061; _headers.find(key);<br \/>\n        if (it &#061;&#061; _headers.end())<br \/>\n        {<br \/>\n            return false;<br \/>\n        }<\/p>\n<p>        return true;<br \/>\n    }<br \/>\n    \/\/ \u83b7\u53d6\u6307\u5b9a\u62a5\u5934<br \/>\n    std::string GetHeader(const std::string &amp;key)<br \/>\n    {<br \/>\n        auto it &#061; _headers.find(key);<br \/>\n        if (it &#061;&#061; _headers.end())<br \/>\n        {<br \/>\n            return &#034;&#034;;<br \/>\n        }<\/p>\n<p>        return it-&gt;second;<br \/>\n    }<br \/>\n    \/\/ \u8bbe\u7f6e\u7c7b\u578b<br \/>\n    void SetContent(const std::string &amp;body, const std::string &amp;type)<br \/>\n    {<br \/>\n        _body &#061; body;<br \/>\n        SetHeader(&#034;Content-Type&#034;, type);<br \/>\n    }<br \/>\n    \/\/ \u8bbe\u7f6e\u91cd\u5b9a\u5411<br \/>\n    void SetRedirect(const std::string &amp;url, int statu &#061; 302)<br \/>\n    {<br \/>\n        _statu &#061; statu;<br \/>\n        _redirect &#061; true;<br \/>\n        _redirect_url &#061; url;<br \/>\n    }<br \/>\n    \/\/ \u5224\u65ad\u662f\u5426\u4e3a\u77ed\u8fde\u63a5<br \/>\n    bool Close()<br \/>\n    {<br \/>\n        DBG_LOG(&#034;JUDGE CLOSE&#034;);<br \/>\n        \/\/ \u6ca1\u6709Connection \u6216\u8005Connection\u7684\u503c\u4e3afalse\u90fd\u662f\u77ed\u8fde\u63a5<br \/>\n        if (HasHeader(&#034;Connection&#034;) &#061;&#061; true &amp;&amp; GetHeader(&#034;Connection&#034;) &#061;&#061; &#034;keep-alive&#034;)<br \/>\n        {<br \/>\n            return false;\/\/\u957f\u8fde\u63a5<br \/>\n        }<br \/>\n        DBG_LOG(&#034;TRUE:%s&#034;,GetHeader(&#034;Connection&#034;).c_str());<br \/>\n        return true;<br \/>\n        \/\/\u77ed\u8fde\u63a5<br \/>\n    }<br \/>\n}; <\/p>\n<h4>HttpContext\u6a21\u5757<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"274\" src=\"2025-04-18icgiqo5zhip.png\" width=\"954\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"831\" src=\"2025-04-18dq1plhbb41g.png\" width=\"1062\" \/><\/p>\n<h4><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"276\" src=\"2025-04-18r0fox0flsin.png\" width=\"681\" \/><\/h4>\n<p>                    typedef enum<br \/>\n{<br \/>\n    RECV_HTTP_ERROR,<br \/>\n    RECV_HTTP_LINE,<br \/>\n    RECV_HTTP_HEAD,<br \/>\n    RECV_HTTP_BODY,<br \/>\n    RECV_HTTP_OVER<br \/>\n} HttpRecvStatu;<\/p>\n<p>#define MAX_LINE 8 * 1024<br \/>\nclass HttpContext<br \/>\n{<br \/>\nprivate:<br \/>\n    int _resp_statu;           \/\/ \u54cd\u5e94\u72b6\u6001\u7801<br \/>\n    HttpRecvStatu _recv_statu; \/\/ \u63a5\u6536\u53ca\u89e3\u6790\u7684\u72b6\u6001<br \/>\n    HttpRequest _request;      \/\/ \u5df2\u7ecf\u89e3\u6790\u5230\u7684\u8bf7\u6c42\u4fe1\u606f<br \/>\nprivate:<br \/>\n    \/\/ \u9996\u884c\u63a5\u6536<br \/>\n    bool RecvHttpLine(Buffer *buf)<br \/>\n    {<br \/>\n        DBG_LOG(&#034;RecvHttpLine&#034;);<br \/>\n        if (_recv_statu !&#061; RECV_HTTP_LINE) return false;<br \/>\n            \/\/1. \u83b7\u53d6\u4e00\u884c\u6570\u636e&#xff0c;\u5e26\u6709\u672b\u5c3e\u7684\u6362\u884c<br \/>\n            std::string line &#061; buf-&gt;GetLineAndPop();<br \/>\n            \/\/2. \u9700\u8981\u8003\u8651\u7684\u4e00\u4e9b\u8981\u7d20&#xff1a;\u7f13\u51b2\u533a\u4e2d\u7684\u6570\u636e\u4e0d\u8db3\u4e00\u884c&#xff0c; \u83b7\u53d6\u7684\u4e00\u884c\u6570\u636e\u8d85\u5927<br \/>\n            if (line.size() &#061;&#061; 0) {<br \/>\n                \/\/\u7f13\u51b2\u533a\u4e2d\u7684\u6570\u636e\u4e0d\u8db3\u4e00\u884c&#xff0c;\u5219\u9700\u8981\u5224\u65ad\u7f13\u51b2\u533a\u7684\u53ef\u8bfb\u6570\u636e\u957f\u5ea6&#xff0c;\u5982\u679c\u5f88\u957f\u4e86\u90fd\u4e0d\u8db3\u4e00\u884c&#xff0c;\u8fd9\u662f\u6709\u95ee\u9898\u7684<br \/>\n                if (buf-&gt;ReadAbleSize() &gt; MAX_LINE) {<br \/>\n                    _recv_statu &#061; RECV_HTTP_ERROR;<br \/>\n                    _resp_statu &#061; 414;\/\/URI TOO LONG<br \/>\n                    return false;<br \/>\n                }<br \/>\n                \/\/\u7f13\u51b2\u533a\u4e2d\u6570\u636e\u4e0d\u8db3\u4e00\u884c&#xff0c;\u4f46\u662f\u4e5f\u4e0d\u591a&#xff0c;\u5c31\u7b49\u7b49\u65b0\u6570\u636e\u7684\u5230\u6765<br \/>\n                return true;<br \/>\n            }<\/p>\n<p>            if (line.size() &gt; MAX_LINE) {<br \/>\n                _recv_statu &#061; RECV_HTTP_ERROR;<br \/>\n                _resp_statu &#061; 414;\/\/URI TOO LONG<br \/>\n                return false;<br \/>\n            }<\/p>\n<p>            bool ret &#061; ParseHttpLine(line);<\/p>\n<p>            if (ret &#061;&#061; false) {<br \/>\n                return false;<br \/>\n            }<br \/>\n            \/\/\u9996\u884c\u5904\u7406\u5b8c\u6bd5&#xff0c;\u8fdb\u5165\u5934\u90e8\u83b7\u53d6\u9636\u6bb5<br \/>\n            _recv_statu &#061; RECV_HTTP_HEAD;<br \/>\n            return true;<br \/>\n    }<br \/>\n    \/\/ \u9996\u884c\u89e3\u6790<br \/>\n    bool ParseHttpLine(const std::string &amp;line)<br \/>\n    {<br \/>\n        DBG_LOG(&#034;ParseHttpLine 1 %s&#034;,line.c_str());<br \/>\n        std::smatch matches;<\/p>\n<p>        std::regex e(&#034;(GET|HEAD|POST|PUT|DELETE) ([^?]*)(?:\\\\\\\\?(.*))? (HTTP\/1\\\\\\\\.[01])(?:\\\\n|\\\\r\\\\n)?&#034;, std::regex::icase);<\/p>\n<p>        ERR_LOG(&#034;LINE&#061;%s&#034;,line.c_str());<br \/>\n        bool ret &#061; std::regex_match(line, matches, e);<\/p>\n<p>        if (ret &#061;&#061; false)<br \/>\n        {<br \/>\n            _recv_statu &#061; RECV_HTTP_ERROR;<br \/>\n            _resp_statu &#061; 400; \/\/ BAD REQUEST<br \/>\n            return false;<br \/>\n        }<br \/>\n        \/\/ 0 : GET \/juhuo\/login?user&#061;xiaoming&amp;pass&#061;123123 HTTP\/1.1<br \/>\n        \/\/ 1 : GET<br \/>\n        \/\/ 2 : \/juhuo\/login<br \/>\n        \/\/ 3 : user&#061;xiaoming&amp;pass&#061;123123<br \/>\n        \/\/ 4 : HTTP\/1.1<br \/>\n        \/\/ \u8bf7\u6c42\u65b9\u6cd5\u7684\u83b7\u53d6<\/p>\n<p>        _request._method &#061; matches[1];<br \/>\n        std::transform(_request._method.begin(), _request._method.end(), _request._method.begin(), ::toupper);<br \/>\n        \/\/ \u8d44\u6e90\u8def\u5f84\u7684\u83b7\u53d6&#xff0c;\u9700\u8981\u8fdb\u884cURL\u89e3\u7801\u64cd\u4f5c&#xff0c;\u4f46\u662f\u4e0d\u9700\u8981&#043;\u8f6c\u7a7a\u683c<br \/>\n        _request._path &#061; Util::UrlDecode(matches[2], false);<br \/>\n        \/\/ \u534f\u8bae\u7248\u672c\u7684\u83b7\u53d6<br \/>\n        _request._version &#061; matches[4];<br \/>\n        \/\/ \u67e5\u8be2\u5b57\u7b26\u4e32\u7684\u83b7\u53d6\u4e0e\u5904\u7406<br \/>\n        std::vector&lt;std::string&gt; query_string_arry;<br \/>\n        std::string query_string &#061; matches[3];<br \/>\n        \/\/ \u67e5\u8be2\u5b57\u7b26\u4e32\u7684\u683c\u5f0f key&#061;val&amp;key&#061;val&#8230;.., \u5148\u4ee5 &amp; \u7b26\u53f7\u8fdb\u884c\u5206\u5272&#xff0c;\u5f97\u5230\u5404\u4e2a\u5b57\u4e32<br \/>\n        Util::Split(query_string, &#034;&amp;&#034;, &amp;query_string_arry);<br \/>\n        \/\/ \u9488\u5bf9\u5404\u4e2a\u5b57\u4e32&#xff0c;\u4ee5 &#061; \u7b26\u53f7\u8fdb\u884c\u5206\u5272&#xff0c;\u5f97\u5230key \u548cval&#xff0c; \u5f97\u5230\u4e4b\u540e\u4e5f\u9700\u8981\u8fdb\u884cURL\u89e3\u7801<br \/>\n        for (auto &amp;str : query_string_arry)<br \/>\n        {<br \/>\n            size_t pos &#061; str.find(&#034;&#061;&#034;);<br \/>\n            if (pos &#061;&#061; std::string::npos)<br \/>\n            {<br \/>\n                _recv_statu &#061; RECV_HTTP_ERROR;<br \/>\n                _resp_statu &#061; 400; \/\/ BAD REQUEST<br \/>\n                return false;<br \/>\n            }<br \/>\n            std::string key &#061; Util::UrlDecode(str.substr(0, pos), true);<br \/>\n            std::string val &#061; Util::UrlDecode(str.substr(pos &#043; 1), true);<br \/>\n            _request.SetParam(key, val);<br \/>\n        }<br \/>\n        DBG_LOG(&#034;ParseHttpLine 4&#034;);<br \/>\n        return true;<br \/>\n    }<br \/>\n    \/\/ \u89e3\u6790\u62a5\u5934<br \/>\n    bool RecvHttpHead(Buffer *buf)<br \/>\n    {<br \/>\n        if (_recv_statu !&#061; RECV_HTTP_HEAD)<br \/>\n        \/\/if (_recv_statu !&#061; RECV_HTTP_LINE)<br \/>\n            return false;<br \/>\n        \/\/ \u4e00\u884c\u4e00\u884c\u89e3\u6790\u6570\u636e&#xff0c;\u9047\u5230\u7a7a\u884c\u7ed3\u675f<br \/>\n        while (1)<br \/>\n        {<br \/>\n            std::string line &#061; buf-&gt;GetLineAndPop();<br \/>\n            if (line.size() &#061;&#061; 0)<br \/>\n            {<br \/>\n                \/\/ \u5982\u679c\u7f13\u51b2\u533a\u6570\u636e\u4e0d\u8db3\u4e00\u884c&#xff0c;\u4e14\u7f13\u51b2\u533a\u6570\u636e\u8fc7\u5927&#xff0c;\u5219url\u53ef\u80fd\u5b58\u5728\u95ee\u9898<br \/>\n                if (buf-&gt;ReadAbleSize() &gt; MAX_LINE)<br \/>\n                {<br \/>\n                    _recv_statu &#061; RECV_HTTP_ERROR;<br \/>\n                    _resp_statu &#061; 414; \/\/ url too long<br \/>\n                    return false;<br \/>\n                }<br \/>\n                \/\/ \u6570\u636e\u4e0d\u8db3\u4e00\u884c&#xff0c;\u4f46\u662f\u6570\u636e\u4e0d\u591a\u5219\u8fd4\u56de\u7b49\u5f85\u65b0\u6570\u636e<br \/>\n                return true;<br \/>\n            }<br \/>\n            if (line.size() &gt; MAX_LINE)<br \/>\n            {<br \/>\n                _recv_statu &#061; RECV_HTTP_ERROR;<br \/>\n                _resp_statu &#061; 414; \/\/ url too long<br \/>\n                return false;<br \/>\n            }<br \/>\n            \/\/ \u89e3\u6790\u5b8c\u6bd5&#xff0c;\u7ed3\u675f\u89e3\u6790<br \/>\n            if (line &#061;&#061; &#034;\\\\n&#034; || line &#061;&#061; &#034;\\\\r\\\\n&#034;)<br \/>\n            {<br \/>\n                break;<br \/>\n            }<br \/>\n            bool ret &#061; ParseHttpHead(line);<br \/>\n            if (ret &#061; false)<br \/>\n            {<br \/>\n                return false;<br \/>\n            }<br \/>\n        }<br \/>\n        \/\/ \u5934\u90e8\u5904\u7406\u5b8c\u6bd5\u8fdb\u5165\u6b63\u6587\u9636\u6bb5<br \/>\n        _recv_statu &#061; RECV_HTTP_BODY;<br \/>\n        return true;<br \/>\n    }<br \/>\n    \/\/\u89e3\u6790\u62a5\u5934<br \/>\n    bool ParseHttpHead(std::string &amp;line)<br \/>\n    {<br \/>\n        if (line.back() &#061;&#061; &#039;\\\\n&#039;) line.pop_back();\/\/\u672b\u5c3e\u662f\u6362\u884c\u5219\u53bb\u6389\u6362\u884c\u5b57\u7b26<br \/>\n        if (line.back() &#061;&#061; &#039;\\\\r&#039;) line.pop_back();\/\/\u672b\u5c3e\u662f\u56de\u8f66\u5219\u53bb\u6389\u56de\u8f66\u5b57\u7b26<br \/>\n        size_t pos &#061; line.find(&#034;: &#034;);<br \/>\n        if (pos &#061;&#061; std::string::npos)<br \/>\n        {<br \/>\n            _recv_statu &#061; RECV_HTTP_ERROR;<br \/>\n            _resp_statu &#061; 400; \/\/ BAD REQUEST<br \/>\n            return false;<br \/>\n        }<br \/>\n        std::string key &#061; Util::UrlDecode(line.substr(0, pos), true);<br \/>\n        std::string val &#061; Util::UrlDecode(line.substr(pos &#043; 2), true);<br \/>\n        DBG_LOG(&#034;Parse Http Head:KEY:%s,Val:%s&#034;,key.c_str(),val.c_str());<br \/>\n        _request.SetHeader(key, val);<br \/>\n        return true;<br \/>\n    }<br \/>\n    bool RecvHttpBody(Buffer *buf)<br \/>\n    {<br \/>\n        if (_recv_statu !&#061; RECV_HTTP_BODY)<br \/>\n            return false;<br \/>\n        size_t content_length &#061; _request.ContentLenth();<br \/>\n        if (content_length &#061;&#061; 0)<br \/>\n        {<br \/>\n            \/\/ \u6ca1\u6709\u6b63\u6587\u5219\u8bf7\u6c42\u7ed3\u675f<br \/>\n            _recv_statu &#061; RECV_HTTP_OVER;<br \/>\n            return true;<br \/>\n        }<br \/>\n        \/\/ \u83b7\u53d6\u6b63\u6587\u957f\u5ea6<br \/>\n        \/\/ \u5f53\u524d\u5df2\u7ecf\u63a5\u6536\u591a\u5c11\u6b63\u6587<br \/>\n        size_t real_length &#061; content_length &#8211; _request._body.size(); \/\/ \u5b9e\u9645\u8fd8\u8981\u63a5\u6536\u7684\u6570\u636e\u957f\u5ea6<br \/>\n        \/\/ \u63a5\u6536\u6b63\u6587\u5230body\u4e2d&#xff0c;\u4e5f\u8981\u8003\u8651\u5f53\u524d\u7684\u7f13\u51b2\u533a\u6570\u636e\u662f\u5426\u662f\u4e00\u4e2a\u6b63\u6587<br \/>\n        \/\/ \u82e5\u6070\u597d\u5305\u542b\u5219\u76f4\u63a5\u63d0\u53d6<br \/>\n        if (buf-&gt;ReadAbleSize() &gt;&#061; real_length)<br \/>\n        {<br \/>\n            _request._body.append(buf-&gt;ReadPosition(), real_length);<br \/>\n            buf-&gt;MoveReadOffset(real_length);<br \/>\n            _recv_statu &#061; RECV_HTTP_OVER;<br \/>\n            return true;<br \/>\n        }<br \/>\n        \/\/ \u82e5\u4e0d\u8db3\u5219\u7b49\u5f85\u65b0\u6570\u636e<br \/>\n        _request._body.append(buf-&gt;ReadPosition(), buf-&gt;ReadAbleSize());<br \/>\n        buf-&gt;MoveReadOffset(buf-&gt;ReadAbleSize());<br \/>\n        return true;<br \/>\n    }<\/p>\n<p>public:<br \/>\n    HttpContext()<br \/>\n        : _resp_statu(200),<br \/>\n          _recv_statu(RECV_HTTP_LINE)<br \/>\n    {<br \/>\n    }<br \/>\n    void ReSet()<br \/>\n    {<br \/>\n        _resp_statu &#061; 200;<br \/>\n        _recv_statu &#061; RECV_HTTP_LINE;<br \/>\n        _request.ReSet();<br \/>\n    }<br \/>\n    int ResponseStatu()<br \/>\n    {<br \/>\n        return _resp_statu;<br \/>\n    }<br \/>\n    HttpRecvStatu RecvStatu()<br \/>\n    {<br \/>\n        return _recv_statu;<br \/>\n    }<br \/>\n    HttpRequest &amp;Request()<br \/>\n    {<br \/>\n        return _request;<br \/>\n    }<br \/>\n    void RecvHttpRequest(Buffer *buf)<br \/>\n    {<br \/>\n        DBG_LOG(&#034;RecvHttpRequest&#034;);<br \/>\n        switch (_recv_statu)<br \/>\n        {<br \/>\n        \/\/ \u6b64\u5904\u4e0d\u9700\u8981break,\u672c\u8eab\u5c31\u9700\u8981\u6309\u7167line,head,body\u4f9d\u6b21\u63a5\u6536\u89e3\u6790&#xff01;<br \/>\n        case RECV_HTTP_LINE:<br \/>\n            RecvHttpLine(buf);<br \/>\n        case RECV_HTTP_HEAD:<br \/>\n            DBG_LOG(&#034;RECV_HTTP_HEAD&#034;);<br \/>\n            RecvHttpHead(buf);<br \/>\n        case RECV_HTTP_BODY:<br \/>\n            RecvHttpBody(buf);<br \/>\n        }<br \/>\n    }<br \/>\n}; <\/p>\n<h4 style=\"background-color:transparent\"> HttpServer\u6a21\u5757<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"657\" src=\"2025-04-184zg2pd2qkh0.png\" width=\"1200\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"105\" src=\"2025-04-18u3e4mnnarn4.png\" width=\"1200\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"385\" src=\"2025-04-18slm5qpa2g5a.png\" width=\"1200\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"535\" src=\"2025-04-18bcfxy2odxci.png\" width=\"1200\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"619\" src=\"2025-04-18rnnd3czohqd.png\" width=\"730\" \/><\/p>\n<p>                    class HttpServer {<br \/>\n    private:<br \/>\n        using Handler &#061; std::function&lt;void(const HttpRequest &amp;, HttpResponse *)&gt;;<br \/>\n        using Handlers &#061; std::vector&lt;std::pair&lt;std::regex, Handler&gt;&gt;;<br \/>\n        Handlers _get_route;<br \/>\n        Handlers _post_route;<br \/>\n        Handlers _put_route;<br \/>\n        Handlers _delete_route;<br \/>\n        std::string _basedir; \/\/\u9759\u6001\u8d44\u6e90\u6839\u76ee\u5f55<br \/>\n        TcpServer _server;<br \/>\n    private:<br \/>\n        void ErrorHandler(const HttpRequest &amp;req, HttpResponse *rsp) {<br \/>\n            \/\/1. \u7ec4\u7ec7\u4e00\u4e2a\u9519\u8bef\u5c55\u793a\u9875\u9762<br \/>\n            std::string body;<br \/>\n            body &#043;&#061; &#034;&lt;html&gt;&#034;;<br \/>\n            body &#043;&#061; &#034;&lt;head&gt;&#034;;<br \/>\n            body &#043;&#061; &#034;&lt;meta http-equiv&#061;&#039;Content-Type&#039; content&#061;&#039;text\/html;charset&#061;utf-8&#039;&gt;&#034;;<br \/>\n            body &#043;&#061; &#034;&lt;\/head&gt;&#034;;<br \/>\n            body &#043;&#061; &#034;&lt;body&gt;&#034;;<br \/>\n            body &#043;&#061; &#034;&lt;h1&gt;&#034;;<br \/>\n            body &#043;&#061; std::to_string(rsp-&gt;_statu);<br \/>\n            body &#043;&#061; &#034; &#034;;<br \/>\n            body &#043;&#061; Util::StatuDesc(rsp-&gt;_statu);<br \/>\n            body &#043;&#061; &#034;&lt;\/h1&gt;&#034;;<br \/>\n            body &#043;&#061; &#034;&lt;\/body&gt;&#034;;<br \/>\n            body &#043;&#061; &#034;&lt;\/html&gt;&#034;;<br \/>\n            \/\/2. \u5c06\u9875\u9762\u6570\u636e&#xff0c;\u5f53\u4f5c\u54cd\u5e94\u6b63\u6587&#xff0c;\u653e\u5165rsp\u4e2d<br \/>\n            rsp-&gt;SetContent(body, &#034;text\/html&#034;);<br \/>\n        }<br \/>\n        \/\/\u5c06HttpResponse\u4e2d\u7684\u8981\u7d20\u6309\u7167http\u534f\u8bae\u683c\u5f0f\u8fdb\u884c\u7ec4\u7ec7&#xff0c;\u53d1\u9001<br \/>\n        void WriteResponse(const PtrConnection &amp;conn, const HttpRequest &amp;req, HttpResponse &amp;rsp) {<br \/>\n            \/\/1. \u5148\u5b8c\u5584\u5934\u90e8\u5b57\u6bb5<br \/>\n            DBG_LOG(&#034;WRITE RESPONSE!!!&#034;);<br \/>\n            if (req.Close() &#061;&#061; true) {<br \/>\n                rsp.SetHeader(&#034;Connection&#034;, &#034;close&#034;);<br \/>\n            }else {<br \/>\n                rsp.SetHeader(&#034;Connection&#034;, &#034;keep-alive&#034;);<br \/>\n            }<br \/>\n            if (rsp._body.empty() &#061;&#061; false &amp;&amp; rsp.HasHeader(&#034;Content-Length&#034;) &#061;&#061; false) {<br \/>\n                rsp.SetHeader(&#034;Content-Length&#034;, std::to_string(rsp._body.size()));<br \/>\n            }<br \/>\n            if (rsp._body.empty() &#061;&#061; false &amp;&amp; rsp.HasHeader(&#034;Content-Type&#034;) &#061;&#061; false) {<br \/>\n                rsp.SetHeader(&#034;Content-Type&#034;, &#034;application\/octet-stream&#034;);<br \/>\n            }<br \/>\n            if (rsp._redirect &#061;&#061; true) {<br \/>\n                rsp.SetHeader(&#034;Location&#034;, rsp._redirect_url);<br \/>\n            }<br \/>\n            \/\/2. \u5c06rsp\u4e2d\u7684\u8981\u7d20&#xff0c;\u6309\u7167http\u534f\u8bae\u683c\u5f0f\u8fdb\u884c\u7ec4\u7ec7<br \/>\n            std::stringstream rsp_str;<br \/>\n            rsp_str &lt;&lt; req._version &lt;&lt; &#034; &#034; &lt;&lt; std::to_string(rsp._statu) &lt;&lt; &#034; &#034; &lt;&lt; Util::StatuDesc(rsp._statu) &lt;&lt; &#034;\\\\r\\\\n&#034;;<br \/>\n            for (auto &amp;head : rsp._headers) {<br \/>\n                rsp_str &lt;&lt; head.first &lt;&lt; &#034;: &#034; &lt;&lt; head.second &lt;&lt; &#034;\\\\r\\\\n&#034;;<br \/>\n            }<br \/>\n            rsp_str &lt;&lt; &#034;\\\\r\\\\n&#034;;<br \/>\n            rsp_str &lt;&lt; rsp._body;<br \/>\n            \/\/3. \u53d1\u9001\u6570\u636e<br \/>\n            conn-&gt;Send(rsp_str.str().c_str(), rsp_str.str().size());<br \/>\n        }<br \/>\n        \/**<br \/>\n         * &#064;brief \u5224\u65ad\u8bf7\u6c42\u662f\u5426\u662f\u6587\u4ef6\u5904\u7406\u8bf7\u6c42<br \/>\n         *<br \/>\n         * \u8be5\u51fd\u6570\u7528\u4e8e\u5224\u65ad\u4f20\u5165\u7684 HTTP \u8bf7\u6c42\u662f\u5426\u662f\u4e00\u4e2a\u6587\u4ef6\u5904\u7406\u8bf7\u6c42\u3002<br \/>\n         *<br \/>\n         * &#064;param req HTTP \u8bf7\u6c42\u5bf9\u8c61<br \/>\n         * &#064;return \u5982\u679c\u8bf7\u6c42\u662f\u6587\u4ef6\u5904\u7406\u8bf7\u6c42&#xff0c;\u5219\u8fd4\u56de true&#xff1b;\u5426\u5219\u8fd4\u56de false\u3002<br \/>\n         *\/<br \/>\n        bool IsFileHandler(const HttpRequest &amp;req) {<br \/>\n            \/\/ 1. \u5fc5\u987b\u8bbe\u7f6e\u4e86\u9759\u6001\u8d44\u6e90\u6839\u76ee\u5f55<br \/>\n            if (_basedir.empty()) {<br \/>\n                return false;<br \/>\n            }<br \/>\n            \/\/ 2. \u8bf7\u6c42\u65b9\u6cd5&#xff0c;\u5fc5\u987b\u662fGET \/ HEAD\u8bf7\u6c42\u65b9\u6cd5<br \/>\n            if (req._method !&#061; &#034;GET&#034; &amp;&amp; req._method !&#061; &#034;HEAD&#034;) {<br \/>\n                return false;<br \/>\n            }<br \/>\n            \/\/ 3. \u8bf7\u6c42\u7684\u8d44\u6e90\u8def\u5f84\u5fc5\u987b\u662f\u4e00\u4e2a\u5408\u6cd5\u8def\u5f84<br \/>\n            DBG_LOG(&#034;hahah: %s&#034;,req._path.c_str());<br \/>\n            if (Util::ValidPath(req._path) &#061;&#061; false) {<br \/>\n                return false;<br \/>\n            }<br \/>\n            \/\/ 4. \u8bf7\u6c42\u7684\u8d44\u6e90\u5fc5\u987b\u5b58\u5728,\u4e14\u662f\u4e00\u4e2a\u666e\u901a\u6587\u4ef6<br \/>\n            \/\/    \u6709\u4e00\u79cd\u8bf7\u6c42\u6bd4\u8f83\u7279\u6b8a &#8212; \u76ee\u5f55&#xff1a;\/, \/image\/&#xff0c; \u8fd9\u79cd\u60c5\u51b5\u7ed9\u540e\u8fb9\u9ed8\u8ba4\u8ffd\u52a0\u4e00\u4e2a index.html<br \/>\n            \/\/ index.html    \/image\/a.png<br \/>\n            \/\/ \u4e0d\u8981\u5fd8\u4e86\u524d\u7f00\u7684\u76f8\u5bf9\u6839\u76ee\u5f55,\u4e5f\u5c31\u662f\u5c06\u8bf7\u6c42\u8def\u5f84\u8f6c\u6362\u4e3a\u5b9e\u9645\u5b58\u5728\u7684\u8def\u5f84  \/image\/a.png  -&gt;   .\/wwwroot\/image\/a.png<br \/>\n            std::string req_path &#061; _basedir &#043; req._path;\/\/\u4e3a\u4e86\u907f\u514d\u76f4\u63a5\u4fee\u6539\u8bf7\u6c42\u7684\u8d44\u6e90\u8def\u5f84&#xff0c;\u56e0\u6b64\u5b9a\u4e49\u4e00\u4e2a\u4e34\u65f6\u5bf9\u8c61<br \/>\n            if (req._path.back() &#061;&#061; &#039;\/&#039;)  {<br \/>\n                req_path &#043;&#061; &#034;index.html&#034;;<br \/>\n            }<\/p>\n<p>            if (Util::IsRegular(req_path) &#061;&#061; false) {<br \/>\n                return false;<br \/>\n            }<br \/>\n            return true;<br \/>\n        }<br \/>\n        \/\/\u9759\u6001\u8d44\u6e90\u7684\u8bf7\u6c42\u5904\u7406 &#8212; \u5c06\u9759\u6001\u8d44\u6e90\u6587\u4ef6\u7684\u6570\u636e\u8bfb\u53d6\u51fa\u6765&#xff0c;\u653e\u5230rsp\u7684_body\u4e2d, \u5e76\u8bbe\u7f6emime<br \/>\n        void FileHandler(const HttpRequest &amp;req, HttpResponse *rsp) {<br \/>\n            std::string req_path &#061; _basedir &#043; req._path;<br \/>\n            if (req._path.back() &#061;&#061; &#039;\/&#039;)  {<br \/>\n                req_path &#043;&#061; &#034;index.html&#034;;<br \/>\n            }<br \/>\n            bool ret &#061; Util::ReadFile(req_path, &amp;rsp-&gt;_body);<br \/>\n            if (ret &#061;&#061; false) {<br \/>\n                return;<br \/>\n            }<br \/>\n            std::string mime &#061; Util::ExtMime(req_path);<br \/>\n            rsp-&gt;SetHeader(&#034;Content-Type&#034;, mime);<br \/>\n            return;<br \/>\n        }<br \/>\n        \/\/\u529f\u80fd\u6027\u8bf7\u6c42\u7684\u5206\u7c7b\u5904\u7406<br \/>\n        void Dispatcher(HttpRequest &amp;req, HttpResponse *rsp, Handlers &amp;handlers) {<br \/>\n            \/\/ \u5728\u5bf9\u5e94\u8bf7\u6c42\u65b9\u6cd5\u7684\u8def\u7531\u8868\u4e2d&#xff0c;\u67e5\u627e\u662f\u5426\u542b\u6709\u5bf9\u5e94\u8d44\u6e90\u8bf7\u6c42\u7684\u5904\u7406\u51fd\u6570&#xff0c;\u6709\u5219\u8c03\u7528&#xff0c;\u6ca1\u6709\u5219\u53d1\u6325404<br \/>\n            \/\/ \u601d\u60f3&#xff1a;\u8def\u7531\u8868\u5b58\u50a8\u7684\u65f6\u952e\u503c\u5bf9 &#8212; \u6b63\u5219\u8868\u8fbe\u5f0f &amp; \u5904\u7406\u51fd\u6570<br \/>\n            \/\/ \u4f7f\u7528\u6b63\u5219\u8868\u8fbe\u5f0f&#xff0c;\u5bf9\u8bf7\u6c42\u7684\u8d44\u6e90\u8def\u5f84\u8fdb\u884c\u6b63\u5219\u5339\u914d&#xff0c;\u5339\u914d\u6210\u529f\u5c31\u4f7f\u7528\u5bf9\u5e94\u51fd\u6570\u8fdb\u884c\u5904\u7406<br \/>\n            \/\/   \/numbers\/(\\\\d&#043;)       \/numbers\/12345<br \/>\n            DBG_LOG(&#034;ON Dispatcher&#034;);<br \/>\n            \/\/ \u904d\u5386\u6240\u6709\u7684\u5904\u7406\u5668<br \/>\n            for (auto &amp;handler : handlers) {<br \/>\n                \/\/ \u83b7\u53d6\u6b63\u5219\u8868\u8fbe\u5f0f<br \/>\n                const std::regex &amp;re &#061; handler.first;<br \/>\n                \/\/ \u83b7\u53d6\u5904\u7406\u51fd\u6570<br \/>\n                const Handler &amp;functor &#061; handler.second;<br \/>\n                \/\/ \u4f7f\u7528\u6b63\u5219\u8868\u8fbe\u5f0f\u5bf9\u8bf7\u6c42\u7684\u8d44\u6e90\u8def\u5f84\u8fdb\u884c\u6b63\u5219\u5339\u914d<br \/>\n                bool ret &#061; std::regex_match(req._path, req._matches, re);<br \/>\n                \/\/ \u5982\u679c\u5339\u914d\u5931\u8d25&#xff0c;\u5219\u7ee7\u7eed\u904d\u5386\u4e0b\u4e00\u4e2a\u5904\u7406\u5668<br \/>\n                if (ret &#061;&#061; false) {<br \/>\n                    continue;<br \/>\n                }<br \/>\n                \/\/ \u5339\u914d\u6210\u529f&#xff0c;\u8c03\u7528\u5904\u7406\u51fd\u6570&#xff0c;\u4f20\u5165\u8bf7\u6c42\u4fe1\u606f\u548c\u7a7a\u7684\u54cd\u5e94\u5bf9\u8c61<br \/>\n                return functor(req, rsp);\/\/\u4f20\u5165\u8bf7\u6c42\u4fe1\u606f&#xff0c;\u548c\u7a7a\u7684rsp&#xff0c;\u6267\u884c\u5904\u7406\u51fd\u6570<br \/>\n            }<br \/>\n            \/\/ \u5982\u679c\u904d\u5386\u5b8c\u6240\u6709\u5904\u7406\u5668\u90fd\u6ca1\u6709\u5339\u914d\u5230\u5bf9\u5e94\u7684\u5904\u7406\u51fd\u6570&#xff0c;\u5219\u8bbe\u7f6e\u54cd\u5e94\u72b6\u6001\u4e3a404<br \/>\n            rsp-&gt;_statu &#061; 404;<br \/>\n        }<br \/>\n        void Route(HttpRequest &amp;req, HttpResponse *rsp) {<br \/>\n            \/\/1. \u5bf9\u8bf7\u6c42\u8fdb\u884c\u5206\u8fa8&#xff0c;\u662f\u4e00\u4e2a\u9759\u6001\u8d44\u6e90\u8bf7\u6c42&#xff0c;\u8fd8\u662f\u4e00\u4e2a\u529f\u80fd\u6027\u8bf7\u6c42<br \/>\n            \/\/   \u9759\u6001\u8d44\u6e90\u8bf7\u6c42&#xff0c;\u5219\u8fdb\u884c\u9759\u6001\u8d44\u6e90\u7684\u5904\u7406<br \/>\n            \/\/   \u529f\u80fd\u6027\u8bf7\u6c42&#xff0c;\u5219\u9700\u8981\u901a\u8fc7\u51e0\u4e2a\u8bf7\u6c42\u8def\u7531\u8868\u6765\u786e\u5b9a\u662f\u5426\u6709\u5904\u7406\u51fd\u6570<br \/>\n            \/\/   \u65e2\u4e0d\u662f\u9759\u6001\u8d44\u6e90\u8bf7\u6c42&#xff0c;\u4e5f\u6ca1\u6709\u8bbe\u7f6e\u5bf9\u5e94\u7684\u529f\u80fd\u6027\u8bf7\u6c42\u5904\u7406\u51fd\u6570&#xff0c;\u5c31\u8fd4\u56de405<br \/>\n            DBG_LOG(&#034;Route&#034;);<br \/>\n            if (IsFileHandler(req) &#061;&#061; true) {<br \/>\n                \/\/\u662f\u4e00\u4e2a\u9759\u6001\u8d44\u6e90\u8bf7\u6c42, \u5219\u8fdb\u884c\u9759\u6001\u8d44\u6e90\u8bf7\u6c42\u7684\u5904\u7406<br \/>\n                return FileHandler(req, rsp);<br \/>\n            }<br \/>\n            if (req._method &#061;&#061; &#034;GET&#034; || req._method &#061;&#061; &#034;HEAD&#034;) {<br \/>\n                return Dispatcher(req, rsp, _get_route);<br \/>\n            }else if (req._method &#061;&#061; &#034;POST&#034;) {<br \/>\n                return Dispatcher(req, rsp, _post_route);<br \/>\n            }else if (req._method &#061;&#061; &#034;PUT&#034;) {<br \/>\n                return Dispatcher(req, rsp, _put_route);<br \/>\n            }else if (req._method &#061;&#061; &#034;DELETE&#034;) {<br \/>\n                return Dispatcher(req, rsp, _delete_route);<br \/>\n            }<br \/>\n            rsp-&gt;_statu &#061; 405;\/\/ Method Not Allowed<br \/>\n            return ;<br \/>\n        }<br \/>\n        \/\/\u8bbe\u7f6e\u4e0a\u4e0b\u6587<br \/>\n        void OnConnected(const PtrConnection &amp;conn) {<br \/>\n            conn-&gt;SetContext(HttpContext());<br \/>\n            DBG_LOG(&#034;NEW CONNECTION %p&#034;, conn.get());<br \/>\n        }<br \/>\n        \/\/\u7f13\u51b2\u533a\u6570\u636e\u89e3\u6790&#043;\u5904\u7406<br \/>\n        void OnMessage(const PtrConnection &amp;conn, Buffer *buffer) {<br \/>\n            while(buffer-&gt;ReadAbleSize() &gt; 0){<br \/>\n                \/\/1. \u83b7\u53d6\u4e0a\u4e0b\u6587<br \/>\n                DBG_LOG(&#034;ON MESSAGE 1&#034;);<br \/>\n                HttpContext *context &#061; conn-&gt;GetContext()-&gt;get&lt;HttpContext&gt;();<br \/>\n                \/\/2. \u901a\u8fc7\u4e0a\u4e0b\u6587\u5bf9\u7f13\u51b2\u533a\u6570\u636e\u8fdb\u884c\u89e3\u6790&#xff0c;\u5f97\u5230HttpRequest\u5bf9\u8c61<br \/>\n                \/\/  1. \u5982\u679c\u7f13\u51b2\u533a\u7684\u6570\u636e\u89e3\u6790\u51fa\u9519&#xff0c;\u5c31\u76f4\u63a5\u56de\u590d\u51fa\u9519\u54cd\u5e94<br \/>\n                \/\/  2. \u5982\u679c\u89e3\u6790\u6b63\u5e38&#xff0c;\u4e14\u8bf7\u6c42\u5df2\u7ecf\u83b7\u53d6\u5b8c\u6bd5&#xff0c;\u624d\u5f00\u59cb\u53bb\u8fdb\u884c\u5904\u7406<br \/>\n                context-&gt;RecvHttpRequest(buffer);<\/p>\n<p>                HttpRequest &amp;req &#061; context-&gt;Request();<br \/>\n                HttpResponse rsp(context-&gt;ResponseStatu());<br \/>\n                if (context-&gt;ResponseStatu() &gt;&#061; 400) {<br \/>\n                    \/\/\u8fdb\u884c\u9519\u8bef\u54cd\u5e94&#xff0c;\u5173\u95ed\u8fde\u63a5<br \/>\n                    DBG_LOG(&#034;ON MESSAGE ERROR&#034;);<br \/>\n                    ErrorHandler(req, &amp;rsp);\/\/\u586b\u5145\u4e00\u4e2a\u9519\u8bef\u663e\u793a\u9875\u9762\u6570\u636e\u5230rsp\u4e2d<br \/>\n                    WriteResponse(conn, req, rsp);\/\/\u7ec4\u7ec7\u54cd\u5e94\u53d1\u9001\u7ed9\u5ba2\u6237\u7aef<br \/>\n                    context-&gt;ReSet();<br \/>\n                    buffer-&gt;MoveReadOffset(buffer-&gt;ReadAbleSize());\/\/\u51fa\u9519\u4e86\u5c31\u628a\u7f13\u51b2\u533a\u6570\u636e\u6e05\u7a7a<br \/>\n                    conn-&gt;ShutDown();\/\/\u5173\u95ed\u8fde\u63a5<br \/>\n                    return;<br \/>\n                }<br \/>\n                if (context-&gt;RecvStatu() !&#061; RECV_HTTP_OVER) {<br \/>\n                    \/\/\u5f53\u524d\u8bf7\u6c42\u8fd8\u6ca1\u6709\u63a5\u6536\u5b8c\u6574,\u5219\u9000\u51fa&#xff0c;\u7b49\u65b0\u6570\u636e\u5230\u6765\u518d\u91cd\u65b0\u7ee7\u7eed\u5904\u7406<br \/>\n                    return;<br \/>\n                }<br \/>\n                \/\/3. \u8bf7\u6c42\u8def\u7531 &#043; \u4e1a\u52a1\u5904\u7406<br \/>\n                Route(req, &amp;rsp);<br \/>\n                \/\/4. \u5bf9HttpResponse\u8fdb\u884c\u7ec4\u7ec7\u53d1\u9001<br \/>\n                WriteResponse(conn, req, rsp);<br \/>\n                \/\/5. \u91cd\u7f6e\u4e0a\u4e0b\u6587<br \/>\n                context-&gt;ReSet();<br \/>\n                \/\/6. \u6839\u636e\u957f\u77ed\u8fde\u63a5\u5224\u65ad\u662f\u5426\u5173\u95ed\u8fde\u63a5\u6216\u8005\u7ee7\u7eed\u5904\u7406<br \/>\n                if (rsp.Close() &#061;&#061; true)<br \/>\n                {<br \/>\n                    DBG_LOG(&#034;rsp.close()&#034;);<br \/>\n                    conn-&gt;ShutDown();<br \/>\n                    \/\/\u77ed\u94fe\u63a5\u5219\u76f4\u63a5\u5173\u95ed<br \/>\n                }<br \/>\n            }<br \/>\n            return;<br \/>\n        }<br \/>\n    public:<br \/>\n        HttpServer(int port, int timeout &#061; DEFALT_TIMEOUT):_server(port) {<br \/>\n            _server.EnableInactiveRelease(timeout);<br \/>\n            _server.SetConnectedCallBack(std::bind(&amp;HttpServer::OnConnected, this, std::placeholders::_1));<br \/>\n            _server.SetMessageCallBack(std::bind(&amp;HttpServer::OnMessage, this, std::placeholders::_1, std::placeholders::_2));<br \/>\n        }<br \/>\n        void SetBaseDir(const std::string &amp;path) {<br \/>\n            if(Util::IsDirectory(path) &#061;&#061; true)<br \/>\n            _basedir &#061; path;<br \/>\n            else abort();<br \/>\n        }<br \/>\n        \/*\u8bbe\u7f6e\/\u6dfb\u52a0&#xff0c;\u8bf7\u6c42&#xff08;\u8bf7\u6c42\u7684\u6b63\u5219\u8868\u8fbe&#xff09;\u4e0e\u5904\u7406\u51fd\u6570\u7684\u6620\u5c04\u5173\u7cfb*\/<br \/>\n        void Get(const std::string &amp;pattern, const Handler &amp;handler) {<br \/>\n            _get_route.push_back(std::make_pair(std::regex(pattern), handler));<br \/>\n        }<br \/>\n        void Post(const std::string &amp;pattern, const Handler &amp;handler) {<br \/>\n            _post_route.push_back(std::make_pair(std::regex(pattern), handler));<br \/>\n        }<br \/>\n        void Put(const std::string &amp;pattern, const Handler &amp;handler) {<br \/>\n            _put_route.push_back(std::make_pair(std::regex(pattern), handler));<br \/>\n        }<br \/>\n        void Delete(const std::string &amp;pattern, const Handler &amp;handler) {<br \/>\n            _delete_route.push_back(std::make_pair(std::regex(pattern), handler));<br \/>\n        }<br \/>\n        void SetThreadCount(int count) {<br \/>\n            _server.SetThreadCount(count);<br \/>\n        }<br \/>\n        void Listen() {<br \/>\n            _server.Start();<br \/>\n        }<br \/>\n}; <\/p>\n<h3>\u7b80\u5355\u670d\u52a1\u5668\u642d\u5efa\u4f7f\u7528\u6837\u4f8b<\/h3>\n<p>                    #include &#034;http.hpp&#034;<\/p>\n<p>#define WWWROOT &#034;.\/wwwroot\/&#034;<\/p>\n<p>std::string RequestStr(const HttpRequest &amp;req)<br \/>\n{<br \/>\n    std::stringstream ss;<br \/>\n    ss &lt;&lt; req._method &lt;&lt; &#034; &#034; &lt;&lt; req._path &lt;&lt; &#034; &#034; &lt;&lt; req._version &lt;&lt; &#034;\\\\r\\\\n&#034;;<br \/>\n    for (auto &amp;it : req._params)<br \/>\n    {<br \/>\n        ss &lt;&lt; it.first &lt;&lt; &#034;: &#034; &lt;&lt; it.second &lt;&lt; &#034;\\\\r\\\\n&#034;;<br \/>\n    }<br \/>\n    for (auto &amp;it : req._headers)<br \/>\n    {<br \/>\n        ss &lt;&lt; it.first &lt;&lt; &#034;: &#034; &lt;&lt; it.second &lt;&lt; &#034;\\\\r\\\\n&#034;;<br \/>\n    }<br \/>\n    ss &lt;&lt; &#034;\\\\r\\\\n&#034;;<br \/>\n    ss &lt;&lt; req._body;<br \/>\n    return ss.str();<br \/>\n}<br \/>\nvoid Hello(const HttpRequest &amp;req, HttpResponse *rsp)<br \/>\n{<br \/>\n    rsp-&gt;SetContent(RequestStr(req), &#034;text\/plain&#034;);<br \/>\n    \/\/sleep(15);<br \/>\n}<br \/>\nvoid Login(const HttpRequest &amp;req, HttpResponse *rsp)<br \/>\n{<br \/>\n    rsp-&gt;SetContent(RequestStr(req), &#034;text\/plain&#034;);<br \/>\n}<br \/>\nvoid PutFile(const HttpRequest &amp;req, HttpResponse *rsp)<br \/>\n{<br \/>\n    rsp-&gt;SetContent(RequestStr(req), &#034;text\/plain&#034;);<br \/>\n    std::string pathname &#061; WWWROOT &#043; req._path;<br \/>\n    Util::WriteFile(pathname, req._body);<br \/>\n}<br \/>\nvoid DelFile(const HttpRequest &amp;req, HttpResponse *rsp)<br \/>\n{<br \/>\n    rsp-&gt;SetContent(RequestStr(req), &#034;text\/plain&#034;);<br \/>\n}<br \/>\nint main()<br \/>\n{<br \/>\n    HttpServer server(8085);<br \/>\n    server.SetThreadCount(3);<br \/>\n    server.SetBaseDir(WWWROOT); \/\/ \u8bbe\u7f6e\u9759\u6001\u8d44\u6e90\u6839\u76ee\u5f55&#xff0c;\u544a\u8bc9\u670d\u52a1\u5668\u6709\u9759\u6001\u8d44\u6e90\u8bf7\u6c42\u5230\u6765&#xff0c;\u9700\u8981\u5230\u54ea\u91cc\u53bb\u627e\u8d44\u6e90\u6587\u4ef6<br \/>\n    server.Get(&#034;\/hello&#034;, Hello);<br \/>\n    server.Post(&#034;\/login&#034;, Login);<br \/>\n    server.Put(&#034;\/1234.txt&#034;, PutFile);<br \/>\n    server.Delete(&#034;\/1234.txt&#034;, DelFile);<br \/>\n    INF_LOG(&#034;\u670d\u52a1\u5668\u8bbe\u7f6e\u5b8c\u6bd5&#034;);<br \/>\n    server.Listen();<br \/>\n    return 0;<br \/>\n} <\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u6587\u7ae0\u6d4f\u89c8\u9605\u8bfb1k\u6b21\uff0c\u70b9\u8d5e27\u6b21\uff0c\u6536\u85cf19\u6b21\u3002\u901a\u8fc7\u54b1\u4eec\u5b9e\u73b0\u7684\u2fbc\u5e76\u53d1\u670d\u52a1\u5668\u7ec4\u4ef6\uff0c\u53ef\u4ee5\u7b80\u6d01\u5feb\u901f\u7684\u5b8c\u6210\u2f00\u4e2a\u2fbc\u6027\u80fd\u7684\u670d\u52a1\u5668\u642d\u5efa\u3002\u5e76\u4e14\uff0c\u901a\u8fc7\u7ec4\u4ef6\u5185\u63d0\u4f9b\u7684\u4e0d\u540c\u5e94\u2f64\u5c42\u534f\u8bae\u2f40\u6301\uff0c\u4e5f\u53ef\u4ee5\u5feb\u901f\u5b8c\u6210\u2f00\u4e2a\u2fbc\u6027\u80fd\u5e94\u2f64\u670d\u52a1\u5668\u7684\u642d\u5efa\uff08\u5f53\u524d\u9879\u2f6c\u4e2d\u63d0\u4f9bHTTP\u534f\u8bae\u7ec4\u4ef6\u7684\u2f40\u6301\uff09\u3002\u5728\u8fd9\u2fa5\uff0c\u8981\u660e\u786e\u7684\u662f\u54b1\u4eec\u8981\u5b9e\u73b0\u7684\u662f\u2f00\u4e2a\u2fbc\u5e76\u53d1\u670d\u52a1\u5668\u7ec4\u4ef6\uff0c\u56e0\u6b64\u5f53\u524d\u7684\u9879\u2f6c\u4e2d\u5e76\u4e0d\u5305\u542b\u5b9e\u9645\u7684\u4e1a\u52a1\u5bb9\u3002<\/p>\n","protected":false},"author":2,"featured_media":15650,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[55,1039,43],"topic":[],"class_list":["post-15670","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-server","tag-c","tag-muduo","tag-43"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.3 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>\u4effmudou\u5e93one thread oneloop\u5f0f\u5e76\u53d1\u670d\u52a1\u5668 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.wsisp.com\/helps\/15670.html\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\u4effmudou\u5e93one thread oneloop\u5f0f\u5e76\u53d1\u670d\u52a1\u5668 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"og:description\" content=\"\u6587\u7ae0\u6d4f\u89c8\u9605\u8bfb1k\u6b21\uff0c\u70b9\u8d5e27\u6b21\uff0c\u6536\u85cf19\u6b21\u3002\u901a\u8fc7\u54b1\u4eec\u5b9e\u73b0\u7684\u2fbc\u5e76\u53d1\u670d\u52a1\u5668\u7ec4\u4ef6\uff0c\u53ef\u4ee5\u7b80\u6d01\u5feb\u901f\u7684\u5b8c\u6210\u2f00\u4e2a\u2fbc\u6027\u80fd\u7684\u670d\u52a1\u5668\u642d\u5efa\u3002\u5e76\u4e14\uff0c\u901a\u8fc7\u7ec4\u4ef6\u5185\u63d0\u4f9b\u7684\u4e0d\u540c\u5e94\u2f64\u5c42\u534f\u8bae\u2f40\u6301\uff0c\u4e5f\u53ef\u4ee5\u5feb\u901f\u5b8c\u6210\u2f00\u4e2a\u2fbc\u6027\u80fd\u5e94\u2f64\u670d\u52a1\u5668\u7684\u642d\u5efa\uff08\u5f53\u524d\u9879\u2f6c\u4e2d\u63d0\u4f9bHTTP\u534f\u8bae\u7ec4\u4ef6\u7684\u2f40\u6301\uff09\u3002\u5728\u8fd9\u2fa5\uff0c\u8981\u660e\u786e\u7684\u662f\u54b1\u4eec\u8981\u5b9e\u73b0\u7684\u662f\u2f00\u4e2a\u2fbc\u5e76\u53d1\u670d\u52a1\u5668\u7ec4\u4ef6\uff0c\u56e0\u6b64\u5f53\u524d\u7684\u9879\u2f6c\u4e2d\u5e76\u4e0d\u5305\u542b\u5b9e\u9645\u7684\u4e1a\u52a1\u5bb9\u3002\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.wsisp.com\/helps\/15670.html\" \/>\n<meta property=\"og:site_name\" content=\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"article:published_time\" content=\"2025-04-18T14:12:55+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250418141243-68025ddb91edf.png\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"45 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/15670.html\",\"url\":\"https:\/\/www.wsisp.com\/helps\/15670.html\",\"name\":\"\u4effmudou\u5e93one thread oneloop\u5f0f\u5e76\u53d1\u670d\u52a1\u5668 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"isPartOf\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\"},\"datePublished\":\"2025-04-18T14:12:55+00:00\",\"dateModified\":\"2025-04-18T14:12:55+00:00\",\"author\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/15670.html#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.wsisp.com\/helps\/15670.html\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/15670.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.wsisp.com\/helps\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\u4effmudou\u5e93one thread oneloop\u5f0f\u5e76\u53d1\u670d\u52a1\u5668\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\",\"url\":\"https:\/\/www.wsisp.com\/helps\/\",\"name\":\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"description\":\"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"contentUrl\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"caption\":\"admin\"},\"sameAs\":[\"http:\/\/wp.wsisp.com\"],\"url\":\"https:\/\/www.wsisp.com\/helps\/author\/admin\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"\u4effmudou\u5e93one thread oneloop\u5f0f\u5e76\u53d1\u670d\u52a1\u5668 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.wsisp.com\/helps\/15670.html","og_locale":"zh_CN","og_type":"article","og_title":"\u4effmudou\u5e93one thread oneloop\u5f0f\u5e76\u53d1\u670d\u52a1\u5668 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","og_description":"\u6587\u7ae0\u6d4f\u89c8\u9605\u8bfb1k\u6b21\uff0c\u70b9\u8d5e27\u6b21\uff0c\u6536\u85cf19\u6b21\u3002\u901a\u8fc7\u54b1\u4eec\u5b9e\u73b0\u7684\u2fbc\u5e76\u53d1\u670d\u52a1\u5668\u7ec4\u4ef6\uff0c\u53ef\u4ee5\u7b80\u6d01\u5feb\u901f\u7684\u5b8c\u6210\u2f00\u4e2a\u2fbc\u6027\u80fd\u7684\u670d\u52a1\u5668\u642d\u5efa\u3002\u5e76\u4e14\uff0c\u901a\u8fc7\u7ec4\u4ef6\u5185\u63d0\u4f9b\u7684\u4e0d\u540c\u5e94\u2f64\u5c42\u534f\u8bae\u2f40\u6301\uff0c\u4e5f\u53ef\u4ee5\u5feb\u901f\u5b8c\u6210\u2f00\u4e2a\u2fbc\u6027\u80fd\u5e94\u2f64\u670d\u52a1\u5668\u7684\u642d\u5efa\uff08\u5f53\u524d\u9879\u2f6c\u4e2d\u63d0\u4f9bHTTP\u534f\u8bae\u7ec4\u4ef6\u7684\u2f40\u6301\uff09\u3002\u5728\u8fd9\u2fa5\uff0c\u8981\u660e\u786e\u7684\u662f\u54b1\u4eec\u8981\u5b9e\u73b0\u7684\u662f\u2f00\u4e2a\u2fbc\u5e76\u53d1\u670d\u52a1\u5668\u7ec4\u4ef6\uff0c\u56e0\u6b64\u5f53\u524d\u7684\u9879\u2f6c\u4e2d\u5e76\u4e0d\u5305\u542b\u5b9e\u9645\u7684\u4e1a\u52a1\u5bb9\u3002","og_url":"https:\/\/www.wsisp.com\/helps\/15670.html","og_site_name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","article_published_time":"2025-04-18T14:12:55+00:00","og_image":[{"url":"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250418141243-68025ddb91edf.png"}],"author":"admin","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"admin","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"45 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.wsisp.com\/helps\/15670.html","url":"https:\/\/www.wsisp.com\/helps\/15670.html","name":"\u4effmudou\u5e93one thread oneloop\u5f0f\u5e76\u53d1\u670d\u52a1\u5668 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","isPartOf":{"@id":"https:\/\/www.wsisp.com\/helps\/#website"},"datePublished":"2025-04-18T14:12:55+00:00","dateModified":"2025-04-18T14:12:55+00:00","author":{"@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41"},"breadcrumb":{"@id":"https:\/\/www.wsisp.com\/helps\/15670.html#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.wsisp.com\/helps\/15670.html"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.wsisp.com\/helps\/15670.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.wsisp.com\/helps"},{"@type":"ListItem","position":2,"name":"\u4effmudou\u5e93one thread oneloop\u5f0f\u5e76\u53d1\u670d\u52a1\u5668"}]},{"@type":"WebSite","@id":"https:\/\/www.wsisp.com\/helps\/#website","url":"https:\/\/www.wsisp.com\/helps\/","name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","description":"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41","name":"admin","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/","url":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","contentUrl":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","caption":"admin"},"sameAs":["http:\/\/wp.wsisp.com"],"url":"https:\/\/www.wsisp.com\/helps\/author\/admin"}]}},"_links":{"self":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/15670","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/comments?post=15670"}],"version-history":[{"count":0,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/15670\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/media\/15650"}],"wp:attachment":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/media?parent=15670"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/categories?post=15670"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/tags?post=15670"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/topic?post=15670"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}