{"id":85,"date":"2025-04-28T22:51:18","date_gmt":"2025-04-28T14:51:18","guid":{"rendered":"https:\/\/tanime.life\/?p=85"},"modified":"2025-04-28T22:51:18","modified_gmt":"2025-04-28T14:51:18","slug":"%e5%85%b3%e4%ba%8epoll%e5%ae%9e%e7%8e%b0server%e5%8f%af%e8%83%bd%e5%87%ba%e7%8e%b0%e7%9a%84%e9%97%ae%e9%a2%98","status":"publish","type":"post","link":"https:\/\/www.tanime.life\/index.php\/2025\/04\/28\/%e5%85%b3%e4%ba%8epoll%e5%ae%9e%e7%8e%b0server%e5%8f%af%e8%83%bd%e5%87%ba%e7%8e%b0%e7%9a%84%e9%97%ae%e9%a2%98\/","title":{"rendered":"\u5173\u4e8epoll\u5b9e\u73b0Server\u53ef\u80fd\u51fa\u73b0\u7684\u95ee\u9898"},"content":{"rendered":"\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"wp-block-paragraph\">\u4eca\u5929\u82b1\u4e86\u5f88\u591a\u7684\u529f\u592b\u5728\u6392\u9519\u4e0a\u9762\uff0c\u4e3b\u8981\u662f\u4e0d\u660e\u767d\u95ee\u4ec0\u4e48\u6570\u636e\u5728\u54ea\u91cc\u51fa\u9519\u3002\u56e0\u4e3a\u8fd9\u91cc\u5df2\u7ecf\u5c06\u95ee\u9898\u4fee\u6539\uff0c\u8d34\u4e00\u4e0b\u4fee\u6539\u8fc7\u540e\u7684\u4ee3\u7801<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;iostream>\n#include \"wrap.h\"\n\nint main() {\n    int i;\n    int sockfd;\n    int lfd = Socket(AF_INET, SOCK_STREAM, 0);\n    char clt_str&#91;INET_ADDRSTRLEN];\n    int clt_port;\n    int cfd;\n    int maxfd = 0;\n    struct pollfd pfd&#91;1024];\n    struct sockaddr_in serv_addr, clt_addr;\n    memset(&amp;serv_addr, 0, sizeof(serv_addr));\n    memset(&amp;clt_addr, 0, sizeof(serv_addr));\n    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);\n    serv_addr.sin_family = AF_INET;\n    serv_addr.sin_port = htons(PORT);\n    char buf&#91;BUFSIZ];\n    int opt = 1;\n    setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, &amp;opt, sizeof(opt));\n    socklen_t clt_socklen;\n    Bind(lfd, (struct sockaddr *) &amp;serv_addr, sizeof(serv_addr));\n    Listen(lfd, BACK_LOG);\n    pfd&#91;0].fd = lfd;\n    pfd&#91;0].events = POLL_IN;\n    pfd&#91;0].revents = 0;\n    int pfd_len = sizeof(pfd) \/ sizeof(pfd&#91;0]);\n    for (i = 1; i &lt; pfd_len; ++i) {\n        pfd&#91;i].fd = -1;\n    }\n    maxfd = 0; \/\/ poll\u5185\u90e8\u7684\u6709\u6548\u5143\u7d20\u7684\u6700\u5927\u5143\u7d20\u4e0b\u6807.\n    int nReady = 0;\n    while (true) {\n        nReady = poll(pfd, maxfd + 1, -1);\n        if (pfd&#91;0].revents == POLL_IN) {\n            \/\/ \u627e\u5230\u5bf9\u5e94\n            clt_socklen = sizeof(clt_addr);\n            cfd = Accept(lfd, (struct sockaddr *) &amp;clt_addr, &amp;clt_socklen);\n            \/\/ \u8f93\u51fa\u5ba2\u6237\u7aef\u4fe1\u606f\n            clt_port = ntohs(clt_addr.sin_port);\n            inet_ntop(AF_INET, &amp;clt_addr.sin_addr, clt_str, INET_ADDRSTRLEN);\n            std::cout &lt;&lt; \"Client Port: \" &lt;&lt; clt_port &lt;&lt; \"  Client IP: \" &lt;&lt; clt_str &lt;&lt; std::endl;\n\n            for (i = 1; i &lt; pfd_len; ++i) {\n                if (pfd&#91;i].fd &lt; 0) {\n                    pfd&#91;i].fd = cfd;\n                    pfd&#91;i].events = POLL_IN;    \/\/\u6ce8\u610f\uff01\uff01\uff01 \u91cd\u70b9\n                    \/\/======================================================\n                    \/\/\u903b\u8f91\u4e0a\u5e94\u5f53\u5728\u8fd9\u91cc\u4fee\u6539pfd\uff0c\u5982\u679c\u4f60\u5199\u5728\u5916\u9762,\u53ef\u80fd\u5c31\u4f1a\u5bfc\u81f4\u5f88\u5927\u7684\u95ee\u9898.\n                    break;\n                }\n            }\n            maxfd = std::max(maxfd, i);\n            if (--nReady &lt;= 0) {\n                continue; \/\/ \u4ee3\u8868\u4ec5\u6709\u76d1\u542c,\u90a3\u4e48\u7ee7\u7eed\u76d1\u542c,\u4e0d\u5904\u7406\u5ba2\u6237\u7aef\u4e8b\u4ef6.\n            }\n            try {\n                if (i >= pfd_len) {\n                    \/\/ \u5b58\u6ee1\u4e86\n                    throw \"Too many Clients\";\n                }\n            } catch (const char *msg) {\n                std::cout &lt;&lt; msg &lt;&lt; std::endl;\n                exit(1);\n            }\n\n        }\n        \/\/\u8981\u6ce8\u610f \u76d1\u542c\u4e8b\u4ef6\u4e0e\u5ba2\u6237\u7aef\u4e8b\u4ef6\u7684\u5206\u79bb,\u9632\u6b62\u5d4c\u5957.\n\n        for (i = 1; i &lt;= maxfd ; ++i) {\n            if((sockfd = pfd&#91;i].fd) &lt; 0) {\n                continue;\n            }\n            if (pfd&#91;i].revents &amp; POLL_IN) {\n                \/\/ \u8fdb\u884c\u76f8\u5173\u8bfb\u5199\u64cd\u4f5c\n                ssize_t n = read(sockfd, buf, sizeof(buf));\n                if (n &lt; 0) {\n                    if (errno == ECONNRESET) {\n                        \/\/ \u8fde\u63a5\u88ab\u91cd\u7f6e\n                        std::cerr &lt;&lt; \"Client&#91;\" &lt;&lt; i &lt;&lt; \"] close the connection\" &lt;&lt; std::endl;\n                        close(sockfd);\n                    } else {\n                        std::cerr &lt;&lt; \"Read Error\" &lt;&lt; std::endl;\n                        exit(1);\n                    }\n\n                } else if (n == 0) {\n                    std::cout &lt;&lt; \"Client close the connection\" &lt;&lt; std::endl;\n                    close(sockfd);\n                    pfd&#91;i].fd = -1;\n                    \/\/ i == maxfd \u53ef\u80fd\u8981\u8fdb\u884c\u76f8\u5e94\u5904\u7406.\n                    if (i == maxfd) {\n                        while (maxfd > 0 &amp;&amp; pfd&#91;maxfd].fd == -1) --maxfd;\n                    }\n                    break;\n                } else if (n > 0) {\n                    for (int k = 0; k &lt; n; ++k) {\n                        buf&#91;k] = toupper(buf&#91;k]);\n                    }\n                    Write(STDOUT_FILENO, buf, n);\n                    Write(sockfd, buf, n);\n                }\n            }\n            if (--nReady &lt;= 0) {\n                break;\n            }\n        }\n    }\n    close(lfd);\n    return 0;\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u5176\u4e2dwrap.h\u5c01\u88c5\u4e86socket\u53caread\uff0cwrite\u4e00\u7cfb\u5217\u51fd\u6570\uff0c\u907f\u514d\u7e41\u7410\u7684\u9519\u8bef\u5904\u7406<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u5173\u952e\u5728\u4e8e\uff0c\u5199\u7684\u65f6\u5019\u7684\uff0c<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u76d1\u542c\u4e8b\u4ef6\u4e0e\u5ba2\u6237\u7aef\u4e8b\u4ef6\u7684\u5206\u79bb<\/li>\n\n\n\n<li> pfd[i].events = POLL_IN;\u7684\u5904\u7406\u4f4d\u7f6e\n<ul class=\"wp-block-list\">\n<li>\u5728\u8fd9\u91cc\u6211\u5fc5\u987b\u8981\u627f\u8ba4\uff0c\u6211\u5bf9\u7f51\u4e0a\u7684\u6559\u7a0b\u6b63\u786e\u5ea6\u62b1\u6709\u671f\u671b\u786e\u5b9e\u592a\u9ad8\u4e86\uff0c\u6709\u4e9b\u65f6\u5019\u6211\u5c31\u770b\u4e86\u534a\u622a\u5c31\u8dd1\u4e86\uff0c\u5728\u540e\u9762\u4ee3\u7801\u53cd\u800c\u4f1a\u8fdb\u884c\u4fee\u6539\uff0c\u5176\u5b9e\u5e94\u8be5\u662f\u6211\u7684\u95ee\u9898\u5427\uff0c\u5e94\u8be5\u770b\u5b8c\u3002\u4e0d\u8fc7\u5176\u5b9e\u6309\u81ea\u5df1\u7684\u5199\u6cd5\uff0c\u5199\u5c31\u597d\u4e86\uff0c\u9876\u591a\u540e\u9762\u53c2\u8003\u4e00\u4e0b\u4ee3\u7801\u903b\u8f91\u3002\u5bf9\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>\u611f\u89c9\u6700\u607c\u706b\u7684\u5c31\u662f\uff0ci\u7684\u4f5c\u7528\u57df\u8303\u56f4\uff0c\u6559\u7a0b\u5185\u90e8\uff0c\u76f4\u63a5\u5b9a\u4e49i\u5728\u521d\u59cb\u4f4d\u7f6e\uff0c\u672c\u8eab\u5c31\u4e0d\u5408\u7406\uff0c\u56e0\u4e3a\u8981\u901a\u8fc7i\u8fdb\u884c\u63a7\u5236\u591a\u4e2a\u5faa\u73af\uff0c\u800c\u6211\u4eec\u53ea\u9700\u8981\u989d\u5916\u5728\u5b9a\u4e49\u4e00\u4e2a\u53d8\u91cf\u4f8b\u5982k\u6765\u63a7\u5236\u5faa\u73af\u5c31\u597d\u4e86\uff0c\u8ba9\u53d8\u91cf\u51fa\u53bb\uff0c\u4e5f\u4e0d\u597d\u6392\u9519\uff0c\u8fd9\u4e5f\u662f\u6211\u4eec\u9700\u8981\u6ce8\u610f\u7684\u3002\u4f5c\u7528\u57df\u5bfc\u81f4\u7684\u975e\u7f16\u8bd1\u95ee\u9898\uff0c\u800c\u662f\u903b\u8f91\u95ee\u9898\u3002<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u4eca\u5929\u82b1\u4e86\u5f88\u591a\u7684\u529f\u592b\u5728\u6392\u9519\u4e0a\u9762\uff0c\u4e3b\u8981\u662f\u4e0d\u660e\u767d\u95ee\u4ec0\u4e48\u6570\u636e\u5728\u54ea\u91cc\u51fa\u9519\u3002\u56e0\u4e3a\u8fd9\u91cc\u5df2\u7ecf\u5c06\u95ee\u9898\u4fee\u6539\uff0c\u8d34\u4e00\u4e0b\u4fee\u6539\u8fc7\u540e\u7684\u4ee3\u7801  [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-85","post","type-post","status-publish","format-standard","hentry","category-techsharing"],"_links":{"self":[{"href":"https:\/\/www.tanime.life\/index.php\/wp-json\/wp\/v2\/posts\/85","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tanime.life\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tanime.life\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tanime.life\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tanime.life\/index.php\/wp-json\/wp\/v2\/comments?post=85"}],"version-history":[{"count":5,"href":"https:\/\/www.tanime.life\/index.php\/wp-json\/wp\/v2\/posts\/85\/revisions"}],"predecessor-version":[{"id":90,"href":"https:\/\/www.tanime.life\/index.php\/wp-json\/wp\/v2\/posts\/85\/revisions\/90"}],"wp:attachment":[{"href":"https:\/\/www.tanime.life\/index.php\/wp-json\/wp\/v2\/media?parent=85"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tanime.life\/index.php\/wp-json\/wp\/v2\/categories?post=85"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tanime.life\/index.php\/wp-json\/wp\/v2\/tags?post=85"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}