{"id":108189,"date":"2026-09-21T07:25:52","date_gmt":"2026-09-20T23:25:52","guid":{"rendered":"https:\/\/www.wsisp.com\/helps\/108189.html"},"modified":"2026-09-21T07:25:52","modified_gmt":"2026-09-20T23:25:52","slug":"%e3%80%90linux%e3%80%91%e4%b8%89%e5%8d%81%e5%85%ab-c-%e6%89%8b%e5%86%99-http-%e6%9c%8d%e5%8a%a1%e5%99%a8%ef%bc%9a%e8%a3%b8-socket-fork-%e5%a4%9a%e8%bf%9b%e7%a8%8b%ef%bc%8c%e4%bb%8e-http-%e6%8a%a5","status":"publish","type":"post","link":"https:\/\/www.wsisp.com\/helps\/108189.html","title":{"rendered":"\u3010Linux\u3011\u4e09\u5341\u516b.C++ \u624b\u5199 HTTP \u670d\u52a1\u5668\uff1a\u88f8 socket + fork \u591a\u8fdb\u7a0b\uff0c\u4ece HTTP \u62a5\u6587\u89e3\u6790\u5230\u6d4f\u89c8\u5668\u6253\u5f00\u7f51\u9875"},"content":{"rendered":"<p id=\"c++-\u624b\u5199-http-\u670d\u52a1\u5668\uff1a\u88f8-socket-+-fork-\u591a\u8fdb\u7a0b\uff0c\u4ece-http-\u62a5\u6587\u89e3\u6790\u5230\u6d4f\u89c8\u5668\u6253\u5f00\u7f51\u9875\">C&#043;&#043; \u7f51\u7edc\u7f16\u7a0b\u5b9e\u6218 &#xff1a;C&#043;&#043;\u3001HTTP \u670d\u52a1\u5668\u3001socket \u7f16\u7a0b\u3001fork \u591a\u8fdb\u7a0b\u3001HTTP \u534f\u8bae\u89e3\u6790\u3001Linux \u7f51\u7edc\u7f16\u7a0b<\/p>\n<hr \/>\n<p>TCP \u4e09\u6b21\u63e1\u624b\u80cc\u5f97\u6eda\u74dc\u70c2\u719f&#xff0c;socket \u90a3\u51e0\u4e2a\u51fd\u6570\u4e5f\u4f1a\u8c03&#xff0c;\u53ef\u4e00\u65e6\u8981\u81ea\u5df1\u6512\u4e00\u4e2a HTTP \u670d\u52a1\u5668&#xff0c;\u5f88\u591a\u4eba\u5c31\u5361\u4f4f\u4e86&#xff1a;\u62a5\u6587\u683c\u5f0f\u8bb0\u4e0d\u7262\u3001\u4e0d\u77e5\u9053\u8be5\u5207\u51e0\u5c42\u3001\u5199\u5b8c\u4e5f\u4e0d\u77e5\u9053\u5bf9\u4e0d\u5bf9&#xff0c;\u53ea\u80fd\u9760&#034;\u770b\u8d77\u6765\u80fd\u8dd1&#034;\u81ea\u6211\u5b89\u6170\u3002<\/p>\n<p>\u66f4\u9ebb\u70e6\u7684\u662f&#xff0c;\u7b49\u4f60\u771f\u53bb\u8bfb\u522b\u4eba\u7684 HTTP \u670d\u52a1\u5668\u4ee3\u7801&#xff0c;\u5f80\u5f80\u662f\u4e00\u5768\u2014\u2014\u89e3\u6790\u3001\u7f51\u7edc\u3001\u4e1a\u52a1\u5168\u7cca\u5728\u4e00\u4e2a\u6587\u4ef6\u91cc&#xff0c;\u770b\u4e0d\u51fa\u54ea\u5c42\u8be5\u5e72\u4ec0\u4e48\u3002<\/p>\n<p>\u8fd9\u7bc7\u6587\u7ae0\u628a\u8fd9\u4ef6\u4e8b\u4ece\u5934\u62c6\u5230\u5e95\u3002\u5168\u90e8\u4ee3\u7801\u5c31\u662f\u5341\u6765\u4e2a\u6587\u4ef6&#xff0c;\u6bcf\u4e00\u6bb5\u6211\u90fd\u8bb2\u900f\u3002\u8bfb\u5b8c\u4f60\u4f1a\u62ff\u5230\u4e09\u6837\u4e1c\u897f&#xff1a;<\/p>\n<li>\n<p>\u4e00\u4e2a\u771f\u6b63\u80fd\u8dd1\u7684\u670d\u52a1\u5668\u2014\u2014\u6d4f\u89c8\u5668\u6253\u5f00\u6709\u9875\u9762&#xff0c;curl \u62ff\u5230\u6b63\u786e\u72b6\u6001\u7801&#xff0c;\u9996\u9875\u3001404\u3001301\u3001\u52a8\u6001\u8def\u7531\u5168\u90fd\u5b9e\u6d4b\u8fc7&#xff1b;<\/p>\n<\/li>\n<li>\n<p>\u4e00\u5f20\u6e05\u6670\u7684\u5206\u5c42\u5730\u56fe\u2014\u2014TcpServer \u7ba1\u8fdb\u7a0b\u3001Http \u7ba1\u534f\u8bae\u3001\u4e1a\u52a1\u51fd\u6570\u7ba1\u903b\u8f91&#xff0c;\u54ea\u4e2a\u6587\u4ef6\u5e72\u4ec0\u4e48\u6d3b&#xff0c;\u4e00\u773c\u770b\u6e05&#xff1b;<\/p>\n<\/li>\n<li>\n<p>\u4e00\u4efd 12 \u6761\u8e29\u5751\u6e05\u5355\u2014\u2014\u5168\u662f\u771f\u8dd1\u51fa\u6765\u7684&#xff0c;\u5305\u62ec\u90a3\u4e9b\u7f16\u8bd1\u96f6\u8b66\u544a\u3001\u8fdb\u7a0b\u4e0d\u5d29\u3001\u9875\u9762&#034;\u770b\u8d77\u6765&#034;\u8fd8\u80fd\u5f00&#xff0c;\u56e0\u800c\u80fd\u6d3b\u597d\u51e0\u5e74\u7684\u9690\u853d bug\u3002<\/p>\n<\/li>\n<p>\u6587\u672b\u6709\u5b8c\u6574\u7684\u8fd0\u884c\u73b0\u8c61\u548c\u6211\u8e29\u8fc7\u7684\u5751&#xff0c;\u8f93\u51fa\u90fd\u662f\u771f\u8dd1\u51fa\u6765\u7684&#xff0c;\u4e0d\u662f\u7f16\u7684\u3002<\/p>\n<hr \/>\n<h3 id=\"\u4e00\u3001\u5148\u770b\u5168\u666f\uff1a\u8fd9\u4e2a\u9879\u76ee\u7684\u5206\u5c42\">\u4e00\u3001\u5148\u770b\u5168\u666f&#xff1a;\u8fd9\u4e2a\u9879\u76ee\u7684\u5206\u5c42<\/h3>\n<p>\u5199\u7f51\u7edc\u7a0b\u5e8f\u6700\u6015\u4e00\u4e0a\u6765\u5c31\u624e\u8fdb\u4ee3\u7801\u91cc\u51fa\u4e0d\u6765\u3002\u6211\u5148\u628a\u6574\u4e2a\u9879\u76ee\u7684\u5c42\u6b21\u753b\u51fa\u6765&#xff0c;\u4f60\u5728\u54ea\u4e2a\u6587\u4ef6\u3001\u5e72\u7684\u662f\u4ec0\u4e48\u6d3b&#xff0c;\u5fc3\u91cc\u5f97\u6709\u5f20\u5730\u56fe&#xff1a;<\/p>\n<p>&#043;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-&#043;<br \/>\n|  Main.cc          \u5165\u53e3&#xff1a;\u6ce8\u518c\u8def\u7531 \/login -&gt; Login \u51fd\u6570      |<br \/>\n&#043;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-&#043;<br \/>\n|  Http.hpp         \u5e94\u7528\u5c42&#xff1a;\u89e3\u6790HTTP\u8bf7\u6c42 \/ \u6784\u9020HTTP\u54cd\u5e94 \/     |<br \/>\n|                   \u8def\u7531\u5206\u53d1 \/ \u8bfb\u9759\u6001\u6587\u4ef6                     |<br \/>\n&#043;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-&#043;<br \/>\n|  TcpServer.hpp    \u7f51\u7edc\u670d\u52a1\u5c42&#xff1a;accept &#043; fork \u5e76\u53d1 &#043; \u56de\u8c03     |<br \/>\n&#043;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-&#043;<br \/>\n|  Socket.hpp       socket\u5c01\u88c5&#xff1a;\u6a21\u677f\u65b9\u6cd5\u6a21\u5f0f                  |<br \/>\n|  InetAddr.hpp     \u5730\u5740\u5c01\u88c5&#xff1a;\u4e3b\u673a\u5e8f&lt;-&gt;\u7f51\u7edc\u5e8f                 |<br \/>\n&#043;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-&#043;<br \/>\n|  Util.hpp         \u5de5\u5177&#xff1a;\u8bfb\u6587\u4ef6 \/ \u6309\u5206\u9694\u7b26\u5207\u884c \/ \u6587\u4ef6\u5927\u5c0f    |<br \/>\n|  Log.hpp          \u65e5\u5fd7&#xff1a;\u7b56\u7565\u6a21\u5f0f&#xff08;\u63a7\u5236\u53f0\/\u6587\u4ef6&#xff09;             |<br \/>\n|  Mutex.hpp        \u9501&#xff1a;RAII\u5c01\u88c5                              |<br \/>\n|  Common.hpp       \u516c\u5171\u679a\u4e3e \/ \u5b8f                             |<br \/>\n&#043;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-&#043;<\/p>\n<p>\u8fd9\u4e2a\u5206\u5c42\u7684\u6838\u5fc3\u601d\u60f3\u5c31\u4e00\u53e5\u8bdd&#xff1a;\u7f51\u7edc\u548c\u4e1a\u52a1\u89e3\u8026\u3002<\/p>\n<p>TcpServer \u6839\u672c\u4e0d\u77e5\u9053 HTTP \u662f\u4ec0\u4e48&#xff0c;\u5b83\u53ea\u7ba1&#034;\u6765\u4e00\u4e2a\u8fde\u63a5&#xff0c;\u6211\u5c31 fork \u4e00\u4e2a\u8fdb\u7a0b\u53bb\u8dd1\u4f60\u7ed9\u6211\u7684\u56de\u8c03&#034;\u3002Http \u4e5f\u4e0d\u5173\u5fc3 socket \u600e\u4e48\u521b\u5efa\u7684&#xff0c;\u5b83\u53ea\u7ba1\u89e3\u6790\u62a5\u6587\u3001\u586b\u54cd\u5e94\u3002\u54ea\u5929\u4f60\u60f3\u628a HTTP \u6362\u6210\u522b\u7684\u534f\u8bae&#xff0c;TcpServer.hpp \u4e00\u884c\u4e0d\u7528\u52a8\u2014\u2014\u8fd9\u5c31\u662f\u6211\u6298\u817e\u8fd9\u4e48\u591a\u5c42\u6362\u6765\u7684\u81ea\u7531\u3002<\/p>\n<hr \/>\n<h3 id=\"\u4e8c\u3001http-\u62a5\u6587\u957f\u4ec0\u4e48\u6837\">\u4e8c\u3001HTTP \u62a5\u6587\u957f\u4ec0\u4e48\u6837<\/h3>\n<p>\u4ee3\u7801\u600e\u4e48\u5199&#xff0c;\u53d6\u51b3\u4e8e\u62a5\u6587\u957f\u4ec0\u4e48\u6837\u3002HTTP \u8bf7\u6c42\u548c\u54cd\u5e94\u7684\u7ed3\u6784\u662f\u7406\u89e3\u6574\u4e2a Http.hpp \u7684\u94a5\u5319\u3002<\/p>\n<p>HTTP REQUEST \u62a5\u6587\u683c\u5f0f\u56fe&#xff08;\u8bf7\u6c42\u884c \/ \u8bf7\u6c42\u62a5\u5934 \/ \u7a7a\u884c \/ \u8bf7\u6c42\u6b63\u6587&#xff09;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"671\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/09\/20260920232537-6ab06b71012a0.png\" width=\"1418\" \/><\/p>\n<p>HTTP RESPONSE \u62a5\u6587\u683c\u5f0f\u56fe&#xff08;\u72b6\u6001\u884c \/ \u54cd\u5e94\u62a5\u5934 \/ \u7a7a\u884c \/ \u54cd\u5e94\u6b63\u6587&#xff09;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"628\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/09\/20260920232537-6ab06b7150fdb.png\" width=\"1405\" \/><\/p>\n<p>\u4e24\u5f20\u56fe\u5bf9\u7167\u7740\u770b&#xff0c;\u7ed3\u6784\u5b8c\u5168\u5bf9\u79f0&#xff0c;\u5c31\u56db\u6bb5&#xff1a;<\/p>\n<p>\u8bf7\u6c42&#xff1a;<br \/>\n    GET \/login?username&#061;zhangsan&amp;password&#061;123456 HTTP\/1.1\\\\r\\\\n   &lt;- \u8bf7\u6c42\u884c<br \/>\n    Host: 127.0.0.1:8080\\\\r\\\\n                                    &lt;- \u62a5\u5934&#xff0c;\u4e00\u5806 Key: Value<br \/>\n    User-Agent: curl\/7.81.0\\\\r\\\\n<br \/>\n    Accept: *\/*\\\\r\\\\n<br \/>\n    \\\\r\\\\n                                                        &lt;- \u7a7a\u884c&#xff0c;\u62a5\u5934\u7ed3\u675f\u7684\u6807\u5fd7<br \/>\n    &#xff08;body&#xff0c;GET \u4e00\u822c\u6ca1\u6709&#xff09;                                        &lt;- \u6b63\u6587<\/p>\n<p>\u54cd\u5e94&#xff1a;<br \/>\n    HTTP\/1.0 200 OK\\\\r\\\\n                                         &lt;- \u72b6\u6001\u884c<br \/>\n    Content-Type: text\/html\\\\r\\\\n                                 &lt;- \u62a5\u5934<br \/>\n    Content-Length: 2872\\\\r\\\\n<br \/>\n    \\\\r\\\\n                                                        &lt;- \u7a7a\u884c<br \/>\n    &lt;html&gt;&#8230;&lt;\/html&gt;                                            &lt;- \u6b63\u6587<\/p>\n<p>\u4e09\u4e2a\u5fc5\u987b\u523b\u8fdb\u8111\u5b50\u91cc\u7684\u70b9&#xff1a;<\/p>\n<li>\n<p>\u6bcf\u4e00\u884c\u4ee5 \\\\r\\\\n \u7ed3\u5c3e&#xff0c;\u4e0d\u662f \\\\n\u3002\u8fd9\u662f\u534f\u8bae\u89c4\u5b9a\u7684&#xff0c;\u5c11\u4e2a \\\\r \u6d4f\u89c8\u5668\u90fd\u4e0d\u8ba4\u3002<\/p>\n<\/li>\n<li>\n<p>\u7a7a\u884c&#xff08;\u4e5f\u5c31\u662f\u5355\u72ec\u4e00\u4e2a \\\\r\\\\n&#xff09;\u662f\u62a5\u5934\u7ed3\u675f\u7684\u6807\u5fd7\u3002\u89e3\u6790\u7684\u65f6\u5019\u5c31\u662f\u9760\u5b83\u77e5\u9053&#034;\u540e\u9762\u662f\u6b63\u6587\u4e86&#034;\u3002<\/p>\n<\/li>\n<li>\n<p>\u6b63\u6587\u591a\u957f\u7531 Content-Length \u8bf4\u4e86\u7b97&#xff0c;\u4e0d\u662f\u9760 \\\\0 \u4e5f\u4e0d\u662f\u9760\u8fde\u63a5\u65ad\u5f00\u2014\u2014\u56e0\u4e3a TCP \u662f\u5b57\u8282\u6d41&#xff0c;\u6ca1\u6709&#034;\u62a5\u6587\u8fb9\u754c&#034;\u8fd9\u4e2a\u6982\u5ff5&#xff0c;\u8fb9\u754c\u5168\u662f\u5e94\u7528\u5c42\u81ea\u5df1\u7ea6\u5b9a\u7684&#xff08;\u8fd9\u5c31\u662f\u7c98\u5305\u95ee\u9898\u7684\u672c\u8d28&#xff0c;\u540e\u9762\u7ec6\u8bf4&#xff09;\u3002<\/p>\n<\/li>\n<p>\u6211\u4eec\u670d\u52a1\u5668\u7684\u6d3b&#xff0c;\u8bf4\u767d\u4e86\u5c31\u662f&#xff1a;\u6536\u4e00\u5927\u5768\u5b57\u8282\u6d41&#xff0c;\u6309\u4e0a\u9762\u7684\u683c\u5f0f\u5207\u5f00&#xff0c;\u7136\u540e\u6309\u683c\u5f0f\u62fc\u4e00\u5768\u56de\u53bb\u3002<\/p>\n<hr \/>\n<h3 id=\"\u4e09\u3001\u5730\u57fa\u56db\u4ef6\u5957\uff1acommon-\/-mutex-\/-log-\/-inetaddr\">\u4e09\u3001\u5730\u57fa\u56db\u4ef6\u5957&#xff1a;Common \/ Mutex \/ Log \/ InetAddr<\/h3>\n<p>\u8fd9\u56db\u4e2a\u6587\u4ef6\u4e0d\u542b\u4efb\u4f55 HTTP \u903b\u8f91&#xff0c;\u7eaf\u7cb9\u662f\u5730\u57fa\u3002\u6211\u6309\u4f9d\u8d56\u987a\u5e8f\u8bb2\u3002<\/p>\n<h4 id=\"3.1-common.hpp\u2014\u2014\u5168\u9879\u76ee\u7684&quot;\u516c\u5171\u8bcd\u5178&quot;\">3.1 Common.hpp\u2014\u2014\u5168\u9879\u76ee\u7684&#034;\u516c\u5171\u8bcd\u5178&#034;<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"985\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/09\/20260920232537-6ab06b719b602.png\" width=\"835\" \/><\/p>\n<p>#pragma once<\/p>\n<p>#include &lt;iostream&gt;<br \/>\n#include &lt;functional&gt;<br \/>\n#include &lt;unistd.h&gt;<br \/>\n#include &lt;string&gt;<br \/>\n#include &lt;cstring&gt;<br \/>\n#include &lt;sys\/socket.h&gt;<br \/>\n#include &lt;sys\/types.h&gt;<br \/>\n#include &lt;arpa\/inet.h&gt;<br \/>\n#include &lt;netinet\/in.h&gt;<\/p>\n<p>enum ExitCode<br \/>\n{<br \/>\n    OK &#061; 0,<br \/>\n    USAGE_ERR,<br \/>\n    SOCKET_ERR,<br \/>\n    BIND_ERR,<br \/>\n    LISTEN_ERR,<br \/>\n    CONNECT_ERR,<br \/>\n    FORK_ERR,<br \/>\n    OPEN_ERR<br \/>\n};<\/p>\n<p>\u8fd9\u4e2a enum ExitCode \u770b\u7740\u4e0d\u8d77\u773c&#xff0c;\u5176\u5b9e\u662f\u4e2a\u597d\u4e60\u60ef&#xff1a;\u8fdb\u7a0b\u9000\u51fa\u65f6 exit(SOCKET_ERR)&#xff0c;shell \u91cc echo $? \u5c31\u80fd\u62ff\u5230 2&#xff0c;\u5199\u811a\u672c\u76d1\u63a7\u670d\u52a1\u5668\u6302\u6ca1\u6302\u7684\u65f6\u5019\u7279\u522b\u597d\u7528\u3002\u6bd4\u6ee1\u4ee3\u7801\u7684 exit(1) \u5f3a\u591a\u4e86\u2014\u20141 \u662f\u4ec0\u4e48\u9519&#xff1f;\u8c01\u77e5\u9053\u3002<\/p>\n<hr \/>\n<p>class NoCopy<br \/>\n{<br \/>\npublic:<br \/>\n    NoCopy(){}<br \/>\n    ~NoCopy(){}<br \/>\n    NoCopy(const NoCopy &amp;) &#061; delete;<br \/>\n    const NoCopy &amp;operator &#061; (const NoCopy&amp;) &#061; delete;<br \/>\n};<\/p>\n<p>NoCopy \u7528 C&#043;&#043;11 \u7684 &#061; delete \u628a\u62f7\u8d1d\u6784\u9020\u548c\u8d4b\u503c\u76f4\u63a5\u5220\u6389\u3002\u60f3\u7981\u6b62\u62f7\u8d1d\u7684\u7c7b\u7ee7\u627f\u5b83\u5c31\u884c\u3002\u8fd9\u7248\u4ee3\u7801\u91cc TcpServer \u8fd8\u6ca1\u7ee7\u627f\u5b83&#xff0c;\u5c5e\u4e8e\u7559\u4e86\u4e2a\u5de5\u5177\u5728\u624b\u8fb9\u3002<\/p>\n<hr \/>\n<p>#define CONV(addr) ((struct sockaddr*)&amp;addr)<\/p>\n<p>\u8fd9\u4e2a\u5b8f\u662f\u7f51\u7edc\u7f16\u7a0b\u7684\u8001\u670b\u53cb\u4e86\u3002accept\u3001bind \u7684\u53c2\u6570\u7c7b\u578b\u662f struct sockaddr*&#xff08;\u901a\u7528\u5730\u5740\u7ed3\u6784&#xff09;&#xff0c;\u4f46\u6211\u4eec\u5b9e\u9645\u7528\u7684\u662f struct sockaddr_in&#xff08;IPv4 \u4e13\u7528&#xff09;\u3002\u5185\u6838\u63a5\u53e3\u5f53\u5e74\u6ca1\u505a\u6cdb\u578b&#xff0c;\u5c31\u9760\u5f3a\u8f6c\u51d1\u5408\u2014\u2014sockaddr_in \u524d 16 \u5b57\u8282\u548c sockaddr \u5e03\u5c40\u517c\u5bb9&#xff0c;\u6240\u4ee5\u5f3a\u8f6c\u662f\u5b89\u5168\u7684&#xff0c;\u8fd9\u662f\u6240\u6709 Unix \u7f51\u7edc\u4ee3\u7801\u7684\u60ef\u7528\u5199\u6cd5\u3002\u5c01\u88c5\u6210\u5b8f&#xff0c;\u81f3\u5c11\u4ee3\u7801\u91cc\u4e0d\u7528\u5230\u5904\u5199\u6076\u5fc3\u7684\u5f3a\u8f6c\u3002<\/p>\n<hr \/>\n<h4 id=\"3.2-mutex.hpp\u2014\u2014\u4e24\u628a\u9501\u7684-raii-\u5c01\u88c5\">3.2 Mutex.hpp\u2014\u2014\u4e24\u628a\u9501\u7684 RAII \u5c01\u88c5<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"1568\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/09\/20260920232537-6ab06b71dd4a3.png\" width=\"649\" \/><\/p>\n<p>class Mutex<br \/>\n{<br \/>\npublic:<br \/>\n    Mutex()<br \/>\n    {<br \/>\n        pthread_mutex_init(&amp;_mutex, nullptr);<br \/>\n    }<br \/>\n    void Lock()<br \/>\n    {<br \/>\n        int n &#061; pthread_mutex_lock(&amp;_mutex);<br \/>\n        (void)n;<br \/>\n    }<br \/>\n    void Unlock()<br \/>\n    {<br \/>\n        int n &#061; pthread_mutex_unlock(&amp;_mutex);<br \/>\n        (void)n;<br \/>\n    }<br \/>\n    ~Mutex()<br \/>\n    {<br \/>\n        pthread_mutex_destroy(&amp;_mutex);<br \/>\n    }<br \/>\nprivate:<br \/>\n    pthread_mutex_t _mutex;<br \/>\n};<\/p>\n<p>\u6784\u9020\u65f6 init&#xff0c;\u6790\u6784\u65f6 destroy\u2014\u2014\u8fd9\u5c31\u662f RAII \u7684\u5473\u9053&#xff0c;\u9501\u7684\u751f\u547d\u5468\u671f\u548c\u5bf9\u8c61\u7ed1\u5b9a&#xff0c;\u4e0d\u4f1a\u51fa\u73b0&#034;\u521d\u59cb\u5316\u4e86\u5fd8\u4e86\u9500\u6bc1&#034;\u7684\u6cc4\u6f0f\u3002<\/p>\n<p>\u771f\u6b63\u6709\u8bb2\u7a76\u7684\u662f\u4e0b\u9762\u8fd9\u4e2a&#xff1a;<\/p>\n<p>class LockGuard<br \/>\n{<br \/>\npublic:<br \/>\n    LockGuard(Mutex &amp;mutex):_mutex(mutex)<br \/>\n    {<br \/>\n        _mutex.Lock();<br \/>\n    }<br \/>\n    ~LockGuard()<br \/>\n    {<br \/>\n        _mutex.Unlock();<br \/>\n    }<br \/>\nprivate:<br \/>\n    Mutex &amp;_mutex;<br \/>\n};<\/p>\n<p>\u7528\u6cd5\u662f\u5728\u6808\u4e0a\u521b\u5efa\u4e00\u4e2a LockGuard \u5c40\u90e8\u5bf9\u8c61&#xff0c;\u6784\u9020\u65f6\u52a0\u9501\u3002<\/p>\n<p>\u5173\u952e\u5728\u6790\u6784&#xff1a;\u51fd\u6570\u4e0d\u7ba1\u4ece\u54ea\u6761\u8def\u5f84 return\u3001\u54ea\u6015\u629b\u5f02\u5e38&#xff0c;\u6808\u5bf9\u8c61\u7684\u6790\u6784\u51fd\u6570\u90fd\u4f1a\u6267\u884c&#xff0c;\u9501\u4e00\u5b9a\u88ab\u91ca\u653e\u3002\u5982\u679c\u4f60\u624b\u5199 lock() &#8230; \u4e2d\u95f4\u4e09\u884c\u4ee3\u7801 &#8230; unlock()&#xff0c;\u4e2d\u95f4\u4efb\u4f55\u4e00\u4e2a early return \u90fd\u80fd\u8ba9\u9501\u6c38\u8fdc\u56de\u4e0d\u53bb\u2014\u2014\u8fd9\u79cd\u6b7b\u9501\u6211\u5728\u771f\u5b9e\u9879\u76ee\u91cc\u89c1\u8fc7\u4e0d\u6b62\u4e00\u6b21\u3002\u6240\u4ee5\u89c4\u77e9\u5c31\u662f&#xff1a;\u80fd RAII \u7684\u7edd\u4e0d\u624b\u5199 lock\/unlock\u3002<\/p>\n<p>\u8fd9\u7248\u4ee3\u7801\u662f fork \u591a\u8fdb\u7a0b\u6a21\u578b&#xff0c;\u8fdb\u7a0b\u95f4\u4e0d\u5171\u4eab\u9501&#xff0c;Mutex \u5b9e\u9645\u7528\u5728\u4e86 Log.hpp \u7684\u591a\u573a\u666f\u9884\u7559\u4e0a&#xff08;\u65e5\u5fd7\u6a21\u5757\u662f\u7167\u7740\u591a\u7ebf\u7a0b\u573a\u666f\u5199\u7684&#xff09;\u3002<\/p>\n<hr \/>\n<h4 id=\"3.3-inetaddr.hpp\u2014\u2014\u5730\u5740\u7684&quot;\u7ffb\u8bd1\u5b98&quot;\">3.3 InetAddr.hpp\u2014\u2014\u5730\u5740\u7684&#034;\u7ffb\u8bd1\u5b98&#034;<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"2008\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/09\/20260920232538-6ab06b724c77c.png\" width=\"1196\" \/><\/p>\n<p>\u7f51\u7edc\u5730\u5740\u6709\u4e24\u526f\u9762\u5b54&#xff1a;\u5185\u5b58\u91cc\u662f struct sockaddr_in&#xff08;4 \u5b57\u8282 IP &#043; 2 \u5b57\u8282\u7aef\u53e3&#xff0c;\u5168\u662f\u5927\u7aef\u7f51\u7edc\u5e8f&#xff09;&#xff0c;\u4eba\u773c\u770b\u7684\u662f &#034;127.0.0.1&#034; &#043; 8080\u3002InetAddr \u5c31\u662f\u8fd9\u4e24\u526f\u9762\u5b54\u4e4b\u95f4\u7684\u7ffb\u8bd1\u5b98&#xff0c;\u628a sockaddr_in\u3001ip\u3001port \u4e09\u4e2a\u88c5\u5728\u4e00\u4e2a\u5bf9\u8c61\u91cc&#xff0c;\u8c01\u7528\u627e\u8c01\u8981\u3002<\/p>\n<p>\u6784\u9020\u51fd\u6570\u6709\u4e09\u80de\u80ce&#xff1a;<\/p>\n<p>InetAddr(struct sockaddr_in &amp;addr)          \/\/ \u4ece\u5bf9\u7aef\u6765\u7684&#xff1a;peer\u5730\u5740<br \/>\nInetAddr(const std::string &amp;ip, uint16_t port)  \/\/ \u5ba2\u6237\u7aef\u8fde\u670d\u52a1\u5668\u7528&#xff1a;\u6307\u5b9aIP<br \/>\nInetAddr(uint16_t port)                     \/\/ \u670d\u52a1\u5668\u7ed1\u5b9a\u7528&#xff1a;INADDR_ANY<\/p>\n<p>\u670d\u52a1\u5668\u7ed1\u5b9a\u65f6\u7528\u7684\u662f\u7b2c\u4e09\u4e2a&#xff1a;<\/p>\n<p>InetAddr(uint16_t port) : _ip(), _port(port) \/\/ \u987a\u5e8f\u548c\u6210\u5458\u58f0\u660e\u987a\u5e8f\u4fdd\u6301\u4e00\u81f4<br \/>\n{<br \/>\n    memset(&amp;_addr, 0, sizeof(_addr));<br \/>\n    _addr.sin_family &#061; AF_INET;<br \/>\n    _addr.sin_addr.s_addr &#061; INADDR_ANY;<br \/>\n    _addr.sin_port &#061; htons(_port);<br \/>\n}<\/p>\n<p>INADDR_ANY \u5c31\u662f 0.0.0.0&#xff0c;\u610f\u601d\u662f&#034;\u672c\u673a\u6240\u6709\u7f51\u5361\u4e0a\u7684\u8fd9\u4e2a\u7aef\u53e3\u6211\u90fd\u542c&#034;\u3002\u4f60\u7684\u673a\u5668\u53ef\u80fd\u6709 127.0.0.1&#xff08;\u56de\u73af&#xff09;\u3001192.168.x.x&#xff08;\u5c40\u57df\u7f51&#xff09;\u3001\u516c\u7f51 IP \u597d\u51e0\u4e2a\u5730\u5740&#xff0c;\u7ed1 ANY \u4e00\u52b3\u6c38\u9038\u3002htons \u628a\u4e3b\u673a\u5e8f\u8f6c\u7f51\u7edc\u5e8f\u2014\u2014\u8fd9\u4e2a\u5fc5\u987b\u8f6c&#xff0c;\u522b\u95ee&#xff0c;\u95ee\u5c31\u662f\u5386\u53f2\u7ea6\u5b9a&#xff1a;\u7f51\u7edc\u5b57\u8282\u5e8f\u7edf\u4e00\u5927\u7aef&#xff0c;x86 \u662f\u5c0f\u7aef\u3002<\/p>\n<p>\u4e00\u4e2a -Wreorder \u7684\u5751&#xff1a;\u6211\u4e0a\u9762\u5199\u4e86\u53e5\u6ce8\u91ca&#034;\u987a\u5e8f\u548c\u6210\u5458\u58f0\u660e\u987a\u5e8f\u4fdd\u6301\u4e00\u81f4&#034;\u3002C&#043;&#043; \u7684\u89c4\u77e9\u662f&#xff1a;\u6210\u5458\u521d\u59cb\u5316\u5217\u8868\u4e0d\u7ba1\u4f60\u5199\u6210\u4ec0\u4e48\u987a\u5e8f&#xff0c;\u5b9e\u9645\u521d\u59cb\u5316\u987a\u5e8f\u6c38\u8fdc\u6309\u6210\u5458\u58f0\u660e\u987a\u5e8f\u6267\u884c\u3002\u5982\u679c\u521d\u59cb\u5316\u5217\u8868\u987a\u5e8f\u548c\u58f0\u660e\u987a\u5e8f\u4e0d\u4e00\u81f4&#xff0c;\u7f16\u8bd1\u5668\u4e0d\u62a5\u9519&#xff0c;\u4f46 -Wall \u4f1a\u7529\u4f60\u4e00\u8138 -Wreorder\u3002\u6211 _port \u5199\u5728 _ip \u524d\u9762&#xff0c;\u58f0\u660e\u5374\u5728\u540e\u9762&#xff0c;\u6b63\u597d\u8e29\u4e2d\u3002\u8fd9\u79cd bug \u4e0d\u70b8\u903b\u8f91&#xff0c;\u4f46\u8bf4\u660e\u4f60\u5bf9\u6267\u884c\u987a\u5e8f\u7684\u8ba4\u77e5\u548c\u7f16\u8bd1\u5668\u4e0d\u4e00\u81f4&#xff0c;\u5f97\u6539\u3002<\/p>\n<p>\u4ece\u5bf9\u7aef\u5730\u5740\u8f6c\u56de\u4eba\u8bdd\u770b\u7684\u662f SetAddr&#xff1a;<\/p>\n<p>void SetAddr(struct sockaddr_in &amp;addr)<br \/>\n{<br \/>\n    _addr &#061; addr;<br \/>\n    _port &#061; ntohs(_addr.sin_port); \/\/ \u4ece\u7f51\u7edc\u4e2d\u62ff\u5230\u7684&#xff01;\u7f51\u7edc\u5e8f\u5217<br \/>\n    char ipbuffer[64];<br \/>\n    inet_ntop(AF_INET, &amp;_addr.sin_addr, ipbuffer, sizeof(ipbuffer));<br \/>\n    _ip &#061; ipbuffer;<br \/>\n}<\/p>\n<p>\u8fd9\u91cc\u6709\u4e2a\u6211\u6539\u8fc7\u7684 bug&#xff1a;inet_ntop \u7684\u6700\u540e\u4e00\u4e2a\u53c2\u6570\u662f\u7f13\u51b2\u533a\u5927\u5c0f&#xff0c;\u539f\u6765\u5199\u7684\u662f sizeof(_addr)\u2014\u2014\u90a3\u662f\u5730\u5740\u7ed3\u6784\u7684\u5927\u5c0f 16&#xff0c;\u4e0d\u662f ipbuffer \u7684\u5927\u5c0f 64\u3002IPv4 \u70b9\u5206\u5341\u8fdb\u5236\u6700\u957f\u5c31\u662f &#034;255.255.255.255&#034; \u6070\u597d 16 \u5b57\u8282&#xff08;15 \u5b57\u7b26 &#043; \\\\0&#xff09;&#xff0c;\u6240\u4ee5\u4fa5\u5e78\u6ca1\u51fa\u4e8b\u3002\u4f46&#034;\u6070\u597d\u591f&#034;\u548c&#034;\u5199\u5bf9\u4e86&#034;\u662f\u4e24\u56de\u4e8b&#xff0c;\u54ea\u5929\u6709\u4eba\u628a buffer \u6539\u5c0f\u4e00\u70b9\u5c31\u662f\u6808\u6ea2\u51fa\u3002<\/p>\n<p>\u8001\u4ee3\u7801\u91cc\u5e38\u89c1\u7684 inet_ntoa \u6211\u4e0d\u5efa\u8bae\u7528\u2014\u2014\u5b83\u8fd4\u56de\u9759\u6001\u7f13\u51b2\u533a\u6307\u9488&#xff0c;\u591a\u7ebf\u7a0b\u4e0b\u4e24\u4e2a\u7ebf\u7a0b\u540c\u65f6\u8c03\u4f1a\u4e92\u76f8\u8986\u76d6&#xff0c;inet_ntop \u628a buffer \u4ea4\u7ed9\u8c03\u7528\u8005&#xff0c;\u5929\u7136\u7ebf\u7a0b\u5b89\u5168\u3002<\/p>\n<hr \/>\n<h4 id=\"3.4-log.hpp\u2014\u2014\u7b56\u7565\u6a21\u5f0f\u65e5\u5fd7\">3.4 Log.hpp\u2014\u2014\u7b56\u7565\u6a21\u5f0f\u65e5\u5fd7<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"6636\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/09\/20260920232539-6ab06b7331b9d.png\" width=\"1121\" \/><\/p>\n<p>\u65e5\u5fd7\u6a21\u5757\u503c\u5f97\u5355\u72ec\u4e00\u8282&#xff0c;\u56e0\u4e3a\u5b83\u662f\u8fd9\u4e2a\u9879\u76ee\u91cc&#034;\u8bbe\u8ba1\u6a21\u5f0f\u6d53\u5ea6&#034;\u6700\u9ad8\u7684\u5730\u65b9&#xff0c;\u800c\u4e14\u90a3\u4e2a C&#043;&#043; \u6280\u5de7\u76f8\u5f53\u6f02\u4eae\u3002<\/p>\n<p>\u7b2c\u4e00\u5c42&#xff1a;\u5237\u65b0\u7b56\u7565&#xff08;\u7b56\u7565\u6a21\u5f0f&#xff09;<\/p>\n<p>class LogStrategy<br \/>\n{<br \/>\npublic:<br \/>\n    ~LogStrategy() &#061; default;<br \/>\n    virtual void SyncLog(const std::string &amp;message) &#061; 0;<br \/>\n};<\/p>\n<p>\u7eaf\u865a\u57fa\u7c7b&#xff0c;\u7ea6\u5b9a&#034;\u65e5\u5fd7\u600e\u4e48\u5237\u51fa\u53bb&#034;\u3002\u4e24\u4e2a\u5b9e\u73b0&#xff1a;<\/p>\n<ul>\n<li>\n<p>ConsoleLogStrategy&#xff1a;\u5f80 std::cout \u5237&#xff0c;\u5185\u90e8\u5e26\u9501&#xff1b;<\/p>\n<\/li>\n<li>\n<p>FileLogStrategy&#xff1a;\u5f80\u6587\u4ef6\u5237&#xff0c;\u6784\u9020\u65f6\u7528 C&#043;&#043;17 \u7684 std::filesystem::create_directories \u81ea\u52a8\u5efa\u76ee\u5f55&#xff08;\u76ee\u5f55\u5b58\u5728\u5c31\u8df3\u8fc7&#xff09;&#xff0c;\u5199\u7684\u65f6\u5019\u4ee5 std::ios::app \u8ffd\u52a0\u6a21\u5f0f\u6253\u5f00\u2014\u2014\u670d\u52a1\u5668\u91cd\u542f\u65e5\u5fd7\u4e0d\u4e22\u3002<\/p>\n<\/li>\n<\/ul>\n<p>\u5207\u6362\u7b56\u7565\u5c31\u4e00\u884c&#xff1a;<\/p>\n<p>void EnableFileLogStrategy()   { _fflush_strategy &#061; std::make_unique&lt;FileLogStrategy&gt;(); }<br \/>\nvoid EnableConsoleLogStrategy(){ _fflush_strategy &#061; std::make_unique&lt;ConsoleLogStrategy&gt;(); }<\/p>\n<p>unique_ptr \u6362\u4e2a\u6307\u5411\u5c31\u5b8c\u6210\u4e86\u7b56\u7565\u5207\u6362&#xff0c;\u591a\u6001&#043;\u667a\u80fd\u6307\u9488&#xff0c;\u4e0d\u9700\u8981 new\/delete\u3002\u60f3\u6539\u6210&#034;\u65e5\u5fd7\u8fdb MySQL&#034;&#xff1f;\u52a0\u4e2a\u5b50\u7c7b\u5c31\u884c&#xff0c;\u5176\u4ed6\u4ee3\u7801\u5168\u4e0d\u52a8\u3002<\/p>\n<hr \/>\n<p>\u7b2c\u4e8c\u5c42&#xff1a;\u62fc\u4e00\u6761\u65e5\u5fd7\u7684\u6280\u5de7\u2014\u2014\u4e34\u65f6\u5bf9\u8c61 &#043; \u6790\u6784\u5237\u65b0<\/p>\n<p>\u8fd9\u662f\u6574\u4e2a Log.hpp \u6700\u7cbe\u5999\u7684\u5730\u65b9&#xff0c;\u6211\u7b2c\u4e00\u6b21\u770b\u7684\u65f6\u5019\u62cd\u6848\u53eb\u7edd&#xff1a;<\/p>\n<p>class LogMessage<br \/>\n{<br \/>\npublic:<br \/>\n    LogMessage(LogLevel &amp;level, std::string &amp;src_name, int line_number, Logger &amp;logger)<br \/>\n        : _curr_time(GetTimeStamp()), _level(level), _pid(getpid()),<br \/>\n          _src_name(src_name), _line_number(line_number), _logger(logger)<br \/>\n    {<br \/>\n        \/\/ \u65e5\u5fd7\u7684\u5de6\u8fb9\u90e8\u5206&#xff0c;\u5408\u5e76\u8d77\u6765<br \/>\n        std::stringstream ss;<br \/>\n        ss &lt;&lt; &#034;[&#034; &lt;&lt; _curr_time &lt;&lt; &#034;] &#034;<br \/>\n           &lt;&lt; &#034;[&#034; &lt;&lt; Level2Str(_level) &lt;&lt; &#034;] &#034;<br \/>\n           &lt;&lt; &#034;[&#034; &lt;&lt; _pid &lt;&lt; &#034;] &#034;<br \/>\n           &lt;&lt; &#034;[&#034; &lt;&lt; _src_name &lt;&lt; &#034;] &#034;<br \/>\n           &lt;&lt; &#034;[&#034; &lt;&lt; _line_number &lt;&lt; &#034;] &#034;<br \/>\n           &lt;&lt; &#034;- &#034;;<br \/>\n        _loginfo &#061; ss.str();<br \/>\n    }<br \/>\n    template &lt;typename T&gt;<br \/>\n    LogMessage &amp;operator&lt;&lt;(const T &amp;info)<br \/>\n    {<br \/>\n        std::stringstream ss;<br \/>\n        ss &lt;&lt; info;<br \/>\n        _loginfo &#043;&#061; ss.str();<br \/>\n        return *this;<br \/>\n    }<br \/>\n    ~LogMessage()<br \/>\n    {<br \/>\n        if (_logger._fflush_strategy)<br \/>\n        {<br \/>\n            _logger._fflush_strategy-&gt;SyncLog(_loginfo);<br \/>\n        }<br \/>\n    }<\/p>\n<p>\u770b\u6784\u9020\u51fd\u6570\u5de6\u8fb9\u62fc\u4ec0\u4e48&#xff1a;\u65f6\u95f4\u3001\u7b49\u7ea7\u3001PID\u3001\u6587\u4ef6\u540d\u3001\u884c\u53f7\u3002__FILE__ \u548c __LINE__ \u662f\u7f16\u8bd1\u5668\u5185\u7f6e\u5b8f&#xff0c;\u6240\u4ee5\u6bcf\u6761\u65e5\u5fd7\u5929\u7136\u5e26&#034;\u6848\u53d1\u73b0\u573a&#034;&#xff1a;<\/p>\n<p>[2026-09-19 15:50:37] [DEBUG] [2778380] [Http.hpp] [64] &#8211; _method: GET<\/p>\n<p>\u51fa\u4e86\u95ee\u9898&#xff0c;\u65e5\u5fd7\u4e00\u7ffb\u5c31\u77e5\u9053\u54ea\u4e2a\u6587\u4ef6\u54ea\u4e00\u884c\u3001\u662f\u54ea\u4e2a\u8fdb\u7a0b\u6253\u7684\u2014\u2014fork \u6a21\u578b\u4e0b PID \u5c24\u5176\u91cd\u8981&#xff0c;\u4e00\u773c\u770b\u51fa\u662f\u7236\u8fdb\u7a0b\u8fd8\u662f\u54ea\u4e2a\u5b50\u8fdb\u7a0b\u5728\u8bf4\u8bdd\u3002<\/p>\n<p>\u518d\u770b\u4f7f\u7528\u4fa7&#xff1a;<\/p>\n<p>LOG(LogLevel::DEBUG) &lt;&lt; &#034;_method: &#034; &lt;&lt; _method;<\/p>\n<p>\u5b8f\u5c55\u5f00\u662f logger(LogLevel::DEBUG, __FILE__, __LINE__)&#xff0c;\u8c03\u7528\u7684\u662f&#xff1a;<\/p>\n<p>LogMessage operator()(LogLevel level, std::string name, int line)<br \/>\n{<br \/>\n    return LogMessage(level, name, line, *this);  \/\/ \u6545\u610f\u8fd4\u56de\u4e34\u65f6\u5bf9\u8c61<br \/>\n}<\/p>\n<p>\u6ce8\u610f&#xff1a;\u8fd4\u56de\u7684\u662f\u4e34\u65f6\u5bf9\u8c61&#xff0c;\u4e0d\u662f\u6307\u9488\u4e0d\u662f\u5f15\u7528\u3002 \u540e\u9762\u4e00\u8fde\u4e32 &lt;&lt; \u90fd\u5728\u8fd9\u4e2a\u4e34\u65f6\u5bf9\u8c61\u4e0a\u8ffd\u52a0\u5185\u5bb9\u3002<\/p>\n<p>\u5173\u952e\u6765\u4e86\u2014\u2014\u8fd9\u6574\u6761\u8bed\u53e5\u7ed3\u675f\u65f6&#xff0c;\u4e34\u65f6\u5bf9\u8c61\u7684\u751f\u547d\u5468\u671f\u5230\u5934&#xff0c;\u6790\u6784\u51fd\u6570\u81ea\u52a8\u89e6\u53d1&#xff0c;SyncLog \u628a\u6512\u597d\u7684\u5b8c\u6574\u65e5\u5fd7\u4e00\u6b21\u6027\u5237\u51fa\u53bb\u3002<\/p>\n<p>\u8fd9\u5c31\u662f&#034;\u4e34\u65f6\u5bf9\u8c61\u6790\u6784\u5373\u5237\u65b0&#034;\u6280\u5de7&#xff1a;\u5237\u65b0\u52a8\u4f5c\u4e0d\u7528\u7528\u6237\u64cd\u5fc3&#xff0c;C&#043;&#043; \u7684\u5bf9\u8c61\u751f\u547d\u5468\u671f\u89c4\u5219\u66ff\u4f60\u515c\u5e95\u3002\u8fd9\u4e5f\u89e3\u91ca\u4e86\u4e00\u4e2a\u5751\u2014\u2014\u4f60\u7edd\u5bf9\u4e0d\u80fd\u628a LOG(&#8230;) \u5199\u6210\u591a\u884c\u8bed\u53e5&#xff1a;<\/p>\n<p>LOG(LogLevel::DEBUG) &lt;&lt; &#034;a&#034;;<br \/>\n&lt;&lt; &#034;b&#034;;   \/\/ \u7f16\u8bd1\u9519\u8bef&#xff01;\u4e34\u65f6\u5bf9\u8c61\u4e0a\u4e00\u884c\u5c31\u6790\u6784\u4e86<\/p>\n<p>\u8fd8\u6709\u4e2a\u5b9e\u73b0\u7ec6\u8282&#xff1a;\u65e5\u5fd7\u91cc\u6362\u884c\u6211\u7edf\u4e00\u7528 \\\\r\\\\n&#xff08;gsep&#xff09;&#xff0c;\u4e0d\u7528 std::endl\u2014\u2014endl \u9664\u4e86\u6362\u884c\u8fd8\u4f1a flush \u6d41&#xff0c;\u5728\u6a21\u677f operator&lt;&lt; \u91cc\u8fd8\u6709\u7c7b\u578b\u63a8\u5bfc\u7684\u5751&#xff0c;\u6211\u4e4b\u524d\u88ab\u5b83\u5751\u51fa\u8fc7\u7f16\u8bd1\u9519\u8bef&#xff0c;\u4ece\u6b64\u6211\u7684\u65e5\u5fd7\u6a21\u5757\u4e00\u5f8b\u81ea\u5df1\u7ba1\u6362\u884c\u3002<\/p>\n<p>inline \u7684\u6559\u8bad&#xff1a;Level2Str\u3001GetTimeStamp \u8fd9\u4e24\u4e2a\u81ea\u7531\u51fd\u6570\u548c Logger logger \u8fd9\u4e2a\u5168\u5c40\u5bf9\u8c61&#xff0c;\u90fd\u5b9a\u4e49\u5728\u5934\u6587\u4ef6\u91cc\u3002\u5934\u6587\u4ef6\u4f1a\u88ab\u591a\u4e2a .cpp \u5305\u542b&#xff0c;\u666e\u901a\u51fd\u6570\u548c\u5168\u5c40\u53d8\u91cf\u5728\u6bcf\u4e2a\u7ffb\u8bd1\u5355\u5143\u91cc\u90fd\u4f1a\u751f\u6210\u4e00\u4efd\u5b9a\u4e49&#xff0c;\u94fe\u63a5\u65f6\u76f4\u63a5\u62a5&#034;multiple definition&#034;\u3002\u6211\u4e4b\u524d\u7684\u9879\u76ee\u5c31\u5728\u8fd9\u4e0a\u9762\u5d29\u8fc7\u3002C&#043;&#043;17 \u7684\u89e3\u6cd5\u5f88\u5e72\u51c0&#xff1a;\u5168\u52a0 inline&#xff08;\u53d8\u91cf\u4e5f\u6709 inline \u4e86&#xff09;&#xff0c;\u591a\u4e2a\u7ffb\u8bd1\u5355\u5143\u5171\u4eab\u4e00\u4efd\u3002<\/p>\n<hr \/>\n<h3 id=\"\u56db\u3001socket.hpp\u2014\u2014\u628a-socket-\u7cfb\u7edf\u8c03\u7528\u5305\u6210\u5bf9\u8c61\">\u56db\u3001Socket.hpp\u2014\u2014\u628a socket \u7cfb\u7edf\u8c03\u7528\u5305\u6210\u5bf9\u8c61<\/h3>\n<p>Linux \u7684 socket API \u662f C \u98ce\u683c\u7684&#xff1a;socket() \u8fd4\u56de\u4e2a fd&#xff0c;bind\/listen\/accept \u90fd\u62ff\u8fd9\u4e2a fd \u64cd\u4f5c\u3002\u76f4\u63a5\u5728\u4e1a\u52a1\u4ee3\u7801\u91cc\u88f8\u8c03\u8fd9\u4e9b\u51fd\u6570&#xff0c;\u4ee3\u7801\u4f1a\u6563\u5f97\u5230\u5904\u90fd\u662f\u3002\u6211\u7684\u505a\u6cd5\u662f\u5c01\u88c5\u6210\u7c7b&#xff1a;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"4265\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/09\/20260920232541-6ab06b757d5cc.png\" width=\"1066\" \/><\/p>\n<p>class Socket<br \/>\n{<br \/>\npublic:<br \/>\n    virtual ~Socket() {}<br \/>\n    virtual void SocketOrDie() &#061; 0;<br \/>\n    virtual void BindOrDie(uint16_t port) &#061; 0;<br \/>\n    virtual void ListenOrDie(int backlog) &#061; 0;<br \/>\n    virtual std::shared_ptr&lt;Socket&gt; Accept(InetAddr *client) &#061; 0;<br \/>\n    virtual void Close() &#061; 0;<br \/>\n    virtual int Recv(std::string *out) &#061; 0;<br \/>\n    virtual int Send(const std::string &amp;message) &#061; 0;<br \/>\n    virtual int Connect(const std::string &amp;server_ip, uint16_t port) &#061; 0;<\/p>\n<p>public:<br \/>\n    void BuildTcpSocketMethod(uint16_t port, int backlog &#061; gbacklog)<br \/>\n    {<br \/>\n        SocketOrDie();<br \/>\n        BindOrDie(port);<br \/>\n        ListenOrDie(backlog);<br \/>\n    }<br \/>\n    void BuildTcpClientSocketMethod()<br \/>\n    {<br \/>\n        SocketOrDie();<br \/>\n    }<br \/>\n};<\/p>\n<p>\u8fd9\u662f\u6a21\u677f\u65b9\u6cd5\u6a21\u5f0f&#xff1a;\u57fa\u7c7b\u628a&#034;\u521b\u5efa TCP \u670d\u52a1\u5668 socket \u7684\u56fa\u5b9a\u5957\u8def&#034;&#xff08;\u521b\u5efa\u2192\u7ed1\u5b9a\u2192\u76d1\u542c&#xff09;\u5728 BuildTcpSocketMethod \u91cc\u5b9a\u6b7b&#xff0c;\u5177\u4f53\u6bcf\u4e00\u6b65\u600e\u4e48\u5e72\u4ea4\u7ed9\u5b50\u7c7b\u3002\u73b0\u5728\u53ea\u6709 TcpSocket \u4e00\u4e2a\u5b50\u7c7b&#xff0c;\u4f46\u54ea\u5929\u8981\u52a0 UdpSocket&#xff0c;\u5957\u8def\u662f\u73b0\u6210\u7684\u3002<\/p>\n<p>\u6bcf\u4e2a\u65b9\u6cd5\u540d\u5e26 OrDie \u662f\u6211\u7684\u547d\u540d\u5f3a\u8feb\u75c7&#xff1a;\u8fd9\u4e9b\u64cd\u4f5c\u5931\u8d25\u5c31\u6ca1\u6cd5\u73a9\u4e86&#xff08;bind \u5931\u8d25\u670d\u52a1\u5668\u8d77\u6765\u5e72\u561b&#xff09;&#xff0c;\u76f4\u63a5\u6253 FATAL \u65e5\u5fd7\u7136\u540e exit\u3002\u9519\u8bef\u5206\u7ea7\u5f88\u91cd\u8981&#xff1a;\u80fd\u6551\u7684\u6551&#xff08;accept \u5076\u5c14\u5931\u8d25 return nullptr \u7ee7\u7eed&#xff09;&#xff0c;\u6551\u4e0d\u4e86\u7684\u75db\u5feb\u6b7b&#xff08;bind \u5931\u8d25\u6d3b\u7740\u4e5f\u662f\u6d6a\u8d39\u7535&#xff09;\u3002<\/p>\n<p>TcpSocket \u91cc\u6700\u503c\u5f97\u7ec6\u8bb2\u7684\u662f Recv&#xff1a;<\/p>\n<p>int Recv(std::string *out) override<br \/>\n{<br \/>\n    \/\/ \u6d41\u5f0f\u8bfb\u53d6&#xff0c;\u4e0d\u5173\u5fc3\u8bfb\u5230\u7684\u662f\u4ec0\u4e48<br \/>\n    char buffer[1024];<br \/>\n    ssize_t n &#061; ::recv(_sockfd, buffer, sizeof(buffer) &#8211; 1, 0);<br \/>\n    if (n &gt; 0)<br \/>\n    {<br \/>\n        buffer[n] &#061; 0;<br \/>\n        *out &#043;&#061; buffer; \/\/ \u6545\u610f<br \/>\n    }<br \/>\n    return n;<br \/>\n}<\/p>\n<p>\u56db\u4e2a\u7ec6\u8282&#xff0c;\u5168\u662f TCP \u7684\u672c\u8d28&#xff1a;<\/p>\n<li>\n<p>buffer \u53ea\u5f00 1024&#xff1a;recv \u662f&#034;\u6765\u591a\u5c11\u8200\u591a\u5c11&#034;&#xff0c;\u4e00\u6b21\u8c03\u7528\u6700\u591a\u8200 1023 \u5b57\u8282\u3002\u5927\u62a5\u6587\u8981\u4e0a\u5c42\u5faa\u73af\u8c03\u3002<\/p>\n<\/li>\n<li>\n<p>sizeof(buffer) &#8211; 1&#xff1a;\u7559 1 \u5b57\u8282\u653e \\\\0\u3002<\/p>\n<\/li>\n<li>\n<p>buffer[n] &#061; 0&#xff1a;recv \u4e0d\u5e2e\u4f60\u52a0 \\\\0&#xff0c;\u5b83\u53ea\u8fd4\u56de\u8bfb\u4e86\u591a\u5c11\u5b57\u8282\u3002\u4e0d\u8865 \\\\0 \u540e\u9762\u6309 C \u5b57\u7b26\u4e32\u5904\u7406\u5c31\u8bfb\u8d8a\u754c\u4e86\u3002<\/p>\n<\/li>\n<li>\n<p>*out &#043;&#061; buffer \u662f &#043;&#061; \u4e0d\u662f &#061;&#xff1a;\u8fd9\u662f&#034;\u8ffd\u52a0&#034;\u8bed\u4e49&#xff0c;\u4e0a\u5c42\u591a\u6b21\u8c03\u7528 Recv \u628a\u5b57\u8282\u6d41\u6512\u8d77\u6765\u3002\u6ce8\u610f &#043;&#061; \u4e00\u4e2a char* \u4f1a\u5728\u7b2c\u4e00\u4e2a \\\\0 \u5904\u622a\u65ad\u2014\u2014HTTP \u62a5\u6587\u91cc\u4e0d\u4f1a\u51fa\u73b0 \\\\0 \u6240\u4ee5\u6ca1\u4e8b&#xff0c;\u4f46\u4f20\u4e8c\u8fdb\u5236\u534f\u8bae\u65f6\u8fd9\u5c31\u662f bug&#xff0c;\u5f97\u6362\u6210 out-&gt;append(buffer, n)\u3002<\/p>\n<\/li>\n<p>Accept \u8fd4\u56de std::shared_ptr&lt;Socket&gt; \u800c\u4e0d\u662f\u88f8 fd&#xff1a;<\/p>\n<p>std::shared_ptr&lt;Socket&gt; Accept(InetAddr *client) override<br \/>\n{<br \/>\n    struct sockaddr_in peer;<br \/>\n    socklen_t len &#061; sizeof(peer);<br \/>\n    int fd &#061; ::accept(_sockfd, CONV(peer), &amp;len);<br \/>\n    if (fd &lt; 0)<br \/>\n    {<br \/>\n        LOG(LogLevel::WARNING) &lt;&lt; &#034;accept warning &#8230;&#034;;<br \/>\n        return nullptr;<br \/>\n    }<br \/>\n    client-&gt;SetAddr(peer);<br \/>\n    return std::make_shared&lt;TcpSocket&gt;(fd);<br \/>\n}<\/p>\n<p>\u8fd9\u662f\u4e2a\u5f88\u8212\u670d\u7684\u5c01\u88c5\u8bbe\u8ba1&#xff1a;accept \u51fa\u6765\u7684\u901a\u4fe1 fd \u76f4\u63a5\u5305\u6210\u4e00\u4e2a\u65b0\u7684 TcpSocket \u5bf9\u8c61\u4ea4\u51fa\u53bb&#xff0c;\u8c03\u7528\u65b9\u62ff\u5230\u7684\u5c31\u662f\u4e2a\u80fd\u6536\u80fd\u53d1\u7684\u5b8c\u6574\u5bf9\u8c61\u3002<\/p>\n<p>\u4f46\u6709\u4e2a\u5fc5\u987b\u8bf4\u7834\u7684\u7ec6\u8282&#xff1a;\u8fd9\u7248 TcpSocket \u7684\u6790\u6784\u51fd\u6570\u662f\u7a7a\u7684&#xff0c;\u5e76\u4e0d\u4f1a\u81ea\u52a8 close fd&#xff01;<\/p>\n<p>\u771f\u6b63\u5173 fd \u9760\u4e24\u4ef6\u4e8b&#xff1a;\u4e0a\u5c42\u663e\u5f0f\u8c03 Close()&#xff08;TcpServer \u91cc\u5b59\u5b50\u8fdb\u7a0b\u5e72\u5b8c\u6d3b\u90a3\u6b21&#xff09;&#xff0c;\u4ee5\u53ca\u8fdb\u7a0b\u9000\u51fa\u65f6\u5185\u6838\u515c\u5e95\u56de\u6536\u3002<\/p>\n<p>\u90a3\u4e3a\u4ec0\u4e48\u4e0d\u987a\u624b\u5728\u6790\u6784\u91cc\u52a0\u4e2a close(_sockfd) \u505a\u6210\u5b8c\u5168 RAII&#xff1f;\u53ef\u4ee5&#xff0c;\u4f46\u5fc5\u987b\u914d\u5957\u628a _sockfd \u7f6e\u56de -1\u2014\u2014\u4e0d\u7136\u663e\u5f0f Close() \u5173\u4e00\u6b21\u3001\u6790\u6784\u518d\u5173\u4e00\u6b21\u5c31\u662f double close&#xff1a;fd \u53f7\u4f1a\u88ab\u7cfb\u7edf\u590d\u7528\u5206\u914d\u7ed9\u522b\u4eba&#xff0c;\u7b2c\u4e8c\u4e2a close \u4f1a\u8bef\u4f24\u522b\u4eba\u521a\u6253\u5f00\u7684\u6587\u4ef6&#xff0c;\u8fd9\u79cd bug \u80fd\u628a\u4eba\u903c\u75af\u3002\u8981\u4e48\u7eaf\u663e\u5f0f\u5173&#xff08;\u73b0\u72b6&#xff09;&#xff0c;\u8981\u4e48\u5f7b\u5e95 RAII&#xff08;\u6790\u6784 close &#043; \u7f6e -1&#xff09;&#xff0c;\u6700\u6015\u534a\u540a\u5b50\u3002TcpSocket(int fd) \u8fd9\u4e2a\u6784\u9020\u51fd\u6570\u5c31\u662f\u4e3a Accept \u51c6\u5907\u7684\u3002<\/p>\n<hr \/>\n<h3 id=\"\u4e94\u3001tcpserver.hpp\u2014\u2014fork-\u5e76\u53d1\u6a21\u578b\uff08\u672c\u9879\u76ee\u7684\u8fdb\u7a0b\u620f\u4efd\u5168\u5728\u8fd9\uff09\">\u4e94\u3001TcpServer.hpp\u2014\u2014fork \u5e76\u53d1\u6a21\u578b&#xff08;\u672c\u9879\u76ee\u7684\u8fdb\u7a0b\u620f\u4efd\u5168\u5728\u8fd9&#xff09;<\/h3>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"2246\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/09\/20260920232543-6ab06b774f186.png\" width=\"1265\" \/><\/p>\n<p>\u8fd9\u4e2a\u6587\u4ef6\u662f\u7eaf\u7f51\u7edc\u5c42&#xff0c;\u5bf9 HTTP \u4e00\u65e0\u6240\u77e5\u3002\u5148\u770b\u5b83\u600e\u4e48\u5b9a\u4e49&#034;\u4e1a\u52a1&#034;&#xff1a;<\/p>\n<p>using ioservice_t &#061; std::function&lt;void(std::shared_ptr&lt;Socket&gt; &amp;sock, InetAddr &amp;client)&gt;;<\/p>\n<p>\u4e00\u4e2a std::function&#xff0c;\u53c2\u6570\u662f\u901a\u4fe1 socket \u548c\u5bf9\u7aef\u5730\u5740\u3002TcpServer \u6536\u5230\u8fde\u63a5\u540e\u8c03\u5b83&#xff0c;\u8c03\u7684\u8c01&#xff1f;Http \u4f20\u8fdb\u6765\u7684\u5904\u7406\u51fd\u6570\u3002\u8fd9\u5c31\u662f\u56de\u8c03\u89e3\u8026&#xff1a;TcpServer \u53ea\u7ba1\u63a5\u5ba2&#xff0c;\u63a5\u5b8c\u5ba2\u628a&#034;\u8bdd\u7b52&#034;\u9012\u51fa\u53bb\u3002<\/p>\n<p>\u4e3b\u5faa\u73af\u56db\u6b65\u8d70&#xff1a;<\/p>\n<p>void Start(ioservice_t callback)<br \/>\n{<br \/>\n    _isrunning &#061; true;<br \/>\n    while (_isrunning)<br \/>\n    {<br \/>\n        InetAddr client;<br \/>\n        auto sock &#061; _listensockptr-&gt;Accept(&amp;client); \/\/ 1. \u62ff\u5230\u901a\u4fe1sockfd\u548c\u5bf9\u7aef\u5730\u5740<br \/>\n        if (sock &#061;&#061; nullptr)<br \/>\n        {<br \/>\n            continue;   \/\/ accept\u5076\u53d1\u5931\u8d25&#xff0c;\u4e0d\u65ad\u4e3b&#xff0c;\u7ee7\u7eed\u63a5\u4e0b\u4e00\u4e2a<br \/>\n        }<br \/>\n        LOG(LogLevel::DEBUG) &lt;&lt; &#034;accept success &#8230;&#034; &lt;&lt; client.StringAddr();<br \/>\n        &#8230;fork \u5206\u53d1&#8230;<br \/>\n    }<br \/>\n}<\/p>\n<p>accept \u62ff\u5230\u7684\u662f\u65b0\u7684 fd&#xff08;\u901a\u4fe1 socket&#xff09;&#xff0c;\u548c listen socket \u662f\u4e24\u7801\u4e8b&#xff1a;listensock \u8d1f\u8d23&#034;\u62c9\u5ba2&#034;&#xff0c;sock \u8d1f\u8d23&#034;\u8ddf\u8fd9\u4f4d\u5ba2\u4eba\u5355\u72ec\u804a&#034;\u3002\u5206\u4e0d\u6e05\u8fd9\u4fe9\u7684&#xff0c;\u53ef\u4ee5\u60f3\u8c61\u6210\u9910\u5385\u95e8\u53e3\u9886\u4f4d\u7684\u548c\u8fdb\u5305\u95f4\u670d\u52a1\u7684\u4e0d\u662f\u540c\u4e00\u4e2a\u4eba\u3002<\/p>\n<p>\u7136\u540e\u662f\u91cd\u5934\u620f&#xff0c;fork \u4e09\u5206\u652f\u3002\u6211\u628a\u6bcf\u4e2a\u5206\u652f&#034;\u8c01\u6d3b\u7740\u3001\u8c01\u5173\u4ec0\u4e48&#034;\u6807\u6e05\u695a&#xff1a;<\/p>\n<p>pid_t id &#061; fork();<br \/>\nif (id &lt; 0)<br \/>\n{<br \/>\n    LOG(LogLevel::FATAL) &lt;&lt; &#034;fork error &#8230;&#034;;<br \/>\n    exit(FORK_ERR);<br \/>\n}<br \/>\nelse if (id &#061;&#061; 0)<br \/>\n{<br \/>\n    \/\/ &#8212;- \u5b50\u8fdb\u7a0b &#8212;-<br \/>\n    _listensockptr-&gt;Close();     \/\/ (1) \u5b50\u8fdb\u7a0b\u4e0d\u62c9\u5ba2&#xff0c;\u5173\u6389listensock<br \/>\n    if (fork() &gt; 0)              \/\/ (2) \u4e8c\u6b21fork<br \/>\n        exit(OK);                \/\/     \u5b50\u8fdb\u7a0b\u81ea\u5df1\u9000\u51fa&#xff0c;\u628a\u6d3b\u7559\u7ed9\u5b59\u5b50<br \/>\n    callback(sock, client);      \/\/ (3) \u5b59\u5b50\u8fdb\u7a0b\u5e72\u6d3b<br \/>\n    sock-&gt;Close();<br \/>\n    exit(OK);<br \/>\n}<br \/>\nelse<br \/>\n{<br \/>\n    \/\/ &#8212;- \u7236\u8fdb\u7a0b &#8212;-<br \/>\n    sock-&gt;Close();               \/\/ (4) \u7236\u8fdb\u7a0b\u4e0d\u804a\u5929&#xff0c;\u5173\u6389\u901a\u4fe1sock<br \/>\n    pid_t rid &#061; ::waitpid(id, nullptr, 0);  \/\/ (5) \u7b49\u513f\u5b50\u9000\u51fa<br \/>\n    (void)rid;<br \/>\n}<\/p>\n<p>\u5173\u952e\u70b9&#xff0c;\u4e00\u4e2a\u90fd\u4e0d\u80fd\u542b\u7cca&#xff1a;<\/p>\n<p>(1) \u5b50\u8fdb\u7a0b\u4e3a\u4ec0\u4e48\u5173 listensock&#xff1f; fork \u51fa\u6765\u7684\u5b50\u8fdb\u7a0b\u7ee7\u627f\u7236\u8fdb\u7a0b\u6240\u6709 fd&#xff0c;\u5305\u62ec listensock\u3002\u5b50\u8fdb\u7a0b\u53ea\u9700\u8981\u4f3a\u5019\u8fd9\u4e00\u4e2a\u8fde\u63a5&#xff0c;listensock \u5728\u5b83\u624b\u91cc\u7eaf\u5c5e\u591a\u4f59\u2014\u2014\u4e0d\u5173\u7684\u8bdd&#xff0c;\u4e07\u4e00\u5b50\u8fdb\u7a0b\u4e5f\u53bb accept&#xff0c;\u4e00\u4e2a\u8fde\u63a5\u53ef\u80fd\u88ab\u5b83\u62a2\u8d70&#xff0c;\u800c\u4e14\u6bcf\u4e2a\u5b50\u8fdb\u7a0b\u90fd\u6525\u7740 listensock \u7684\u5f15\u7528&#xff0c;fd \u8ba1\u6570\u4e71\u7cdf\u7cdf\u3002<\/p>\n<p>(2) \u4e3a\u4ec0\u4e48\u8981 fork \u4e24\u6b21&#xff1f; \u8fd9\u662f\u8fd9\u4e2a\u6a21\u578b\u6700\u7cbe\u5999\u7684\u8bbe\u8ba1\u3002<\/p>\n<p>\u5982\u679c\u53ea fork \u4e00\u6b21&#xff1a;\u7236\u8fdb\u7a0b\u8981\u4e48 waitpid \u7b49\u5b50\u8fdb\u7a0b\u5904\u7406\u5b8c\u4e1a\u52a1&#xff08;\u4e1a\u52a1\u6162\u5c31\u963b\u585e\u4e86 accept&#xff0c;\u670d\u52a1\u5668&#034;\u5361\u4f4f&#034;&#xff09;&#xff0c;\u8981\u4e48\u8bbe SIG_IGN\/\u4fe1\u53f7\u5904\u7406\u56de\u6536&#xff08;\u4ee3\u7801\u53c8\u591a\u4e00\u4efd&#xff09;\u3002<\/p>\n<p>\u4e8c\u6b21 fork \u7684\u601d\u8def\u662f&#xff1a;\u513f\u5b50 fork \u5b8c\u7acb\u523b\u9000\u51fa&#xff0c;\u771f\u6b63\u5e72\u6d3b\u7684\u5b59\u5b50\u53d8\u6210\u5b64\u513f&#xff0c;\u88ab 1 \u53f7\u8fdb\u7a0b&#xff08;init\/systemd&#xff09;\u9886\u517b&#xff0c;\u5b59\u5b50\u9000\u51fa\u540e\u7531 1 \u53f7\u8fdb\u7a0b\u81ea\u52a8\u6536\u5272\u3002\u7236\u8fdb\u7a0b waitpid \u7b49\u7684\u662f\u513f\u5b50\u2014\u2014\u513f\u5b50 fork \u5b8c\u5c31\u9000&#xff0c;waitpid \u77ac\u95f4\u8fd4\u56de&#xff0c;\u4e3b\u5faa\u73af\u7acb\u523b\u56de\u53bb accept \u4e0b\u4e00\u4e2a\u5ba2\u4eba\u3002\u5904\u7406\u8017\u65f6\u7684\u4e1a\u52a1\u88ab\u5b8c\u5168\u7529\u7ed9\u4e86\u5b64\u513f\u8fdb\u7a0b\u3002<\/p>\n<p>\u4e00\u53e5\u8bdd&#xff1a;waitpid \u53ea\u7b49&#034;\u4ea4\u63a5\u73ed&#034;&#xff0c;\u4e0d\u7b49&#034;\u5e72\u5b8c\u6d3b&#034;\u3002<\/p>\n<p>(3) \u5b59\u5b50\u8fdb\u7a0b\u5e72\u5b8c\u6d3b\u7684\u6536\u5c3e&#xff1a;callback \u8dd1\u5b8c sock-&gt;Close() \u518d exit(OK)\u3002\u5176\u5b9e\u5b64\u513f\u8fdb\u7a0b\u9000\u51fa\u65f6\u5185\u6838\u540c\u6837\u4f1a\u56de\u6536 fd&#xff0c;\u8fd9\u4e24\u884c\u66f4\u50cf&#034;\u597d\u4e60\u60ef\u7684\u4eea\u5f0f\u611f&#034;\u2014\u2014\u4e07\u4e00\u4ee5\u540e\u4e1a\u52a1\u51fd\u6570\u91cc\u8fd8\u6709\u522b\u7684\u4ee3\u7801\u8def\u5f84&#xff0c;\u663e\u5f0f\u5173\u603b\u662f\u4e0d\u5403\u4e8f\u7684\u3002<\/p>\n<p>(4) \u7236\u8fdb\u7a0b\u4e3a\u4ec0\u4e48\u5173 sock&#xff1f; \u540c\u7406\u53cd\u4e00\u4e0b&#xff1a;\u7236\u8fdb\u7a0b\u53ea\u7ba1\u62c9\u5ba2\u3002\u901a\u4fe1 sock \u4e0d\u5173&#xff0c;\u6bcf\u6765\u4e00\u4e2a\u8fde\u63a5\u7236\u8fdb\u7a0b\u5c31\u591a\u6525\u4e00\u4e2a fd&#xff0c;\u8fde\u63a5\u4e00\u591a\u76f4\u63a5\u628a\u8fdb\u7a0b\u7684 fd \u4e0a\u9650\u8017\u5149&#xff08;ulimit -n&#xff0c;\u9ed8\u8ba4 1024&#xff09;\u3002fork \u6a21\u578b\u7684\u94c1\u5f8b&#xff1a;\u4e0d\u7528\u7684 fd \u7acb\u523b\u5173&#xff0c;\u7236\u5b50\u5404\u5173\u5404\u7684\u3002<\/p>\n<p>(5) waitpid \u963b\u585e\u5728\u4e3b\u5faa\u73af\u91cc&#xff0c;\u4e0d\u614c\u5417&#xff1f; \u614c\u7684\u65f6\u5019\u624d\u9700\u8981\u4fe1\u53f7\u65b9\u6848&#xff0c;\u8fd9\u91cc\u4e0d\u614c\u2014\u2014\u56e0\u4e3a\u513f\u5b50\u6d3b\u5f97\u6781\u77ed&#xff08;fork \u5b8c\u5c31\u9000&#xff09;&#xff0c;waitpid \u5b9e\u9645\u4e0a\u4e0d\u963b\u585e\u3002<\/p>\n<p>\u8fd8\u6709\u4e00\u4e2a\u5bb9\u6613\u6f0f\u7684\u70b9&#xff1a;fork \u5931\u8d25\u5206\u652f\u91cc\u90a3\u4e2a sock \u6ca1 close \u5c31 exit \u4e86\u2014\u2014\u8981\u4e0d\u8981\u7d27&#xff1f;\u4e0d\u8981\u7d27&#xff0c;\u8fdb\u7a0b\u9000\u51fa\u65f6\u5185\u6838\u4f1a\u56de\u6536\u8be5\u8fdb\u7a0b\u6240\u6709\u7684 fd&#xff0c;\u8fd9\u662f\u5185\u6838\u7684\u515c\u5e95&#xff0c;\u4e0d\u662f\u4f60\u4e0d\u7528\u7ba1&#xff0c;\u662f\u5185\u6838\u66ff\u4f60\u7ba1\u4e86\u3002<\/p>\n<hr \/>\n<h3 id=\"\u516d\u3001util.hpp\u2014\u2014\u4e09\u4e2a\u7eaf\u5de5\u5177\u51fd\u6570\">\u516d\u3001Util.hpp\u2014\u2014\u4e09\u4e2a\u7eaf\u5de5\u5177\u51fd\u6570<\/h3>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"2322\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/09\/20260920232544-6ab06b78a55ad.png\" width=\"1381\" \/><\/p>\n<h4 id=\"6.1-readfilecontent\uff1a\u8bfb\u6587\u4ef6\u7684\u4e24\u4e2a\u5751\">6.1 ReadFileContent&#xff1a;\u8bfb\u6587\u4ef6\u7684\u4e24\u4e2a\u5751<\/h4>\n<p>static bool ReadFileContent(const std::string &amp;filename, std::string *out)<br \/>\n{<br \/>\n    int filesize &#061; FileSize(filename);<br \/>\n    if(filesize &gt; 0)<br \/>\n    {<br \/>\n        std::ifstream in(filename, std::ios::binary);<br \/>\n        if(!in.is_open())<br \/>\n            return false;<br \/>\n        out-&gt;resize(filesize);<br \/>\n        in.read(out-&gt;data(), filesize);<br \/>\n        in.close();<br \/>\n    }<br \/>\n    else<br \/>\n    {<br \/>\n        return false;<br \/>\n    }<br \/>\n    return true;<br \/>\n}<\/p>\n<p>\u6d41\u7a0b&#xff1a;\u5148\u95ee\u6587\u4ef6\u591a\u5927 \u2192 \u4e00\u6b21\u6027 resize \u597d\u5185\u5b58 \u2192 \u4e00\u53e3\u6c14\u8bfb\u8fdb\u6765\u3002<\/p>\n<p>\u6ce8\u91ca\u91cc\u6211\u7559\u4e86 version1 \u7684\u5bf9\u7167&#xff08;\u9010\u884c getline&#xff09;&#xff0c;\u5b83\u6709\u4e2a\u81f4\u547d\u95ee\u9898&#xff1a;\u6309\u884c\u8bfb\u4f1a\u4e22\u6362\u884c\u7b26&#xff0c;\u800c\u4e14\u662f\u6587\u672c\u6a21\u5f0f\u3002HTTP \u8981\u56de\u7684\u53ef\u80fd\u662f\u56fe\u7247\u3001\u89c6\u9891&#xff0c;\u4efb\u4f55&#034;\u6309\u884c&#034;\u7684\u5047\u8bbe\u90fd\u662f\u9519\u7684&#xff0c;\u4e8c\u8fdb\u5236\u5fc5\u987b\u6574\u5757\u8bfb\u3002<\/p>\n<p>\u57511&#xff1a;std::ios::binary \u5fc5\u987b\u52a0\u3002\u8fd9\u7248\u4ee3\u7801\u539f\u6765\u6ca1\u52a0\u2014\u2014\u6ce8\u91ca\u5199\u7740&#034;\u4ee5\u4e8c\u8fdb\u5236\u65b9\u5f0f\u8fdb\u884c\u8bfb\u53d6&#034;&#xff0c;\u6253\u5f00\u5374\u9ed8\u8ba4\u6587\u672c\u6a21\u5f0f\u3002Linux \u4e0a\u4fa5\u5e78\u6ca1\u4e8b&#xff08;Linux \u4e0d\u533a\u5206\u6587\u672c\/\u4e8c\u8fdb\u5236\u6a21\u5f0f&#xff09;&#xff0c;Windows \u4e0a\u8bfb PNG \u4f1a\u628a \\\\r\\\\n \u505a\u8f6c\u6362&#xff0c;\u56fe\u7247\u76f4\u63a5\u635f\u574f\u3002\u4ee3\u7801\u610f\u56fe\u548c\u5b9e\u73b0\u5fc5\u987b\u4e00\u81f4&#xff0c;\u4fa5\u5e78\u2260\u6b63\u786e\u3002<\/p>\n<p>\u57512&#xff1a;\u522b\u5bf9 c_str() \u5f3a\u8f6c\u5199\u5165\u3002\u539f\u4ee3\u7801\u662f in.read((char*)(out-&gt;c_str()), filesize)\u2014\u2014c_str() \u8fd4\u56de const char*&#xff0c;\u5f3a\u8f6c\u6389 const \u5f80\u91cc\u5199\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002C&#043;&#043;17 \u91cc string::data() \u8fd4\u56de\u7684\u5c31\u662f\u975e const \u6307\u9488&#xff0c;\u5149\u660e\u6b63\u5927\u5730\u7528\u3002<\/p>\n<hr \/>\n<h4 id=\"6.2-readoneline\uff1a\u6574\u4e2a-http-\u89e3\u6790\u7684\u5207\u884c\u6838\u5fc3\">6.2 ReadOneLine&#xff1a;\u6574\u4e2a HTTP \u89e3\u6790\u7684\u5207\u884c\u6838\u5fc3<\/h4>\n<p>static bool ReadOneLine(std::string &amp;bigstr, std::string *out, const std::string &amp;sep\/*\\\\r\\\\n*\/)<br \/>\n{<br \/>\n    auto pos &#061; bigstr.find(sep);<br \/>\n    if(pos &#061;&#061; std::string::npos)<br \/>\n        return false;<\/p>\n<p>    *out &#061; bigstr.substr(0, pos);<br \/>\n    bigstr.erase(0, pos &#043; sep.size());<br \/>\n    return true;<br \/>\n}<\/p>\n<p>\u903b\u8f91\u4e09\u884c&#xff1a;\u627e\u5206\u9694\u7b26 \u2192 \u5207\u51fa\u524d\u534a\u6bb5 \u2192 \u628a\u5207\u8d70\u7684&#xff08;\u8fde\u540c\u5206\u9694\u7b26&#xff09;\u4ece\u6e90\u4e32\u91cc\u5220\u6389\u3002<\/p>\n<p>\u5999\u5728 bigstr \u662f\u5f15\u7528\u4f20\u5165\u3001\u539f\u5730\u7f29\u51cf&#xff1a;\u6bcf\u8c03\u4e00\u6b21&#xff0c;&#034;\u5403\u6389&#034;\u4e00\u884c&#xff0c;\u5269\u4e0b\u7684\u5185\u5bb9\u8fd8\u5728 bigstr \u91cc\u3002\u4e0a\u5c42\u5faa\u73af\u8c03\u5b83\u5c31\u80fd\u628a\u62a5\u6587\u9010\u884c\u5265\u5f00\u3002\u8fd4\u56de false \u610f\u5473\u7740&#034;\u627e\u4e0d\u5230 \\\\r\\\\n \u4e86&#034;\u2014\u2014\u5bf9\u8bf7\u6c42\u884c\u89e3\u6790\u6765\u8bf4\u5c31\u662f\u62a5\u6587\u6b8b\u7f3a&#xff0c;\u4e0a\u5c42\u76f4\u63a5\u653e\u5f03\u3002<\/p>\n<hr \/>\n<h4 id=\"6.3-filesize\uff1aseekg\/tellg-\u7ec4\u5408\u62f3\">6.3 FileSize&#xff1a;seekg\/tellg \u7ec4\u5408\u62f3<\/h4>\n<p>static int FileSize(const std::string &amp;filename)<br \/>\n{<br \/>\n    std::ifstream in(filename, std::ios::binary);<br \/>\n    if(!in.is_open())<br \/>\n        return -1;<br \/>\n    in.seekg(0, in.end);    \/\/ \u6587\u4ef6\u6307\u9488\u7529\u5230\u7ed3\u5c3e<br \/>\n    int filesize &#061; in.tellg(); \/\/ \u95ee\u5f53\u524d\u4f4d\u7f6e&#061;\u7b2c\u51e0\u5b57\u8282&#xff0c;\u5c31\u662f\u6587\u4ef6\u5927\u5c0f<br \/>\n    in.seekg(0, in.beg);    \/\/ \u62e8\u56de\u5f00\u5934<br \/>\n    in.close();<br \/>\n    return filesize;<br \/>\n}<\/p>\n<p>\u539f\u7406\u5c31\u50cf\u95ee\u4f60&#034;\u8fd9\u672c\u4e66\u591a\u539a&#034;\u2014\u2014\u628a\u4e66\u7b7e\u7ffb\u5230\u6700\u540e\u4e00\u9875&#xff0c;\u770b\u9875\u7801\u3002seekg \u79fb\u52a8\u8bfb\u6307\u9488&#xff0c;tellg \u62a5\u544a\u5f53\u524d\u4f4d\u7f6e&#xff0c;\u4e00\u53bb\u4e00\u56de\u62ff\u5230\u5b57\u8282\u6570\u3002\u6253\u4e0d\u5f00\u6587\u4ef6\u8fd4\u56de -1&#xff0c;\u8c03\u7528\u65b9\u636e\u6b64\u8d70 404 \u903b\u8f91\u3002<\/p>\n<hr \/>\n<h3 id=\"\u4e03\u3001http.hpp\u2014\u2014\u6b63\u620f\uff1a\u62a5\u6587\u7684\u89e3\u6790\u4e0e\u7ec4\u88c5\">\u4e03\u3001Http.hpp\u2014\u2014\u6b63\u620f&#xff1a;\u62a5\u6587\u7684\u89e3\u6790\u4e0e\u7ec4\u88c5<\/h3>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"10768\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/09\/20260920232546-6ab06b7a0f896.png\" width=\"1175\" \/><\/p>\n<p>\u8fd9\u4e2a\u6587\u4ef6\u662f\u5e94\u7528\u5c42\u6838\u5fc3&#xff0c;\u6211\u62c6\u6210\u56db\u5757\u8bb2&#xff1a;\u8bf7\u6c42\u89e3\u6790\u3001\u54cd\u5e94\u7ec4\u88c5\u3001\u8def\u7531\u5206\u53d1\u3001\u670d\u52a1\u5668\u7ec4\u88c5\u3002<\/p>\n<h4 id=\"7.1-httprequest\uff1a\u628a\u8bf7\u6c42\u884c\u56bc\u788e\">7.1 HttpRequest&#xff1a;\u628a\u8bf7\u6c42\u884c\u56bc\u788e<\/h4>\n<p>class HttpRequest<br \/>\n{<br \/>\npublic:<br \/>\n    HttpRequest() : _is_interact(false) {}<br \/>\n    &#8230;<br \/>\nprivate:<br \/>\n    std::string _method;<br \/>\n    std::string _uri;<br \/>\n    std::string _version;<\/p>\n<p>    std::unordered_map&lt;std::string, std::string&gt; _headers;<br \/>\n    std::string _blankline;<br \/>\n    std::string _text;<\/p>\n<p>    std::string _args;      \/\/ ?\u540e\u9762\u7684\u53c2\u6570<br \/>\n    bool _is_interact;      \/\/ \u662f\u5426\u662f\u5e26\u53c2\u6570\u7684\u52a8\u6001\u4ea4\u4e92\u8bf7\u6c42<br \/>\n};<\/p>\n<p>_is_interact \u662f\u7406\u89e3\u8fd9\u4e2a\u7c7b\u8bbe\u8ba1\u7684\u94a5\u5319&#xff1a;\u8bf7\u6c42\u5206\u4e24\u7c7b\u2014\u2014\u9759\u6001\u8bf7\u6c42&#xff08;\u8981\u4e2a\u7f51\u9875\/\u56fe\u7247&#xff0c;\u56de\u6587\u4ef6\u5c31\u884c&#xff09;\u548c\u52a8\u6001\u8bf7\u6c42&#xff08;\/login?username&#061;xxx \u8fd9\u79cd\u8981\u8dd1\u4ee3\u7801\u7684&#xff09;\u3002\u533a\u522b\u5c31\u662f URI \u91cc\u6709\u6ca1\u6709 ?\u3002<\/p>\n<p>\u53cd\u5e8f\u5217\u5316\u7684\u4e3b\u5e72&#xff1a;<\/p>\n<p>bool Deserialize(std::string &amp;reqstr)<br \/>\n{<br \/>\n    \/\/ 1. \u63d0\u53d6\u8bf7\u6c42\u884c&#xff1a;\u4ecereqstr\u91cc\u6309\\\\r\\\\n\u5207\u4e0b\u7b2c\u4e00\u884c<br \/>\n    std::string reqline;<br \/>\n    bool res &#061; Util::ReadOneLine(reqstr, &amp;reqline, glinespace);<br \/>\n    if (!res) \/\/ \u8fde\u8bf7\u6c42\u884c\u90fd\u5207\u4e0d\u51fa\u6765&#xff0c;\u8bf4\u660e\u62a5\u6587\u662f\u7a7a\u7684\/\u6b8b\u7f3a\u7684<br \/>\n        return false;<br \/>\n    LOG(LogLevel::DEBUG) &lt;&lt; reqline;<\/p>\n<p>    \/\/ 2. \u5bf9\u8bf7\u6c42\u884c\u8fdb\u884c\u53cd\u5e8f\u5217\u5316<br \/>\n    ParseReqLine(reqline);<\/p>\n<p>ParseReqLine \u7528 stringstream \u4e00\u884c\u641e\u5b9a\u4e09\u4e2a\u5b57\u6bb5&#xff1a;<\/p>\n<p>void ParseReqLine(std::string &amp;reqline)<br \/>\n{<br \/>\n    \/\/ GET \/ HTTP\/1.1<br \/>\n    std::stringstream ss(reqline);<br \/>\n    ss &gt;&gt; _method &gt;&gt; _uri &gt;&gt; _version;<br \/>\n}<\/p>\n<p>&gt;&gt; \u6309\u7a7a\u767d\u5207&#xff0c;\u6b63\u597d\u5bf9\u5e94&#034;\u65b9\u6cd5 \u7a7a\u683c URI \u7a7a\u683c \u7248\u672c&#034;\u7684\u683c\u5f0f\u2014\u2014\u7528\u683c\u5f0f\u672c\u8eab\u7684\u89c4\u5f8b\u7701\u6389\u624b\u5199\u5207\u5206&#xff0c;\u8fd9\u662f C&#043;&#043; \u5904\u7406\u5b9a\u5f0f\u6587\u672c\u7684\u60ef\u7528\u62db\u3002<\/p>\n<p>\u63a5\u7740\u662f URI \u7684\u89c4\u6574\u548c\u53c2\u6570\u5265\u79bb&#xff1a;<\/p>\n<p>if (_uri &#061;&#061; &#034;\/&#034;)<br \/>\n    _uri &#061; webroot &#043; _uri &#043; homepage; \/\/ .\/wwwroot\/index.html<br \/>\nelse<br \/>\n    _uri &#061; webroot &#043; _uri; \/\/ .\/wwwroot\/a\/b\/c.html<br \/>\n&#8230;<br \/>\nconst std::string temp &#061; &#034;?&#034;;<br \/>\nauto pos &#061; _uri.find(temp);<br \/>\nif (pos &#061;&#061; std::string::npos)<br \/>\n{<br \/>\n    return true;   \/\/ \u6ca1\u6709?&#xff0c;\u7eaf\u9759\u6001\u8bf7\u6c42<br \/>\n}<br \/>\n_args &#061; _uri.substr(pos &#043; temp.size()); \/\/ username&#061;zhangsan&amp;password&#061;123456<br \/>\n_uri &#061; _uri.substr(0, pos);             \/\/ .\/wwwroot\/login<br \/>\n_is_interact &#061; true;<\/p>\n<p>\u4e24\u4e2a\u8bbe\u8ba1\u70b9&#xff1a;<\/p>\n<li>\n<p>\u6d4f\u89c8\u5668\u8bf7\u6c42 \/ \u65f6\u8865\u4e0a\u9ed8\u8ba4\u9996\u9875\u3002\u7528\u6237\u8bbf\u95ee http:\/\/ip:8080\/&#xff0c;URI \u662f \/&#xff0c;\u4f60\u603b\u4e0d\u80fd\u56de\u4e00\u53e5&#034;\u4f60\u8981\u5565\u6587\u4ef6\u554a&#034;&#xff0c;\u7ea6\u5b9a\u4fd7\u6210\u56de index.html\u3002<\/p>\n<\/li>\n<li>\n<p>URI \u52a0\u4e0a webroot \u524d\u7f00\u53d8\u6210\u78c1\u76d8\u8def\u5f84\u3002\u6d4f\u89c8\u5668\u8bf4 \/index.html&#xff0c;\u90a3\u662f\u76f8\u5bf9 Web \u6839\u76ee\u5f55\u7684\u903b\u8f91\u8def\u5f84&#xff0c;\u670d\u52a1\u5668\u7ffb\u8bd1\u6210 .\/wwwroot\/index.html \u624d\u77e5\u9053\u53bb\u54ea\u8bfb\u3002\u8fd9\u4e2a\u524d\u7f00\u540c\u65f6\u6321\u4f4f\u4e86\u76f4\u63a5\u8bfb\u7cfb\u7edf\u6587\u4ef6\u7684\u4f01\u56fe\u2014\u2014\u4f20 \/etc\/passwd \u62fc\u51fa\u6765\u662f .\/wwwroot\/etc\/passwd&#xff0c;\u8bfb\u4e0d\u5230\u3002<\/p>\n<\/li>\n<p>\u4f46\u8fd8\u6ca1\u5b8c&#xff1a;\u4f20 \/..\/..\/etc\/passwd \u8fd9\u79cd\u7a7f\u8d8a\u8def\u5f84&#xff0c;.\/wwwroot\/..\/.. \u5c31\u8df3\u56de\u4e86\u7cfb\u7edf\u6839\u76ee\u5f55&#xff0c;\u7167\u6837\u628a\u7cfb\u7edf\u6587\u4ef6\u8bfb\u8d70&#xff08;\u8def\u5f84\u89c4\u8303\u5316\u5fc5\u987b\u5728\u62fc\u63a5\u524d\u505a&#xff0c;\u8fd9\u7248\u4ee3\u7801\u8fd8\u6ca1\u505a&#xff0c;\u5c5e\u4e8e\u5df2\u77e5\u5f85\u529e&#xff09;\u2014\u2014Web \u5b89\u5168\u6c38\u8fdc\u662f\u653b\u9632\u535a\u5f08&#xff0c;\u6321\u4e00\u5c42\u4e0d\u591f\u3002<\/p>\n<p>\u5e26 ? \u7684\u8bf7\u6c42&#xff0c;? \u540e\u9762\u5c31\u662f\u53c2\u6570&#xff08;query string&#xff09;&#xff0c;\u683c\u5f0f key&#061;value&amp;key&#061;value&#xff0c;\u5265\u51fa\u6765\u5b58 _args&#xff0c;\u7559\u7ed9\u4e1a\u52a1\u51fd\u6570\u5904\u7406\u3002<\/p>\n<p>\u5df2\u77e5\u7b80\u5316&#xff08;\u6ce8\u91ca\u91cc\u6211\u4e5f\u5199\u4e86&#xff09;&#xff1a;\u8fd9\u7248\u53ea\u89e3\u6790\u4e86\u8bf7\u6c42\u884c&#xff0c;header \u548c body \u6ca1\u8bfb\u3002\u5bf9 GET \u53d6\u9759\u6001\u9875\u591f\u7528&#xff1b;\u8981\u505a POST \u62ff body&#xff0c;\u5f97\u7ee7\u7eed\u6309 \\\\r\\\\n \u5265 header&#xff0c;\u627e\u5230 Content-Length \u518d\u6309\u957f\u5ea6\u8bfb body\u3002<\/p>\n<hr \/>\n<h4 id=\"7.2-httpresponse\uff1a\u628a\u54cd\u5e94\u62fc\u51fa\u6765\">7.2 HttpResponse&#xff1a;\u628a\u54cd\u5e94\u62fc\u51fa\u6765<\/h4>\n<p>HttpResponse() : _version(&#034;HTTP\/1.0&#034;), _code(200), _desc(&#034;OK&#034;), _blankline(glinespace)<br \/>\n{<br \/>\n}<\/p>\n<p>\u5148\u770b\u6784\u9020\u51fd\u6570\u2014\u2014\u8fd9\u884c\u662f\u6211\u6539\u51fa\u6765\u7684\u8840\u6cea&#xff1a;_code \u662f int&#xff0c;\u4e0d\u521d\u59cb\u5316\u5c31\u662f\u968f\u673a\u503c\u3002\u539f\u4ee3\u7801\u5168\u9760\u6bcf\u4e2a\u5206\u652f\u8bb0\u5f97\u5148\u8c03 SetCode&#xff0c;\u54ea\u5929\u65b0\u52a0\u4e2a\u5206\u652f\u5fd8\u4e86\u8c03&#xff0c;Serialize \u5c31\u628a\u6808\u4e0a\u7684\u5783\u573e\u6570\u5b57\u5f53\u72b6\u6001\u7801\u53d1\u7ed9\u6d4f\u89c8\u5668&#xff0c;\u90a3\u79cd bug \u80fd\u67e5\u4e00\u4e0b\u5348\u3002\u6784\u9020\u65f6\u7ed9\u9ed8\u8ba4\u503c&#xff0c;\u9632\u5fa1\u6027\u7f16\u7a0b\u4e0d\u4e22\u4eba\u3002<\/p>\n<p>\u5e8f\u5217\u5316\u2014\u2014\u6ce8\u610f\u6ce8\u91ca\u91cc\u90a3\u53e5&#034;\u6210\u719f\u7684 http&#xff0c;\u5e94\u7b54\u505a\u5e8f\u5217\u5316&#xff0c;\u4e0d\u8981\u4f9d\u8d56\u4efb\u4f55\u7b2c\u4e09\u65b9\u5e93&#034;&#xff1a;<\/p>\n<p>std::string Serialize()<br \/>\n{<br \/>\n    std::string status_line &#061; _version &#043; gspace &#043; std::to_string(_code) &#043; gspace &#043; _desc &#043; glinespace;<br \/>\n    std::string resp_header;<br \/>\n    for (auto &amp;header : _headers)<br \/>\n    {<br \/>\n        std::string line &#061; header.first &#043; glinesep &#043; header.second &#043; glinespace;<br \/>\n        resp_header &#043;&#061; line;<br \/>\n    }<br \/>\n    return status_line &#043; resp_header &#043; _blankline &#043; _text;<br \/>\n}<\/p>\n<p>\u7eaf\u5b57\u7b26\u4e32\u62fc\u63a5&#xff1a;\u72b6\u6001\u884c &#043; \u62a5\u5934\u9010\u884c &#043; \u7a7a\u884c &#043; \u6b63\u6587\u3002<\/p>\n<p>\u5bf9\u6bd4\u4e00\u4e0b&#xff1a;\u4e0a\u7bc7\u8ba1\u7b97\u5668\u7684\u8bf7\u6c42\u89e3\u6790\u7528 jsoncpp&#xff0c;\u662f\u56e0\u4e3a\u4e1a\u52a1\u5b57\u6bb5\u662f JSON\u3001\u5d4c\u5957\u7ed3\u6784\u624b\u5207\u5bb9\u6613\u9519&#xff1b;HTTP \u8bf7\u6c42\u884c\u662f&#034;\u7a7a\u683c\u5206\u9694\u7684\u5b9a\u5f0f\u6587\u672c&#034;&#xff0c;stringstream \u5c31\u591f&#xff1b;\u800c\u54cd\u5e94\u5e8f\u5217\u5316\u662f\u6211\u4eec\u751f\u4ea7\u62a5\u6587&#xff0c;\u683c\u5f0f\u5b8c\u5168\u7531\u81ea\u5df1\u63a7\u5236&#xff0c;\u5b57\u7b26\u4e32\u62fc\u63a5\u6700\u8f7b\u91cf\u2014\u2014\u8fd9\u4e5f\u662f\u4f60\u4ee5\u540e\u770b Nginx \u6e90\u7801\u4f1a\u770b\u5230\u7684\u624b\u6cd5\u3002<\/p>\n<p>MakeResponse \u662f\u9759\u6001\u8d44\u6e90\u670d\u52a1\u7684\u7075\u9b42&#xff1a;<\/p>\n<p>bool MakeResponse()<br \/>\n{<br \/>\n    if (_targetfile &#061;&#061; &#034;.\/wwwroot\/favicon.ico&#034;)<br \/>\n    {<br \/>\n        LOG(LogLevel::DEBUG) &lt;&lt; &#034;\u7528\u6237\u8bf7\u6c42: &#034; &lt;&lt; _targetfile &lt;&lt; &#034;\u5ffd\u7565\u5b83&#034;;<br \/>\n        return false;<br \/>\n    }<br \/>\n    if (_targetfile &#061;&#061; &#034;.\/wwwroot\/redir_test&#034;)<br \/>\n    {<br \/>\n        SetCode(301);<br \/>\n        SetHeader(&#034;Location&#034;, &#034;https:\/\/www.qq.com\/&#034;);<br \/>\n        return true;<br \/>\n    }<br \/>\n    int filesize &#061; 0;<br \/>\n    bool res &#061; Util::ReadFileContent(_targetfile, &amp;_text);<br \/>\n    if (!res)<br \/>\n    {<br \/>\n        _text &#061; &#034;&#034;;<br \/>\n        SetCode(404);<br \/>\n        _targetfile &#061; webroot &#043; page_404;<br \/>\n        filesize &#061; Util::FileSize(_targetfile);<br \/>\n        if (filesize &lt;&#061; 0) \/\/ \u8fde404.html\u90fd\u4e0d\u5b58\u5728\u65f6&#xff0c;\u4e0d\u80fd\u628aContent-Length\u5199\u6210-1<br \/>\n            filesize &#061; 0;<br \/>\n        Util::ReadFileContent(_targetfile, &amp;_text);<br \/>\n        SetHeader(&#034;Content-Type&#034;, Uri2Suffix(_targetfile));<br \/>\n        SetHeader(&#034;Content-Length&#034;, std::to_string(filesize));<br \/>\n    }<br \/>\n    else<br \/>\n    {<br \/>\n        SetCode(200);<br \/>\n        filesize &#061; Util::FileSize(_targetfile);<br \/>\n        SetHeader(&#034;Content-Type&#034;, Uri2Suffix(_targetfile));<br \/>\n        SetHeader(&#034;Content-Length&#034;, std::to_string(filesize));<br \/>\n        SetHeader(&#034;Set-Cookie&#034;, &#034;username&#061;zhangsan;&#034;);<br \/>\n    }<br \/>\n    return true;<br \/>\n}<\/p>\n<p>\u56db\u4e2a\u73b0\u8c61\u7ea7\u7684\u903b\u8f91&#xff1a;<\/p>\n<li>\n<p>favicon.ico \u76f4\u63a5\u5ffd\u7565&#xff1a;\u6d4f\u89c8\u5668\u6bcf\u6b21\u8bbf\u95ee\u90fd\u4f1a\u81ea\u52a8\u8bf7\u6c42\u4e00\u6b21 \u7ad9\u70b9\/favicon.ico&#xff08;\u6807\u7b7e\u9875\u5c0f\u56fe\u6807&#xff09;\u3002\u6211\u4eec\u6ca1\u8fd9\u6587\u4ef6&#xff0c;\u4e0d\u7406\u5b83\u5c31\u884c\u2014\u2014\u867d\u7136\u8fd4\u56de false \u610f\u5473\u7740\u8fd9\u4e2a\u8fde\u63a5\u5565\u4e5f\u4e0d\u56de&#xff0c;\u6d4f\u89c8\u5668\u5bf9 favicon \u6709\u81ea\u5df1\u7684\u5bb9\u9519&#xff0c;\u4e0d\u5f71\u54cd\u9875\u9762\u6e32\u67d3&#xff08;\u5b9e\u6d4b\u73b0\u8c61\u89c1\u7b2c\u4e5d\u8282\u73b0\u8c612&#xff09;\u3002<\/p>\n<\/li>\n<li>\n<p>301 \u91cd\u5b9a\u5411&#xff1a;SetCode(301) &#043; SetHeader(&#034;Location&#034;, &#034;https:\/\/www.qq.com\/&#034;)&#xff0c;\u5c31\u8fd9\u4e24\u4e2a\u5934\u3002\u6d4f\u89c8\u5668\u6536\u5230 301&#xff0c;\u770b\u5230 Location&#xff0c;\u4e8c\u8bdd\u4e0d\u8bf4\u8df3\u8f6c\u5230\u65b0\u5730\u5740\u3002\u91cd\u5b9a\u5411\u7684\u672c\u8d28\u5c31\u8fd9\u4e48\u6734\u7d20\u3002<\/p>\n<\/li>\n<li>\n<p>404 \u7684\u515c\u5e95\u903b\u8f91&#xff1a;\u6587\u4ef6\u8bfb\u4e0d\u5230 \u2192 \u6362 404.html \u7684\u5185\u5bb9\u5f53\u6b63\u6587 \u2192 \u72b6\u6001\u7801 404\u3002\u6ce8\u610f\u90a3\u4e2a filesize &lt;&#061; 0 \u7684\u4fdd\u62a4&#xff1a;404.html \u81ea\u5df1\u4e5f\u4e22\u4e86\u7684\u8bdd&#xff0c;FileSize \u8fd4\u56de -1&#xff0c;Content-Length: -1 \u53d1\u51fa\u53bb\u6d4f\u89c8\u5668\u76f4\u63a5\u61f5\u2014\u2014\u62a5\u5934\u6570\u503c\u6c38\u8fdc\u662f\u5bf9\u65b9\u89e3\u6790\u7684\u5bf9\u8c61&#xff0c;\u4e0d\u80fd\u6709\u975e\u6cd5\u503c\u3002<\/p>\n<\/li>\n<li>\n<p>Set-Cookie&#xff1a;\u6210\u529f\u54cd\u5e94\u987a\u624b\u79cd\u4e86\u4e2a cookie\u3002\u6d4f\u89c8\u5668\u4f1a\u5b58\u4e0b\u6765&#xff0c;\u4ee5\u540e\u6bcf\u6b21\u8bf7\u6c42\u81ea\u52a8\u5e26\u4e0a Cookie: username&#061;zhangsan\u2014\u2014HTTP \u672c\u8eab\u65e0\u72b6\u6001&#xff0c;\u4f1a\u8bdd\u4fdd\u6301\u5168\u9760\u8fd9\u5bf9\u914d\u5408\u3002<\/p>\n<\/li>\n<p>Uri2Suffix \u7ba1 MIME \u7c7b\u578b&#xff1a;<\/p>\n<p>if (suffix &#061;&#061; &#034;.html&#034; || suffix &#061;&#061; &#034;.htm&#034;)<br \/>\n    return &#034;text\/html&#034;;<br \/>\nelse if (suffix &#061;&#061; &#034;.jpg&#034;)<br \/>\n    return &#034;image\/jpeg&#034;;<br \/>\nelse if (suffix &#061;&#061; &#034;.png&#034;)<br \/>\n    return &#034;image\/png&#034;;<\/p>\n<p>\u8fd9\u91cc\u6709\u4e2a\u6211\u6293\u51fa\u6765\u7684\u7ecf\u5178 bug&#xff1a;\u539f\u4ee3\u7801\u5199\u7684\u662f suffix &#061;&#061; &#034;png&#034;\u2014\u2014\u5c11\u4e2a\u70b9&#xff0c;\u6c38\u8fdc\u5339\u914d\u4e0d\u4e0a&#xff0c;PNG \u7684 Content-Type \u4e00\u76f4\u662f\u7a7a\u3002substr(pos) \u4ece . \u5f00\u59cb\u5207&#xff0c;\u5207\u51fa\u6765\u7684\u662f .png&#xff0c;\u5b57\u7b26\u4e32\u5339\u914d\u5dee\u4e00\u4e2a\u5b57\u7b26\u90fd\u4e0d\u884c\u3002\u6d4f\u89c8\u5668\u62ff\u5230\u7a7a\u7684 Content-Type \u5c31\u53ea\u80fd\u9760\u731c&#xff08;\u55c5\u63a2&#xff09;&#xff0c;\u731c\u9519\u4e86\u5c31\u5f53\u6587\u672c\u4e0b\u8f7d\u3002\u8fd9\u7c7b bug \u7f16\u8bd1\u5668\u4e0d\u62a5\u3001\u8fd0\u884c\u4e0d\u5d29&#xff0c;\u9875\u9762&#034;\u770b\u8d77\u6765&#034;\u8fd8\u80fd\u5f00&#xff0c;\u6700\u5bb9\u6613\u5b58\u6d3b\u4e0b\u6765\u3002<\/p>\n<p>\u8fd8\u6709 SetHeader \u7684\u8bed\u4e49\u6ce8\u91ca&#xff1a;<\/p>\n<p>\/\/ \u6ce8\u610f\u8bed\u4e49&#xff1a;\u540c\u540dkey\u5df2\u5b58\u5728\u65f6\u4e0d\u8986\u76d6&#xff0c;\u7b2c\u4e8c\u6b21\u8bbe\u7f6e\u4f1a\u88ab\u4e22\u5f03<br \/>\n\/\/ \u60f3\u8986\u76d6\u7684\u8bdd&#xff0c;\u628a\u8fd9\u91cc\u6539\u6210 _headers[key] &#061; value; \u5373\u53ef<\/p>\n<p>&#034;\u5148\u67e5\u518d\u63d2&#034;\u5b9e\u73b0\u7684\u662f\u4e0d\u8986\u76d6\u8bed\u4e49\u3002\u8fd9\u662f\u8bbe\u8ba1\u9009\u62e9&#xff08;\u9632\u6b62\u540e\u9762\u7684\u4ee3\u7801\u8bef\u6539\u5173\u952e\u5934&#xff09;&#xff0c;\u4f46\u4f60\u5fc5\u987b\u77e5\u9053\u5b83\u2014\u2014\u4e0d\u7136\u660e\u660e\u8c03\u4e86 SetHeader \u5374&#034;\u4e0d\u751f\u6548&#034;&#xff0c;\u67e5\u534a\u5929\u67e5\u4e0d\u51fa\u95ee\u9898\u3002<\/p>\n<hr \/>\n<h4 id=\"7.3-\u8def\u7531\u8868-+-\u670d\u52a1\u5668\u7ec4\u88c5\">7.3 \u8def\u7531\u8868 &#043; \u670d\u52a1\u5668\u7ec4\u88c5<\/h4>\n<p>using http_func_t &#061; std::function&lt;void(HttpRequest &amp;req, HttpResponse &amp;resp)&gt;;<\/p>\n<p>class Http<br \/>\n{<br \/>\npublic:<br \/>\n    Http(uint16_t port) : tsvrp(std::make_unique&lt;TcpServer&gt;(port)) {}<\/p>\n<p>    void RegisterService(const std::string name, http_func_t h)<br \/>\n    {<br \/>\n        std::string key &#061; webroot &#043; name; \/\/ .\/wwwroot\/login<br \/>\n        if (_route.find(key) &#061;&#061; _route.end())<br \/>\n        {<br \/>\n            _route.insert(std::make_pair(key, h));<br \/>\n        }<br \/>\n    }<\/p>\n<p>\u8def\u7531\u8868\u5c31\u662f unordered_map&lt;\u8def\u5f84, \u5904\u7406\u51fd\u6570&gt;\u3002\u6ce8\u518c\u65f6\u628a \/login \u4e5f\u62fc\u4e0a webroot \u524d\u7f00\u53d8\u6210 .\/wwwroot\/login\u2014\u2014\u548c\u8bf7\u6c42\u89e3\u6790\u540e\u7684 URI \u540c\u4e00\u5957\u683c\u5f0f&#xff0c;\u67e5\u627e\u624d\u80fd\u5bf9\u4e0a\u3002<\/p>\n<p>\u8fd9\u5c31\u662f&#034;\u6ce8\u518c\u548c\u67e5\u627e\u5fc5\u987b\u7528\u540c\u4e00\u79cd\u5750\u6807\u7cfb&#034;&#xff0c;\u4e24\u8fb9\u5750\u6807\u7cfb\u4e0d\u4e00\u81f4&#xff0c;\u8def\u7531\u6c38\u8fdc 404&#xff0c;\u800c\u4e14\u662f\u90a3\u79cd\u4ee3\u7801\u770b\u7740\u5168\u5bf9\u3001\u5c31\u662f\u8dd1\u4e0d\u901a\u7684 404\u3002<\/p>\n<p>\u6838\u5fc3\u5206\u53d1\u903b\u8f91&#xff1a;<\/p>\n<p>void HandlerHttpRquest(std::shared_ptr&lt;Socket&gt; &amp;sock, InetAddr &amp;client)<br \/>\n{<br \/>\n    std::string httpreqstr;<br \/>\n    \/\/ \u8fd9\u91cc\u5b9e\u9645\u662f&#034;TCP\u7c98\u5305\u95ee\u9898&#034;&#xff1a;HTTP\u62a5\u6587\u4e4b\u95f4\u9760\u7a7a\u884c(\\\\r\\\\n\\\\r\\\\n)\u5206\u754c&#xff0c;\u53earecv\u4e00\u6b21&#xff0c;<br \/>\n    \/\/ \u5927\u7f51\u9875\/\u6162\u7f51\u7edc\u65f6\u53ef\u80fd\u53ea\u6536\u5230\u534a\u4e2a\u62a5\u6587&#xff0c;\u4e5f\u53ef\u80fd\u4e00\u6b21\u6536\u5230\u597d\u51e0\u4e2a\u62a5\u6587<br \/>\n    \/\/ \u5b8c\u6574\u505a\u6cd5&#xff1a;\u5148\u8bfb\u5230\\\\r\\\\n\\\\r\\\\n\u62ff\u5230header&#xff0c;\u89e3\u6790\u51faContent-Length&#xff0c;\u518d\u5faa\u73afrecv\u628abody\u8bfb\u591f<br \/>\n    int n &#061; sock-&gt;Recv(&amp;httpreqstr);<br \/>\n    if (n &gt; 0)<br \/>\n    {<br \/>\n        std::cout &lt;&lt; &#034;##########################&#034; &lt;&lt; std::endl;<br \/>\n        std::cout &lt;&lt; httpreqstr;<br \/>\n        std::cout &lt;&lt; &#034;##########################&#034; &lt;&lt; std::endl;<\/p>\n<p>        HttpRequest req;<br \/>\n        HttpResponse resp;<br \/>\n        if (!req.Deserialize(httpreqstr))<br \/>\n            return;<br \/>\n        if (req.isInteract())<br \/>\n        {<br \/>\n            if (_route.find(req.Uri()) &#061;&#061; _route.end())<br \/>\n            {<br \/>\n                \/\/ \u8def\u7531\u8868\u91cc\u6ca1\u6709\u8fd9\u4e2a\u4ea4\u4e92\u8def\u5f84&#xff1a;\u4e0d\u80fd\u4ec0\u4e48\u90fd\u4e0d\u56de&#xff01;<br \/>\n                \/\/ \u4e0d\u56de\u6570\u636e\u7684\u8bdd&#xff0c;\u6d4f\u89c8\u5668\u4f1a\u4e00\u76f4\u5e72\u7b49\u5230\u8d85\u65f6&#xff0c;\u8868\u73b0\u5c31\u662f\u9875\u9762\u5361\u6b7b\u8f6c\u5708<br \/>\n                resp.SetCode(404);<br \/>\n                std::string text &#061; &#034;&lt;html&gt;&lt;h1&gt;404 Not Found&lt;\/h1&gt;&lt;\/html&gt;&#034;;<br \/>\n                resp.SetHeader(&#034;Content-Type&#034;, &#034;text\/html&#034;);<br \/>\n                resp.SetHeader(&#034;Content-Length&#034;, std::to_string(text.size()));<br \/>\n                resp.SetText(text);<br \/>\n                sock-&gt;Send(resp.Serialize());<br \/>\n            }<br \/>\n            else<br \/>\n            {<br \/>\n                _route[req.Uri()](req, resp);<br \/>\n                std::string response_str &#061; resp.Serialize();<br \/>\n                sock-&gt;Send(response_str);<br \/>\n            }<br \/>\n        }<br \/>\n        else<br \/>\n        {<br \/>\n            resp.SetTargetFile(req.Uri());<br \/>\n            if (resp.MakeResponse())<br \/>\n            {<br \/>\n                std::string response_str &#061; resp.Serialize();<br \/>\n                sock-&gt;Send(response_str);<br \/>\n            }<br \/>\n        }<br \/>\n    }<br \/>\n}<\/p>\n<p>\u8fd9\u6bb5\u91cc\u6700\u503c\u5f97\u5708\u51fa\u6765\u7684\u662f\u4ea4\u4e92\u8def\u5f84\u672a\u6ce8\u518c\u65f6\u7684\u5904\u7406\u3002\u539f\u4ee3\u7801\u90a3\u91cc\u662f\u7a7a\u7684\u2014\u2014\u627e\u5230\u8def\u7531\u8d70\u56de\u8c03&#xff0c;\u627e\u4e0d\u5230\u5c31\u4ec0\u4e48\u90fd\u4e0d\u5e72\u3002TCP \u8fde\u63a5\u8fd8\u5f00\u7740&#xff0c;\u5bf9\u65b9\u5728\u7b49\u54cd\u5e94&#xff0c;\u6211\u4eec\u4e0d\u56de\u4e5f\u4e0d\u5173&#xff0c;\u6d4f\u89c8\u5668\u5c31\u4e00\u76f4\u8f6c\u5708\u7b49\u5230\u8d85\u65f6\u3002\u6211\u5b9e\u6d4b&#xff1a;curl exit 52&#xff08;\u7a7a\u54cd\u5e94&#xff09;\u3002\u4efb\u4f55\u5206\u652f\u90fd\u5fc5\u987b\u7ed9\u5bf9\u65b9\u4e00\u4e2a\u4ea4\u4ee3&#xff0c;\u54ea\u6015\u662f\u4e2a 404\u3002<\/p>\n<p>\u6700\u540e Start \u628a\u81ea\u5df1\u548c TcpServer \u7f1d\u5408&#xff1a;<\/p>\n<p>void Start()<br \/>\n{<br \/>\n    tsvrp-&gt;Start([this](std::shared_ptr&lt;Socket&gt; &amp;sock, InetAddr &amp;client)<br \/>\n                 { this-&gt;HandlerHttpRquest(sock, client); });<br \/>\n}<\/p>\n<p>lambda \u6355\u83b7 this&#xff0c;\u628a Http \u7684\u6210\u5458\u65b9\u6cd5\u5305\u88c5\u6210 TcpServer \u8981\u7684 ioservice_t\u3002\u81f3\u6b64&#xff1a;TcpServer \u7ba1\u8fde\u63a5\u548c\u8fdb\u7a0b&#xff0c;Http \u7ba1\u534f\u8bae&#xff0c;Main.cc \u7ba1\u4e1a\u52a1\u2014\u2014\u4e09\u5c42\u5404\u5e72\u5404\u7684\u3002<\/p>\n<hr \/>\n<h3 id=\"\u516b\u3001main.cc\u2014\u2014\u628a\u6240\u6709\u79ef\u6728\u62fc\u8d77\u6765\">\u516b\u3001Main.cc\u2014\u2014\u628a\u6240\u6709\u79ef\u6728\u62fc\u8d77\u6765<\/h3>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"2638\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/09\/20260920232549-6ab06b7d52322.png\" width=\"1266\" \/><\/p>\n<p>int main(int argc, char *argv[])<br \/>\n{<br \/>\n    if(argc !&#061; 2)<br \/>\n    {<br \/>\n        std::cout &lt;&lt; &#034;Usage: &#034; &lt;&lt; argv[0] &lt;&lt; &#034; port&#034; &lt;&lt; std::endl;<br \/>\n        exit(USAGE_ERR);<br \/>\n    }<br \/>\n    \/\/ \u57511&#xff1a;stoi\u9047\u5230\u975e\u6570\u5b57\u4f1a\u629bstd::invalid_argument&#xff0c;\u8fdb\u7a0b\u76f4\u63a5\u5d29<br \/>\n    \/\/ \u57512&#xff1a;stoi\u8fd4\u56deint&#xff0c;\u8d85\u51fa\u7aef\u53e3\u8303\u56f4\u76f4\u63a5\u585e\u8fdbuint16_t\u4f1a\u88ab\u622a\u65ad(99999-&gt;34463)<br \/>\n    int port_num &#061; 0;<br \/>\n    try<br \/>\n    {<br \/>\n        port_num &#061; std::stoi(argv[1]);<br \/>\n    }<br \/>\n    catch (const std::exception &amp;e)<br \/>\n    {<br \/>\n        std::cout &lt;&lt; &#034;port must be a number! &#034; &lt;&lt; e.what() &lt;&lt; std::endl;<br \/>\n        exit(USAGE_ERR);<br \/>\n    }<br \/>\n    if (port_num &lt; 0 || port_num &gt; 65535)<br \/>\n    {<br \/>\n        std::cout &lt;&lt; &#034;port must be in [0, 65535]!&#034; &lt;&lt; std::endl;<br \/>\n        exit(USAGE_ERR);<br \/>\n    }<br \/>\n    uint16_t port &#061; static_cast&lt;uint16_t&gt;(port_num);<\/p>\n<p>    std::unique_ptr&lt;Http&gt; httpsvr &#061; std::make_unique&lt;Http&gt;(port);<br \/>\n    httpsvr-&gt;RegisterService(&#034;\/login&#034;, Login); \/\/ \u6ce8\u518c\u8def\u7531&#xff1a;uri -&gt; \u5904\u7406\u51fd\u6570<\/p>\n<p>    httpsvr-&gt;Start();<br \/>\n    return 0;<br \/>\n}<\/p>\n<p>\u547d\u4ee4\u884c\u53c2\u6570\u7ed9\u7aef\u53e3\u2014\u2014\u7aef\u53e3\u53f7\u4e0d\u8be5\u5199\u6b7b\u5728\u4ee3\u7801\u91cc&#xff0c;\u4e0d\u7136\u6d4b\u8bd5\u73af\u5883 8080\u3001\u7ebf\u4e0a 80 \u5c31\u5f97\u6539\u4ee3\u7801\u91cd\u7f16\u3002<\/p>\n<p>std::stoi \u8fd9\u5757\u662f\u6211\u52a0\u56fa\u8fc7\u7684&#xff0c;\u4e24\u5751\u90fd\u5b9e\u6d4b\u8fc7&#xff08;\u89c1\u7b2c\u4e5d\u8282\u73b0\u8c616&#xff09;&#xff1a;\u4f20\u5b57\u6bcd\u629b\u5f02\u5e38&#xff1b;\u4f20 99999 \u4e0d\u629b\u5f02\u5e38\u4f46\u585e\u8fdb uint16_t \u9759\u9ed8\u622a\u65ad\u6210 34463&#xff0c;\u670d\u52a1\u5668\u7ed1\u4e86\u4e2a\u83ab\u540d\u5176\u5999\u7684\u7aef\u53e3&#xff0c;\u4f60\u67e5\u534a\u5929&#034;\u4e3a\u4ec0\u4e48 99999 \u8fde\u4e0d\u4e0a&#034;\u3002\u7aef\u53e3\u672c\u8d28\u662f\u4e2a 16 \u4f4d\u65e0\u7b26\u53f7\u6570&#xff0c;\u8303\u56f4 [0, 65535]&#xff0c;\u8fb9\u754c\u5fc5\u987b\u81ea\u5df1\u5b88\u3002<\/p>\n<p>\u4e1a\u52a1\u56de\u8c03 Login&#xff1a;<\/p>\n<p>void Login(HttpRequest &amp;req, HttpResponse &amp;resp)<br \/>\n{<br \/>\n    LOG(LogLevel::DEBUG) &lt;&lt; req.Args() &lt;&lt; &#034;, \u6211\u4eec\u6210\u529f\u8fdb\u5165\u5230\u4e86\u5904\u7406\u6570\u636e\u7684\u903b\u8f91&#034;;<br \/>\n    std::string text &#061; &#034;hello: &#034; &#043; req.Args();<\/p>\n<p>    resp.SetCode(200);<br \/>\n    resp.SetHeader(&#034;Content-Type&#034;,&#034;text\/plain&#034;);<br \/>\n    resp.SetHeader(&#034;Content-Length&#034;, std::to_string(text.size()));<br \/>\n    resp.SetText(text);<br \/>\n}<\/p>\n<p>\u771f\u5b9e\u7684\u4e1a\u52a1\u51fd\u6570\u5c31\u8be5\u8fd9\u4e48\u5e72\u51c0&#xff1a;\u4ece req \u62ff\u53c2\u6570&#xff08;\u8fd9\u91cc\u5077\u61d2\u76f4\u63a5\u56de\u663e&#xff09;&#xff0c;\u5f80 resp \u586b\u72b6\u6001\u7801\u3001\u62a5\u5934\u3001\u6b63\u6587\u3002\u4e1a\u52a1\u4ee3\u7801\u5b8c\u5168\u4e0d\u78b0 socket\u3001\u4e0d\u78b0 recv\/send\u2014\u2014\u7f51\u7edc\u7684\u4e8b TcpServer \u7ba1\u4e86&#xff0c;\u534f\u8bae\u7684\u4e8b Http \u7ba1\u4e86\u3002\u8fd9\u5c31\u662f\u5206\u5c42\u7ed9\u4f60\u7684\u81ea\u7531\u3002<\/p>\n<p>\u6ce8\u610f Content-Length \u5fc5\u987b\u548c text.size() \u4e00\u81f4&#xff0c;\u865a\u6807\u957f\u5ea6\u6d4f\u89c8\u5668\u5c31\u50bb\u7b49\u4e0d\u5b58\u5728\u7684\u5b57\u8282\u3002<\/p>\n<p>Makefile \u5c31\u56db\u884c&#xff0c;\u4e24\u5904\u8bb2\u7a76&#xff1a;<\/p>\n<p># Mutex.hpp\u7528\u4e86pthread_mutex&#xff0c;\u94fe\u63a5\u8981\u5e26-pthread<br \/>\nmyhttp:Main.cc<br \/>\ng&#043;&#043; -o $&#064; $^ -std&#061;c&#043;&#043;17 -pthread<br \/>\n.PHONY:clean<br \/>\nclean:<br \/>\nrm -f myhttp<\/p>\n<p>-std&#061;c&#043;&#043;17&#xff1a;std::filesystem\u3001inline \u53d8\u91cf\u3001string::data() \u975e const \u7248&#xff0c;\u5168\u8981 17\u3002-pthread&#xff1a;\u7f16\u8bd1\u5668\/\u94fe\u63a5\u5668\u9700\u8981\u77e5\u9053\u4f60\u5728\u7528 POSIX \u7ebf\u7a0b\u5e93\u2014\u2014\u4e0d\u52a0\u5728\u67d0\u4e9b\u5e73\u53f0\u4e0a\u80fd\u8fc7&#xff0c;\u67d0\u4e9b\u5e73\u53f0\u4e0a\u8fd0\u884c\u65f6\u70b8&#xff0c;\u522b\u8d4c\u3002<\/p>\n<p>\u8fd8\u6709\u4e2a Makefile \u7684\u6697\u5751&#xff1a;recipe \u884c&#xff08;Tab \u5f00\u5934\u7684\u547d\u4ee4&#xff09;\u91cc\u7684 # \u4f1a\u539f\u6837\u4f20\u7ed9 shell&#xff0c;\u6211\u7b2c\u4e00\u7248\u628a\u6ce8\u91ca\u5199\u5728 g&#043;&#043; \u884c\u5c3e&#xff0c;\u80fd\u8dd1\u4f46\u810f&#xff0c;\u540e\u6765\u632a\u5230\u4e86\u72ec\u7acb\u884c\u3002<\/p>\n<hr \/>\n<h3 id=\"\u4e5d\u3001\u8fd0\u884c\u73b0\u8c61\uff1a\u771f\u8dd1\u8d77\u6765\u662f\u4ec0\u4e48\u6837\">\u4e5d\u3001\u8fd0\u884c\u73b0\u8c61&#xff1a;\u771f\u8dd1\u8d77\u6765\u662f\u4ec0\u4e48\u6837<\/h3>\n<p>\u7f16\u8bd1\u3001\u542f\u52a8&#xff08;-pthread \u5df2\u5c31\u4f4d&#xff09;&#xff1a;<\/p>\n<p>$ make<br \/>\ng&#043;&#043; -o myhttp Main.cc -std&#061;c&#043;&#043;17 -pthread<br \/>\n$ .\/myhttp 8080<br \/>\n[2026-09-19 15:50:36] [INFO] [2778366] [Socket.hpp] [72] &#8211; socket success<br \/>\n[2026-09-19 15:50:36] [INFO] [2778366] [Socket.hpp] [83] &#8211; bind success<br \/>\n[2026-09-19 15:50:36] [INFO] [2778366] [Socket.hpp] [93] &#8211; listen success<\/p>\n<p>\u4e09\u6761\u65e5\u5fd7&#xff0c;\u5bf9\u5e94 BuildTcpSocketMethod \u7684\u4e09\u6b65\u3002[2778366] \u662f\u7236\u8fdb\u7a0b PID\u3002\u670d\u52a1\u5668\u542f\u52a8\u53ea\u5e72\u8fd9\u4e09\u4ef6\u4e8b&#xff0c;\u4e4b\u540e\u6240\u6709\u65e5\u5fd7\u90fd\u662f\u6bcf\u4e2a\u8fde\u63a5\u7684\u5904\u7406\u8fc7\u7a0b\u3002<\/p>\n<h4 id=\"\u73b0\u8c611\uff1acurl-\u9996\u9875\u2014\u2014\u4e00\u4e2a\u5b8c\u6574\u8bf7\u6c42\u7684\u5168\u8fc7\u7a0b\">\u73b0\u8c611&#xff1a;curl \u9996\u9875\u2014\u2014\u4e00\u4e2a\u5b8c\u6574\u8bf7\u6c42\u7684\u5168\u8fc7\u7a0b<\/h4>\n<p>$ curl -s -o \/dev\/null -w &#034;%{http_code} %{size_download}B %{content_type}\\\\n&#034; http:\/\/127.0.0.1:8080\/<br \/>\n200 2872B text\/html<\/p>\n<p>\u670d\u52a1\u7aef\u8fd9\u8fb9\u540c\u65f6\u6253\u51fa\u4e86\u5b8c\u6574\u7684\u4e00\u5957\u65e5\u5fd7&#xff1a;<\/p>\n<p>##########################<br \/>\nGET \/ HTTP\/1.1<br \/>\nHost: 127.0.0.1:8080<br \/>\nUser-Agent: curl\/7.81.0<br \/>\nAccept: *\/*<\/p>\n<p>##########################<br \/>\n[DEBUG] [2778380] [Http.hpp] [54] &#8211; GET \/ HTTP\/1.1        &lt;- \u5e72\u6d3b\u7684\u8fdb\u7a0bPID\u662f2778380&#xff0c;\u4e0d\u662f\u7236\u8fdb\u7a0b2778366<br \/>\n[DEBUG] [2778380] [Http.hpp] [65] &#8211; _uri: .\/wwwroot\/index.html<br \/>\n[DEBUG] [2778380] [Http.hpp] [66] &#8211; _version: HTTP\/1.1<br \/>\n[DEBUG] [2778380] [Http.hpp] [223] &#8211; \u8bfb\u53d6\u6587\u4ef6: .\/wwwroot\/index.html<\/p>\n<p>\u51e0\u4e2a\u73b0\u8c61\u503c\u5f97\u54c1&#xff1a;<\/p>\n<li>\n<p>##### \u5305\u7740\u7684\u539f\u59cb\u62a5\u6587\u5c31\u662f\u6d4f\u89c8\u5668\/curl \u53d1\u6765\u7684\u7b2c\u4e00\u624b\u6570\u636e&#xff0c;\u7a7a\u884c\u8089\u773c\u53ef\u89c1\u2014\u2014\u548c\u7b2c\u4e8c\u8282\u8bb2\u7684\u683c\u5f0f\u56fe\u4e00\u4e00\u5bf9\u4e0a\u3002<\/p>\n<\/li>\n<li>\n<p>\u5904\u7406\u8bf7\u6c42\u7684\u8fdb\u7a0b PID \u662f 2778380&#xff0c;\u542f\u52a8\u65e5\u5fd7\u662f 2778366\u2014\u2014fork \u6a21\u578b\u7684\u76f4\u63a5\u8bc1\u636e&#xff1a;\u7236\u8fdb\u7a0b\u63a5\u5ba2&#xff0c;\u5b64\u513f\u8fdb\u7a0b\u5e72\u6d3b&#xff0c;\u65e5\u5fd7\u91cc\u7684 PID \u4e0d\u4f1a\u9a97\u4eba\u3002<\/p>\n<\/li>\n<li>\n<p>URI \/ \u88ab\u81ea\u52a8\u8865\u6210 .\/wwwroot\/index.html\u2014\u2014\u9ed8\u8ba4\u9996\u9875\u903b\u8f91\u751f\u6548\u3002<\/p>\n<\/li>\n<li>\n<p>\u6ce8\u610f header \u6253\u5370\u987a\u5e8f\u6bcf\u6b21\u53ef\u80fd\u4e0d\u4e00\u6837&#xff08;Set-Cookie \u6709\u65f6\u6392\u5728\u6700\u524d&#xff09;\u2014\u2014\u56e0\u4e3a\u62a5\u5934\u5b58\u5728 unordered_map \u91cc&#xff0c;\u54c8\u5e0c\u8868\u65e0\u5e8f&#xff0c;\u5e8f\u5217\u5316\u65f6\u6309\u904d\u5386\u5e8f\u8f93\u51fa\u3002HTTP \u62a5\u5934\u7684\u987a\u5e8f\u534f\u8bae\u4e0d\u8981\u6c42&#xff0c;\u6d4f\u89c8\u5668\u4e0d\u5728\u4e4e&#xff0c;\u4f46\u5f3a\u8feb\u75c7\u770b\u7740\u96be\u53d7&#xff08;\u60f3\u56fa\u5b9a\u987a\u5e8f\u5c31\u6362 std::map \u6216\u8005 vector&lt;pair&gt;&#xff09;\u3002<\/p>\n<\/li>\n<p>\u5b8c\u6574\u54cd\u5e94\u6293\u51fa\u6765\u770b&#xff1a;<\/p>\n<p>HTTP\/1.0 200 OK<br \/>\nSet-Cookie: username&#061;zhangsan;<br \/>\nContent-Length: 2872<br \/>\nContent-Type: text\/html<\/p>\n<p>\u6211\u8fd8\u505a\u4e86\u4e2a\u5b57\u8282\u7ea7\u6821\u9a8c&#xff1a;Content-Length: 2872&#xff0c;\u5b9e\u9645 body \u4e5f\u662f 2872 \u5b57\u8282&#xff0c;\u5206\u6beb\u4e0d\u5dee\u3002\u957f\u5ea6\u62a5\u5934\u865a\u6807\u662f HTTP \u7684\u5927\u5fcc&#xff0c;\u6d4f\u89c8\u5668\u4f1a\u6309 Content-Length \u8bfb\u6b63\u6587&#xff0c;\u865a\u4e86\u5c31\u6c38\u8fdc\u8bfb\u4e0d\u6ee1\u3002<\/p>\n<hr \/>\n<h4 id=\"\u73b0\u8c612\uff1a\u6d4f\u89c8\u5668\u4f1a\u5077\u5077\u8981-favicon.ico\">\u73b0\u8c612&#xff1a;\u6d4f\u89c8\u5668\u4f1a\u5077\u5077\u8981 favicon.ico<\/h4>\n<p>\u7528 curl \u6a21\u62df\u6d4f\u89c8\u5668\u8865\u4e00\u5200&#xff1a;<\/p>\n<p>$ curl -s -o \/dev\/null -w &#034;%{http_code}\\\\n&#034; &#8211;max-time 2 http:\/\/127.0.0.1:8080\/favicon.ico<br \/>\n000            &lt;- 2\u79d2\u5185\u670d\u52a1\u5668\u4e00\u4e2a\u5b57\u8282\u90fd\u6ca1\u56de<br \/>\n$ echo $?<br \/>\n52             &lt;- curl: Empty reply from server<\/p>\n<p>\u670d\u52a1\u7aef\u65e5\u5fd7&#xff1a;<\/p>\n<p>[DEBUG] [2804378] [Http.hpp] [54] &#8211; GET \/favicon.ico HTTP\/1.1<br \/>\n[DEBUG] [2804378] [Http.hpp] [65] &#8211; _uri: .\/wwwroot\/favicon.ico<br \/>\n[DEBUG] [2804378] [Http.hpp] [193] &#8211; \u7528\u6237\u8bf7\u6c42: .\/wwwroot\/favicon.ico\u5ffd\u7565\u5b83<\/p>\n<p>\u6d4f\u89c8\u5668\u8bbf\u95ee\u4efb\u4f55\u7f51\u7ad9\u90fd\u4f1a\u81ea\u52a8\u5e26\u4e00\u6b21 \/favicon.ico \u8bf7\u6c42&#xff08;\u6807\u7b7e\u9875\u56fe\u6807&#xff09;&#xff0c;\u8fd9\u662f\u6d4f\u89c8\u5668\u884c\u4e3a&#xff0c;\u8ddf\u9875\u9762\u4ee3\u7801\u65e0\u5173\u3002\u6211\u4eec\u9009\u62e9\u5ffd\u7565\u2014\u2014\u6d4f\u89c8\u5668\u5bf9\u8fd9\u4e2a\u8bf7\u6c42\u6709\u81ea\u5df1\u7684\u5bb9\u9519&#xff0c;\u9875\u9762\u7167\u5e38\u6e32\u67d3\u3002\u5982\u679c\u4f60\u5728\u65e5\u5fd7\u91cc\u770b\u5230\u83ab\u540d\u5176\u5999\u7684 favicon \u8bf7\u6c42&#xff0c;\u4e0d\u662f\u8c01\u5728\u653b\u51fb\u4f60&#xff0c;\u662f\u6d4f\u89c8\u5668\u7684\u5c0f\u4e60\u60ef\u3002<\/p>\n<hr \/>\n<h4 id=\"\u73b0\u8c613\uff1a404\u2014\u2014\u515c\u5e95\u9875\u9762\">\u73b0\u8c613&#xff1a;404\u2014\u2014\u515c\u5e95\u9875\u9762<\/h4>\n<p>$ curl -s -o \/dev\/null -w &#034;%{http_code} %{size_download}B\\\\n&#034; http:\/\/127.0.0.1:8080\/no_such.html<br \/>\n404 1506B<\/p>\n<p>\u8bf7\u6c42\u7684\u6587\u4ef6\u4e0d\u5b58\u5728&#xff0c;\u670d\u52a1\u5668\u8bfb wwwroot\/404.html \u5f53\u6b63\u6587\u8fd4\u56de&#xff0c;1506 \u5b57\u8282\u5c31\u662f 404 \u9875\u9762\u7684\u5927\u5c0f\u3002\u670d\u52a1\u7aef WARNING \u65e5\u5fd7&#xff1a;client want get : .\/wwwroot\/no_such.html but not found\u3002<\/p>\n<hr \/>\n<h4 id=\"\u73b0\u8c614\uff1a\u52a8\u6001\u4ea4\u4e92-\/login\">\u73b0\u8c614&#xff1a;\u52a8\u6001\u4ea4\u4e92 \/login<\/h4>\n<p>$ curl -s &#034;http:\/\/127.0.0.1:8080\/login?username&#061;zhangsan&amp;password&#061;123456&#034;<br \/>\nhello: username&#061;zhangsan&amp;password&#061;123456<\/p>\n<p>\u8d70\u4e86\u5b8c\u5168\u4e0d\u540c\u7684\u8def&#xff1a;is_interact&#061;true \u2192 \u67e5\u8def\u7531\u8868\u547d\u4e2d .\/wwwroot\/login \u2192 \u56de\u8c03 Login \u2192 \u56de\u663e\u53c2\u6570\u3002\u9759\u6001\u8bf7\u6c42\u8bfb\u6587\u4ef6\u3001\u52a8\u6001\u8bf7\u6c42\u8dd1\u4ee3\u7801&#xff0c;\u5728\u8fd9\u4e2a curl \u91cc\u8089\u773c\u53ef\u89c1\u5730\u5206\u5c94\u4e86\u3002<\/p>\n<p>\u53c2\u6570\u91cc\u7684 &amp; \u8bb0\u5f97\u7ed9 shell \u52a0\u5f15\u53f7&#xff0c;\u4e0d\u7136 shell \u628a\u5b83\u5f53\u540e\u53f0\u8fd0\u884c\u7b26&#xff0c;\u4f60\u7684 curl \u4f1a\u83ab\u540d\u5176\u5999\u53ea\u53d1\u4e00\u534a\u3002<\/p>\n<hr \/>\n<h4 id=\"\u73b0\u8c615\uff1a301-\u91cd\u5b9a\u5411\">\u73b0\u8c615&#xff1a;301 \u91cd\u5b9a\u5411<\/h4>\n<p>$ curl -s -o \/dev\/null -w &#034;%{http_code} -&gt; %{redirect_url}\\\\n&#034; http:\/\/127.0.0.1:8080\/redir_test<br \/>\n301 -&gt; https:\/\/www.qq.com\/<\/p>\n<p>\u670d\u52a1\u5668\u53ea\u56de\u4e86\u72b6\u6001\u884c 301 Moved Permanently &#043; Location: https:\/\/www.qq.com\/&#xff0c;\u8df3\u8f6c\u662f\u6d4f\u89c8\u5668\/\u5ba2\u6237\u7aef\u5b8c\u6210\u7684\u2014\u2014\u670d\u52a1\u5668\u4ece\u4e0d\u66ff\u4f60\u8df3&#xff0c;\u5b83\u53ea\u6307\u8def\u3002<\/p>\n<hr \/>\n<h4 id=\"\u73b0\u8c616\uff1a\u53c2\u6570\u4f20\u9519\u7684\u9632\u5b88\">\u73b0\u8c616&#xff1a;\u53c2\u6570\u4f20\u9519\u7684\u9632\u5b88<\/h4>\n<p>$ .\/myhttp abc<br \/>\nport must be a number! stoi<br \/>\n$ echo $?<br \/>\n1<br \/>\n$ .\/myhttp 99999<br \/>\nport must be in [0, 65535]!<br \/>\n$ .\/myhttp -1<br \/>\nport must be in [0, 65535]!<br \/>\n$ .\/myhttp<br \/>\nUsage: .\/myhttp port<\/p>\n<p>\u4fee\u590d\u524d\u4f20 abc \u662f\u672a\u6355\u83b7\u7684 std::invalid_argument \u76f4\u63a5 core&#xff1b;\u4f20 99999 \u9759\u9ed8\u622a\u65ad\u6210 34463 \u7ed1\u4e86\u4e2a\u9b3c\u7aef\u53e3\u3002\u73b0\u5728\u90fd\u62e6\u5728\u95e8\u53e3\u3002<\/p>\n<hr \/>\n<h4 id=\"\u73b0\u8c617\uff1a\u5e76\u53d1\">\u73b0\u8c617&#xff1a;\u5e76\u53d1<\/h4>\n<p>\u591a\u5f00\u51e0\u4e2a\u7ec8\u7aef\u540c\u65f6 curl&#xff0c;\u670d\u52a1\u7aef\u65e5\u5fd7\u4f1a\u51fa\u73b0\u4e0d\u540c\u7684 PID \u4ea4\u9519\u5904\u7406\u2014\u2014\u6bcf\u4e2a\u8fde\u63a5\u4e00\u4e2a\u5b64\u513f\u8fdb\u7a0b&#xff0c;\u5929\u7136\u5e76\u53d1\u3002<\/p>\n<p>\u8fd9\u4e5f\u662f fork \u6a21\u578b\u7684\u597d\u5904&#xff1a;\u8fdb\u7a0b\u95f4\u9694\u79bb&#xff0c;\u4e00\u4e2a\u8fde\u63a5\u7684\u5904\u7406\u5d29\u4e86&#xff08;\u6bd4\u5982 stoi \u629b\u5f02\u5e38&#xff09;&#xff0c;\u6b7b\u7684\u662f\u90a3\u4e2a\u5b64\u513f\u8fdb\u7a0b&#xff0c;\u7236\u8fdb\u7a0b\u548c\u5176\u4ed6\u8fde\u63a5\u6beb\u53d1\u65e0\u635f\u3002\u4ee3\u4ef7\u662f fork \u5f00\u9500\u5927&#xff0c;\u8fde\u63a5\u91cf\u7ea7\u4e0a\u53bb\u4e86\u8981\u6362\u591a\u7ebf\u7a0b\/epoll\u2014\u2014\u90a3\u662f\u540e\u7eed\u8bfe\u7a0b\u7684\u4e8b\u3002<\/p>\n<hr \/>\n<h3 id=\"\u5341\u3001\u8e29\u5751\u5b9e\u5f55\uff1a\u8fd9\u6b21\u68c0\u67e5\u4fee\u6389\u7684\u95ee\u9898\u6e05\u5355\">\u5341\u3001\u8e29\u5751\u5b9e\u5f55&#xff1a;\u8fd9\u6b21\u68c0\u67e5\u4fee\u6389\u7684\u95ee\u9898\u6e05\u5355<\/h3>\n<p>\u8fd9\u4e00\u8282\u662f\u6211\u6700\u60f3\u5199\u7684\u3002\u8fd9\u7248\u4ee3\u7801\u7f16\u8bd1\u96f6\u8b66\u544a\u3001\u4e00\u8dd1\u5168\u662f\u5751\u2014\u2014\u4e0b\u9762\u6bcf\u4e00\u4e2a\u90fd\u662f\u5b9e\u9645\u8fd0\u884c\u6293\u51fa\u6765\u7684&#xff0c;\u4e0d\u662f\u7eb8\u9762\u63a8\u6f14&#xff1a;<\/p>\n<table>\n<tbody>\n<tr>\n<p>#<\/p>\n<p>\u4f4d\u7f6e<\/p>\n<p>\u95ee\u9898<\/p>\n<p>\u73b0\u8c61<\/p>\n<p>\u4fee\u6cd5<\/p>\n<\/tr>\n<tr>\n<td>\n<p>1<\/p>\n<\/td>\n<td>\n<p>webroot<\/p>\n<\/td>\n<td>\n<p>\u4ee3\u7801\u5199 .\/wwwroot&#xff0c;\u78c1\u76d8\u76ee\u5f55\u53eb www.root&#xff0c;\u5dee\u4e00\u4e2a\u70b9<\/p>\n<\/td>\n<td>\n<p>\u6240\u6709\u8bf7\u6c42 404&#xff0c;\u5305\u62ec\u9996\u9875<\/p>\n<\/td>\n<td>\n<p>\u76ee\u5f55\u6539\u540d wwwroot\u3002Linux \u6587\u4ef6\u7cfb\u7edf\u5927\u5c0f\u5199\u654f\u611f\u3001\u540d\u5b57\u7cbe\u786e\u5339\u914d&#xff0c;\u5dee\u4e00\u4e2a\u5b57\u7b26\u90fd\u4e0d\u884c<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>2<\/p>\n<\/td>\n<td>\n<p>MakeResponse<\/p>\n<\/td>\n<td>\n<p>\u6210\u529f\u5206\u652f\u62a5\u5934\u5199\u6210 Conent-Type&#xff08;\u62fc\u5199\u9519&#xff09;<\/p>\n<\/td>\n<td>\n<p>\u6d4f\u89c8\u5668\u6536\u4e0d\u5230\u6b63\u786e\u7c7b\u578b\u5934<\/p>\n<\/td>\n<td>\n<p>\u6539\u56de Content-Type<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>3<\/p>\n<\/td>\n<td>\n<p>Uri2Suffix<\/p>\n<\/td>\n<td>\n<p>suffix &#061;&#061; &#034;png&#034; \u5c11\u4e2a\u70b9<\/p>\n<\/td>\n<td>\n<p>PNG \u6c38\u8fdc\u5339\u914d\u4e0d\u4e0a&#xff0c;Content-Type \u4e3a\u7a7a<\/p>\n<\/td>\n<td>\n<p>\u6539\u6210 &#034;.png&#034;<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>4<\/p>\n<\/td>\n<td>\n<p>\u4ea4\u4e92\u8def\u7531\u672a\u547d\u4e2d<\/p>\n<\/td>\n<td>\n<p>\u4ec0\u4e48\u90fd\u4e0d\u56de<\/p>\n<\/td>\n<td>\n<p>curl exit 52&#xff0c;\u6d4f\u89c8\u5668\u5361\u6b7b\u8f6c\u5708<\/p>\n<\/td>\n<td>\n<p>\u56de 404<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>5<\/p>\n<\/td>\n<td>\n<p>ReadFileContent<\/p>\n<\/td>\n<td>\n<p>\u6253\u5f00\u6587\u4ef6\u6ca1\u52a0 std::ios::binary&#xff1b;(char*)c_str() \u5f3a\u8f6c\u5199\u5165 UB<\/p>\n<\/td>\n<td>\n<p>Windows \u4e0a\u8bfb\u56fe\u5fc5\u574f<\/p>\n<\/td>\n<td>\n<p>\u52a0 binary&#xff1b;\u6539\u7528 data()<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>6<\/p>\n<\/td>\n<td>\n<p>stoi<\/p>\n<\/td>\n<td>\n<p>\u975e\u6570\u5b57\u5d29 \/ 99999 \u622a\u65ad<\/p>\n<\/td>\n<td>\n<p>\u670d\u52a1\u5668\u7ed1\u9519\u7aef\u53e3<\/p>\n<\/td>\n<td>\n<p>try-catch &#043; \u8303\u56f4\u68c0\u67e5<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>7<\/p>\n<\/td>\n<td>\n<p>HttpResponse \u6784\u9020<\/p>\n<\/td>\n<td>\n<p>_code \u672a\u521d\u59cb\u5316<\/p>\n<\/td>\n<td>\n<p>\u5fd8\u8c03 SetCode \u5c31\u53d1\u968f\u673a\u72b6\u6001\u7801<\/p>\n<\/td>\n<td>\n<p>\u6784\u9020\u65f6\u7ed9\u9ed8\u8ba4\u503c<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>8<\/p>\n<\/td>\n<td>\n<p>inet_ntop<\/p>\n<\/td>\n<td>\n<p>\u7f13\u51b2\u533a\u5927\u5c0f\u4f20\u6210 sizeof(_addr)<\/p>\n<\/td>\n<td>\n<p>IPv4 \u6700\u957f\u6070\u597d 16 \u5b57\u8282&#xff0c;\u7eaf\u649e\u5927\u8fd0<\/p>\n<\/td>\n<td>\n<p>\u4f20 sizeof(ipbuffer)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>9<\/p>\n<\/td>\n<td>\n<p>\u521d\u59cb\u5316\u987a\u5e8f<\/p>\n<\/td>\n<td>\n<p>\u521d\u59cb\u5316\u5217\u8868\u987a\u5e8f\u548c\u6210\u5458\u58f0\u660e\u987a\u5e8f\u4e0d\u4e00\u81f4<\/p>\n<\/td>\n<td>\n<p>-Wall \u62a5 -Wreorder<\/p>\n<\/td>\n<td>\n<p>\u6309\u58f0\u660e\u987a\u5e8f\u5199<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>10<\/p>\n<\/td>\n<td>\n<p>Log.hpp \u5168\u5c40\u7b26\u53f7<\/p>\n<\/td>\n<td>\n<p>\u5934\u6587\u4ef6\u91cc\u5b9a\u4e49\u51fd\u6570\u548c\u5168\u5c40\u53d8\u91cf\u6ca1\u52a0 inline<\/p>\n<\/td>\n<td>\n<p>\u591a\u4e2a .cpp \u5305\u542b\u4f1a multiple definition<\/p>\n<\/td>\n<td>\n<p>inline \u51fd\u6570 &#043; C&#043;&#043;17 inline \u53d8\u91cf<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>11<\/p>\n<\/td>\n<td>\n<p>Makefile<\/p>\n<\/td>\n<td>\n<p>\u6ca1\u5e26 -pthread<\/p>\n<\/td>\n<td>\n<p>\u90e8\u5206\u5e73\u53f0\u8fd0\u884c\u65f6\u70b8<\/p>\n<\/td>\n<td>\n<p>\u8865\u4e0a<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>12<\/p>\n<\/td>\n<td>\n<p>favicon\/\u7a7aPNG<\/p>\n<\/td>\n<td>\n<p>0 \u5b57\u8282\u7684\u56fe\u7247\u6587\u4ef6<\/p>\n<\/td>\n<td>\n<p>ReadFileContent \u8fd4\u56de false \u2192 404<\/p>\n<\/td>\n<td>\n<p>\u8fd9\u4e0d\u662f bug&#xff1a;\u7a7a\u6587\u4ef6\u672c\u6765\u5c31\u8be5 404&#xff0c;\u653e\u771f\u56fe\u5373\u53ef<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u6700\u5bb9\u6613\u6d3b\u4e0b\u6765\u7684 bug \u662f #2 \u548c #3&#xff1a;\u7f16\u8bd1\u5668\u4e0d\u62a5\u3001\u8fdb\u7a0b\u4e0d\u5d29\u3001\u9875\u9762&#034;\u770b\u8d77\u6765&#034;\u8fd8\u80fd\u5f00\u3002\u8fd9\u79cd bug \u7684\u5b58\u6d3b\u65f6\u95f4\u53ef\u4ee5\u4ee5\u5e74\u8ba1\u3002<\/p>\n<p>\u6240\u4ee5\u6211\u7684\u6d41\u7a0b\u662f&#xff1a;\u6539\u5b8c\u5fc5\u987b -Wall -Wextra \u7f16\u8bd1 &#043; curl \u9010\u9879\u5b9e\u6d4b &#043; \u6821\u9a8c\u54cd\u5e94\u5934\u548c\u5b57\u8282\u6570&#xff0c;\u5149&#034;\u770b\u4ee3\u7801\u6ca1\u95ee\u9898&#034;\u4e0d\u4f5c\u6570\u3002<\/p>\n<hr \/>\n<h3 id=\"\u5341\u4e00\u3001\u6536\u4e2a\u5c3e\uff1a\u8fd9\u4e2a\u9879\u76ee\u7684\u53e3\u8bc0\">\u5341\u4e00\u3001\u6536\u4e2a\u5c3e&#xff1a;\u8fd9\u4e2a\u9879\u76ee\u7684\u53e3\u8bc0<\/h3>\n<p>\u6574\u4e2a\u670d\u52a1\u5668\u62c6\u5b8c&#xff0c;\u5c31\u5e72\u56db\u4ef6\u4e8b&#xff1a;<\/p>\n<p>\u5efa\u8fde\u63a5&#xff08;socket\/bind\/listen&#xff09;&#xff0c;\u63a5\u5ba2\u4eba&#xff08;accept &#043; fork&#xff09;&#xff0c; \u6536\u62a5\u6587&#xff08;recv &#043; \u5207\u884c\u89e3\u6790&#xff09;&#xff0c;\u56de\u62a5\u6587&#xff08;\u8bfb\u6587\u4ef6 \/ \u8dd1\u4e1a\u52a1 &#043; \u62fc\u54cd\u5e94&#xff09;\u3002<\/p>\n<p>\u5206\u5c42\u53e3\u8bc0&#xff1a;<\/p>\n<p>TcpServer \u7ba1\u8fdb\u7a0b&#xff0c;Http \u7ba1\u534f\u8bae&#xff0c;\u4e1a\u52a1\u51fd\u6570\u7ba1\u903b\u8f91&#xff0c;\u8c01\u4e5f\u522b\u8d8a\u754c\u3002<\/p>\n<p>\u51e0\u4e2a\u523b\u8fdb DNA \u7684\u70b9&#xff1a;<\/p>\n<li>\n<p>TCP \u662f\u5b57\u8282\u6d41&#xff0c;\u62a5\u6587\u8fb9\u754c\u662f\u5e94\u7528\u5c42\u7684\u4e8b\u2014\u2014HTTP \u9760 \\\\r\\\\n \u548c Content-Length&#xff0c;\u4f60\u7684\u534f\u8bae\u5f97\u81ea\u5df1\u5b9a&#xff08;\u4e0a\u6b21\u662f len\\\\r\\\\njson\\\\r\\\\n&#xff0c;\u4e00\u56de\u4e8b&#xff09;<\/p>\n<\/li>\n<li>\n<p>fork \u540e\u4e0d\u7528\u7684 fd \u7acb\u523b\u5173&#xff0c;\u7236\u5b50\u5404\u5173\u5404\u7684<\/p>\n<\/li>\n<li>\n<p>\u4e8c\u6b21 fork&#xff1a;\u513f\u5b50\u4ea4\u63a5\u73ed&#xff0c;\u5b59\u5b50\u5e72\u6d3b&#xff0c;waitpid \u4e0d\u7b49\u5e72\u5b8c\u6d3b<\/p>\n<\/li>\n<li>\n<p>\u4efb\u4f55\u5206\u652f\u90fd\u8981\u7ed9\u5bf9\u7aef\u4e00\u4e2a\u4ea4\u4ee3&#xff0c;\u4e0d\u56de\u6570\u636e\u4eba\u5bb6\u5c31\u6302\u7740<\/p>\n<\/li>\n<li>\n<p>\u62a5\u5934\u6570\u503c&#xff08;Content-Length&#xff09;\u548c\u5b9e\u9645\u5b57\u8282\u6570\u5fc5\u987b\u5206\u6beb\u4e0d\u5dee<\/p>\n<\/li>\n<li>\n<p>\u6539\u5b8c\u4ee3\u7801&#xff1a;-Wall -Wextra \u96f6\u8b66\u544a &#043; \u5b9e\u6d4b\u6bcf\u4e00\u9879&#xff0c;\u518d\u76f8\u4fe1&#034;\u6211\u5199\u5bf9\u4e86&#034;<\/p>\n<\/li>\n","protected":false},"excerpt":{"rendered":"<p>C \u7f51\u7edc\u7f16\u7a0b\u5b9e\u6218 &#xff1a;C\u3001HTTP \u670d\u52a1\u5668\u3001socket \u7f16\u7a0b\u3001fork \u591a\u8fdb\u7a0b\u3001HTTP \u534f\u8bae\u89e3\u6790\u3001Linux \u7f51\u7edc\u7f16\u7a0bTCP \u4e09\u6b21\u63e1\u624b\u80cc\u5f97\u6eda\u74dc\u70c2\u719f&#xff0c;socket \u90a3\u51e0\u4e2a\u51fd\u6570\u4e5f\u4f1a\u8c03&#xff0c;\u53ef\u4e00\u65e6\u8981\u81ea\u5df1\u6512\u4e00\u4e2a HTTP \u670d\u52a1\u5668&#xff0c;\u5f88\u591a\u4eba\u5c31\u5361\u4f4f\u4e86&#xff1a;\u62a5\u6587\u683c\u5f0f\u8bb0\u4e0d\u7262\u3001\u4e0d\u77e5\u9053\u8be5\u5207\u51e0\u5c42\u3001\u5199\u5b8c\u4e5f\u4e0d\u77e5\u9053\u5bf9\u4e0d\u5bf9&#xff0c;\u53ea\u80fd\u9760\\&#8221;\u770b\u8d77\u6765\u80fd\u8dd1\\&#8221;\u81ea\u6211\u5b89\u6170\u3002\u66f4\u9ebb\u70e6\u7684\u662f&#xff0c;\u7b49\u4f60\u771f\u53bb\u8bfb\u522b\u4eba\u7684 HTTP \u670d\u52a1\u5668\u4ee3\u7801&amp;#xff0c<\/p>\n","protected":false},"author":2,"featured_media":108178,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[11653,151,58,78,191,396],"topic":[],"class_list":["post-108189","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-server","tag-11653","tag-http","tag-linux","tag-78","tag-191","tag-396"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.3 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>\u3010Linux\u3011\u4e09\u5341\u516b.C++ \u624b\u5199 HTTP \u670d\u52a1\u5668\uff1a\u88f8 socket + fork \u591a\u8fdb\u7a0b\uff0c\u4ece HTTP \u62a5\u6587\u89e3\u6790\u5230\u6d4f\u89c8\u5668\u6253\u5f00\u7f51\u9875 - \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\/108189.html\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\u3010Linux\u3011\u4e09\u5341\u516b.C++ \u624b\u5199 HTTP \u670d\u52a1\u5668\uff1a\u88f8 socket + fork \u591a\u8fdb\u7a0b\uff0c\u4ece HTTP \u62a5\u6587\u89e3\u6790\u5230\u6d4f\u89c8\u5668\u6253\u5f00\u7f51\u9875 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"og:description\" content=\"C \u7f51\u7edc\u7f16\u7a0b\u5b9e\u6218 &#xff1a;C\u3001HTTP \u670d\u52a1\u5668\u3001socket \u7f16\u7a0b\u3001fork \u591a\u8fdb\u7a0b\u3001HTTP \u534f\u8bae\u89e3\u6790\u3001Linux \u7f51\u7edc\u7f16\u7a0bTCP \u4e09\u6b21\u63e1\u624b\u80cc\u5f97\u6eda\u74dc\u70c2\u719f&#xff0c;socket \u90a3\u51e0\u4e2a\u51fd\u6570\u4e5f\u4f1a\u8c03&#xff0c;\u53ef\u4e00\u65e6\u8981\u81ea\u5df1\u6512\u4e00\u4e2a HTTP \u670d\u52a1\u5668&#xff0c;\u5f88\u591a\u4eba\u5c31\u5361\u4f4f\u4e86&#xff1a;\u62a5\u6587\u683c\u5f0f\u8bb0\u4e0d\u7262\u3001\u4e0d\u77e5\u9053\u8be5\u5207\u51e0\u5c42\u3001\u5199\u5b8c\u4e5f\u4e0d\u77e5\u9053\u5bf9\u4e0d\u5bf9&#xff0c;\u53ea\u80fd\u9760&quot;\u770b\u8d77\u6765\u80fd\u8dd1&quot;\u81ea\u6211\u5b89\u6170\u3002\u66f4\u9ebb\u70e6\u7684\u662f&#xff0c;\u7b49\u4f60\u771f\u53bb\u8bfb\u522b\u4eba\u7684 HTTP \u670d\u52a1\u5668\u4ee3\u7801&amp;#xff0c\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.wsisp.com\/helps\/108189.html\" \/>\n<meta property=\"og:site_name\" content=\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"article:published_time\" content=\"2026-09-20T23:25:52+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/09\/20260920232537-6ab06b71012a0.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=\"19 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/108189.html\",\"url\":\"https:\/\/www.wsisp.com\/helps\/108189.html\",\"name\":\"\u3010Linux\u3011\u4e09\u5341\u516b.C++ \u624b\u5199 HTTP \u670d\u52a1\u5668\uff1a\u88f8 socket + fork \u591a\u8fdb\u7a0b\uff0c\u4ece HTTP \u62a5\u6587\u89e3\u6790\u5230\u6d4f\u89c8\u5668\u6253\u5f00\u7f51\u9875 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"isPartOf\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\"},\"datePublished\":\"2026-09-20T23:25:52+00:00\",\"dateModified\":\"2026-09-20T23:25:52+00:00\",\"author\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/108189.html#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.wsisp.com\/helps\/108189.html\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/108189.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.wsisp.com\/helps\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\u3010Linux\u3011\u4e09\u5341\u516b.C++ \u624b\u5199 HTTP \u670d\u52a1\u5668\uff1a\u88f8 socket + fork \u591a\u8fdb\u7a0b\uff0c\u4ece HTTP \u62a5\u6587\u89e3\u6790\u5230\u6d4f\u89c8\u5668\u6253\u5f00\u7f51\u9875\"}]},{\"@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":"\u3010Linux\u3011\u4e09\u5341\u516b.C++ \u624b\u5199 HTTP \u670d\u52a1\u5668\uff1a\u88f8 socket + fork \u591a\u8fdb\u7a0b\uff0c\u4ece HTTP \u62a5\u6587\u89e3\u6790\u5230\u6d4f\u89c8\u5668\u6253\u5f00\u7f51\u9875 - \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\/108189.html","og_locale":"zh_CN","og_type":"article","og_title":"\u3010Linux\u3011\u4e09\u5341\u516b.C++ \u624b\u5199 HTTP \u670d\u52a1\u5668\uff1a\u88f8 socket + fork \u591a\u8fdb\u7a0b\uff0c\u4ece HTTP \u62a5\u6587\u89e3\u6790\u5230\u6d4f\u89c8\u5668\u6253\u5f00\u7f51\u9875 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","og_description":"C \u7f51\u7edc\u7f16\u7a0b\u5b9e\u6218 &#xff1a;C\u3001HTTP \u670d\u52a1\u5668\u3001socket \u7f16\u7a0b\u3001fork \u591a\u8fdb\u7a0b\u3001HTTP \u534f\u8bae\u89e3\u6790\u3001Linux \u7f51\u7edc\u7f16\u7a0bTCP \u4e09\u6b21\u63e1\u624b\u80cc\u5f97\u6eda\u74dc\u70c2\u719f&#xff0c;socket \u90a3\u51e0\u4e2a\u51fd\u6570\u4e5f\u4f1a\u8c03&#xff0c;\u53ef\u4e00\u65e6\u8981\u81ea\u5df1\u6512\u4e00\u4e2a HTTP \u670d\u52a1\u5668&#xff0c;\u5f88\u591a\u4eba\u5c31\u5361\u4f4f\u4e86&#xff1a;\u62a5\u6587\u683c\u5f0f\u8bb0\u4e0d\u7262\u3001\u4e0d\u77e5\u9053\u8be5\u5207\u51e0\u5c42\u3001\u5199\u5b8c\u4e5f\u4e0d\u77e5\u9053\u5bf9\u4e0d\u5bf9&#xff0c;\u53ea\u80fd\u9760\"\u770b\u8d77\u6765\u80fd\u8dd1\"\u81ea\u6211\u5b89\u6170\u3002\u66f4\u9ebb\u70e6\u7684\u662f&#xff0c;\u7b49\u4f60\u771f\u53bb\u8bfb\u522b\u4eba\u7684 HTTP \u670d\u52a1\u5668\u4ee3\u7801&amp;#xff0c","og_url":"https:\/\/www.wsisp.com\/helps\/108189.html","og_site_name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","article_published_time":"2026-09-20T23:25:52+00:00","og_image":[{"url":"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/09\/20260920232537-6ab06b71012a0.png"}],"author":"admin","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"admin","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"19 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.wsisp.com\/helps\/108189.html","url":"https:\/\/www.wsisp.com\/helps\/108189.html","name":"\u3010Linux\u3011\u4e09\u5341\u516b.C++ \u624b\u5199 HTTP \u670d\u52a1\u5668\uff1a\u88f8 socket + fork \u591a\u8fdb\u7a0b\uff0c\u4ece HTTP \u62a5\u6587\u89e3\u6790\u5230\u6d4f\u89c8\u5668\u6253\u5f00\u7f51\u9875 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","isPartOf":{"@id":"https:\/\/www.wsisp.com\/helps\/#website"},"datePublished":"2026-09-20T23:25:52+00:00","dateModified":"2026-09-20T23:25:52+00:00","author":{"@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41"},"breadcrumb":{"@id":"https:\/\/www.wsisp.com\/helps\/108189.html#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.wsisp.com\/helps\/108189.html"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.wsisp.com\/helps\/108189.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.wsisp.com\/helps"},{"@type":"ListItem","position":2,"name":"\u3010Linux\u3011\u4e09\u5341\u516b.C++ \u624b\u5199 HTTP \u670d\u52a1\u5668\uff1a\u88f8 socket + fork \u591a\u8fdb\u7a0b\uff0c\u4ece HTTP \u62a5\u6587\u89e3\u6790\u5230\u6d4f\u89c8\u5668\u6253\u5f00\u7f51\u9875"}]},{"@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\/108189","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=108189"}],"version-history":[{"count":0,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/108189\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/media\/108178"}],"wp:attachment":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/media?parent=108189"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/categories?post=108189"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/tags?post=108189"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/topic?post=108189"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}