{"id":63,"date":"2025-04-22T20:51:59","date_gmt":"2025-04-22T12:51:59","guid":{"rendered":"http:\/\/120.76.99.214\/?p=63"},"modified":"2025-11-24T16:43:19","modified_gmt":"2025-11-24T08:43:19","slug":"io%e5%a4%9a%e8%b7%af%e5%a4%8d%e7%94%a8%e5%ae%9e%e7%8e%b0%e6%9c%8d%e5%8a%a1%e5%99%a8%e5%b9%b6%e5%8f%91%ef%bc%883%ef%bc%89","status":"publish","type":"post","link":"https:\/\/www.tgwttt.xyz\/?p=63","title":{"rendered":"IO\u591a\u8def\u590d\u7528\u5b9e\u73b0\u670d\u52a1\u5668\u5e76\u53d1\uff083\uff09"},"content":{"rendered":"\n<p>\u4f7f\u7528epoll\u5b9e\u73b0\u670d\u52a1\u5668\u5e76\u53d1<\/p>\n\n\n\n<p>io\u591a\u8def\u590d\u7528\u4e00\u5171\u6709\u4e09\u79cd\u65b9\u5f0fselect poll epoll \u7531\u4e8epoll\u7528\u7684\u6bd4\u8f83\u5c11\uff0c\u535a\u4e3b\u5c31\u6ca1\u6709\u4ecb\u7ecd\uff0cepoll\u662f\u4e09\u79cd\u65b9\u5f0f\u4e2d\u7528\u7684\u6700\u591a\u7684\u4e00\u79cd\uff0c\u7531\u4e8e\u5b83\u7684\u5e95\u5c42\u662f\u6709\u7ea2\u9ed1\u6811\u5b9e\u73b0\u7684\u518d\u52a0\u4e0a\u5b83\u72ec\u7279\u7684\u56de\u8c03\u673a\u5236\u4f7f\u5f97\u5b83\u5728\u5904\u7406\u5e76\u53d1\u91cf\u8f83\u9ad8\u7684\u573a\u666f\u4e2d\u5177\u6709\u660e\u663e\u4f18\u52bf\u3002\u63a5\u4e0b\u6765\u662f\u4f7f\u7528epoll\u5b9e\u73b0\u670d\u52a1\u5668\u5e76\u53d1\u7684\u4ee3\u7801\u6f14\u793a\uff0c\u4ee3\u7801\u5177\u6709\u5927\u91cf\u6ce8\u91ca\uff0c\u53ef\u4ee5\u5f88\u5bb9\u6613\u770b\u61c2\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>include <sys\/epoll.h>\n#include <iostream>\n#include <unistd.h>\n#include <sys\/types.h>\n#include <sys\/stat.h>\n#include <arpa\/inet.h>\n#include <cstring>\n#include <vector>\n#include <thread>\n#include <mutex>\n#include <functional>\n#define PORT 8888\nusing namespace std;\n\nmutex mtx;\n\n\/\/ \u5b9a\u4e49\u4e00\u4e2a\u7ed3\u6784\u4f53\u6765\u5b58\u50a8\u76f8\u5173\u4fe1\u606f\ntypedef struct infor {\n    epoll_event *ev;\n    int epct;\n    int epfd;\n    int fd;\n} infor;\n\n\/\/ \u5904\u7406\u65b0\u8fde\u63a5\u7684\u51fd\u6570\nvoid listen_handler(infor info) {\n    int cfd = accept(info.fd, NULL, NULL);  \/\/ \u63a5\u53d7\u8fde\u63a5\n    if (cfd == -1) {\n        cout << \"accept error\" << endl;\n        return;\n    }\n\n    epoll_event ev;\n    ev.events = EPOLLIN;  \/\/ \u5173\u6ce8\u8bfb\u4e8b\u4ef6\n    ev.data.fd = cfd;  \/\/ \u5173\u8054\u5ba2\u6237\u7aef\u5957\u63a5\u5b57\n    unique_lock<mutex> lock(mtx);\n    lock.lock();\n    int epct = epoll_ctl(info.epfd, EPOLL_CTL_ADD, cfd, &ev);  \/\/ \u5c06\u5ba2\u6237\u7aef\u5957\u63a5\u5b57\u52a0\u5165epoll\u76d1\u63a7\n    if (epct == -1) {\n        cout << \"epoll_ctl add client fd error\" << endl;\n        close(cfd);  \/\/ \u5982\u679c\u51fa\u9519\uff0c\u5173\u95ed\u5ba2\u6237\u7aef\u5957\u63a5\u5b57\n    }\n}\n\n\/\/ \u5904\u7406\u5ba2\u6237\u7aef\u8bf7\u6c42\u7684\u51fd\u6570\nvoid client_handler(infor info) {\n    char buf[1024];\n    int len = recv(info.fd, buf, sizeof(buf), 0);  \/\/ \u63a5\u6536\u6570\u636e\n    if (len == -1) {\n        cout << \"recv error\" << endl;\n    } else if (len == 0) {  \/\/ \u5ba2\u6237\u7aef\u5173\u95ed\u8fde\u63a5\n        unique_lock<mutex> lock(mtx);\n        lock.lock();\n        epoll_ctl(info.epfd, EPOLL_CTL_DEL, info.fd, NULL);  \/\/ \u4eceepoll\u76d1\u63a7\u4e2d\u79fb\u9664\nclose(info.fd);  \/\/ \u5173\u95ed\u5ba2\u6237\u7aef\u5957\u63a5\u5b57\n        cout << \"client is closed\" << endl;\n    } else {  \/\/ \u5ba2\u6237\u7aef\u53d1\u9001\u6570\u636e\n        for (int j = 0; j < len; j++) {  \/\/ \u5c06\u6570\u636e\u8f6c\u6362\u4e3a\u5927\u5199\n            buf[j] = toupper(buf[j]);\n        }\n        int ret = send(info.fd, buf, len, 0);  \/\/ \u53d1\u9001\u6570\u636e\n        if (ret == -1) {\n            cout << \"send error\" << endl;\n        }\n    }\n}\n\nint main() {\n    int lfd = socket(AF_INET, SOCK_STREAM, 0);  \/\/ \u521b\u5efa\u5957\u63a5\u5b57\n    if (lfd == -1) {\n        cout << \"socket error\" << endl;\n        return -1;\n    }\n\n    struct sockaddr_in serv_addr;  \/\/ \u670d\u52a1\u5668\u5730\u5740\u7ed3\u6784\n    memset(&#038;serv_addr, 0, sizeof(serv_addr));  \/\/ \u521d\u59cb\u5316\u5730\u5740\u7ed3\u6784\n    serv_addr.sin_family = AF_INET;\n    serv_addr.sin_port = htons(PORT);  \/\/ \u8bbe\u7f6e\u7aef\u53e3\u53f7\n    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);\n\n    int optval = 1;\n    setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, &#038;optval, sizeof(optval));  \/\/ \u8bbe\u7f6e\u5957\u63a5\u5b57\u9009\u9879\n\n    \/\/ \u7ed1\u5b9a\u5730\u5740\n    int ret = bind(lfd, (struct sockaddr*)&#038;serv_addr, sizeof(serv_addr));\n    if (ret == -1) {\n        cout << \"bind error\" << endl;\n        close(lfd);\n        return -1;\n    }\n\n    ret = listen(lfd, 128);  \/\/ \u76d1\u542c\u5957\u63a5\u5b57\n    if (ret == -1) {\n        cout << \"listen error\" << endl;\n        close(lfd);\n        return -1;\n    }\n\n    int epfd = epoll_create(1);  \/\/ \u521b\u5efaepoll\u5b9e\u4f8b\n    if (epfd == -1) {\n        cout << \"epoll create error\" << endl;\n        close(lfd);\n        return -1;\n    }\n\n    epoll_event ev;  \/\/ epoll\u4e8b\u4ef6\u7ed3\u6784\n    ev.events = EPOLLIN;  \/\/ \u5173\u6ce8\u8bfb\u4e8b\u4ef6\n    ev.data.fd = lfd;  \/\/ \u5173\u8054\u76d1\u542c\u5957\u63a5\u5b57\nret = epoll_ctl(epfd, EPOLL_CTL_ADD, lfd, &#038;ev);\n    if (ret == -1) {\n        cout << \"epoll_ctl add listen fd error\" << endl;\n        close(lfd);\n        close(epfd);\n        return -1;\n    }\n\n    vector<epoll_event> evs(1024);  \/\/ \u521d\u59cb\u5316epoll\u4e8b\u4ef6\u6570\u7ec4\uff0c\u5206\u914d\u8db3\u591f\u7a7a\u95f4\n    while (1) {\n        int number = epoll_wait(epfd, evs.data(), evs.size(), -1);  \/\/ \u7b49\u5f85epoll\u4e8b\u4ef6\n        if (number == -1) {\n            cout << \"epoll_wait error\" << endl;\n            continue;\n        }\n\n        for (int i = 0; i < number; ++i) {  \/\/ \u904d\u5386\u89e6\u53d1\u7684\u4e8b\u4ef6\n            int fd = evs[i].data.fd;\n            if (fd == lfd) {\n                \/\/ \u5982\u679c\u662f\u76d1\u542c\u5957\u63a5\u5b57\n                infor info;\n                info.ev = &ev;\n                info.epct = ret;\n                info.epfd = epfd;\n                info.fd = lfd;\n                thread t(listen_handler, info);  \/\/ \u521b\u5efa\u7ebf\u7a0b\u5904\u7406\u65b0\u8fde\u63a5\n                t.detach();  \/\/ \u5206\u79bb\u7ebf\u7a0b\n            } else {\n                \/\/ \u5982\u679c\u662f\u5ba2\u6237\u7aef\u5957\u63a5\u5b57\n                infor info;\n                info.ev = &ev;\n                info.epct = ret;\n                info.epfd = epfd;\n                info.fd = fd;\n                thread t(client_handler, info);  \/\/ \u521b\u5efa\u7ebf\u7a0b\u5904\u7406\u5ba2\u6237\u7aef\u8bf7\u6c42\n                t.detach();  \/\/ \u5206\u79bb\u7ebf\u7a0b\n            }\n        }\n    }\n\n    close(lfd);  \/\/ \u5173\u95ed\u76d1\u542c\u5957\u63a5\u5b57\n    close(epfd);  \/\/ \u5173\u95edepoll\u5b9e\u4f8b\n    return 0;\n\n                             <\/code><\/pre>\n\n\n\n<p>\u5b83\u7684\u4f5c\u7528\u4f9d\u65e7\u662f\u5c06\u5927\u5199\u8f6c\u5316\u4e3a\u5c0f\u5199\uff0c\u652f\u6301\u5e76\u53d1\u91cf\u8f83\u9ad8\u7684\u573a\u666f\u3002<\/p>\n\n\n\n<p>\u4eca\u5929\u7684\u66f4\u65b0\u5c31\u5230\u8fd9\u91cc\u4e86\uff0c\u5927\u5bb6\u518d\u89c1\uff01\uff01\uff01<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u4f7f\u7528epoll\u5b9e\u73b0\u670d\u52a1\u5668\u5e76\u53d1 io\u591a\u8def\u590d\u7528\u4e00\u5171\u6709\u4e09\u79cd\u65b9\u5f0fselect poll epoll \u7531\u4e8epoll\u7528\u7684\u6bd4&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","footnotes":""},"categories":[1],"tags":[],"class_list":["post-63","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.tgwttt.xyz\/index.php?rest_route=\/wp\/v2\/posts\/63","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tgwttt.xyz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tgwttt.xyz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tgwttt.xyz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tgwttt.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=63"}],"version-history":[{"count":4,"href":"https:\/\/www.tgwttt.xyz\/index.php?rest_route=\/wp\/v2\/posts\/63\/revisions"}],"predecessor-version":[{"id":890,"href":"https:\/\/www.tgwttt.xyz\/index.php?rest_route=\/wp\/v2\/posts\/63\/revisions\/890"}],"wp:attachment":[{"href":"https:\/\/www.tgwttt.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=63"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tgwttt.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=63"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tgwttt.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=63"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}