{"id":1885,"date":"2019-01-24T14:06:26","date_gmt":"2019-01-24T06:06:26","guid":{"rendered":"https:\/\/www.yusian.com\/blog\/?p=1885"},"modified":"2020-12-02T14:09:39","modified_gmt":"2020-12-02T06:09:39","slug":"%e5%a4%9a%e8%b7%afio%e8%bd%ac%e6%8e%a5%e6%a8%a1%e5%9e%8b","status":"publish","type":"post","link":"https:\/\/www.yusian.com\/blog\/cpp\/2019\/01\/24\/1406261885.html","title":{"rendered":"\u591a\u8defIO\u8f6c\u63a5\u6a21\u578b"},"content":{"rendered":"<h3>1\u3001select\u51fd\u6570<\/h3>\n<pre><code class=\"language-c line-numbers\">#include &lt;sys\/select.h&gt;\n\n\/* According to earlier standards *\/\n#include &lt;sys\/time.h&gt;\n#include &lt;sys\/types.h&gt;\n#include &lt;unistd.h&gt;\n\nint select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);\n\nvoid FD_CLR(int fd, fd_set *set);\nint  FD_ISSET(int fd, fd_set *set);\nvoid FD_SET(int fd, fd_set *set);\nvoid FD_ZERO(fd_set *set);\n<\/code><\/pre>\n<p>demo\u793a\u4f8b<!--more--><\/p>\n<pre><code class=\"language-c line-numbers\">#include \"wrap.h\"\n#include &lt;sys\/select.h&gt;\n#include &lt;arpa\/inet.h&gt;\n#include &lt;strings.h&gt;\n#include &lt;ctype.h&gt;\n\nvoid exchange(char *buf, int len);\nint main(){\n    \/\/ socket\n    int sfd, cfd;\n    sfd = Socket(AF_INET, SOCK_STREAM, 0);\n    int sockopt = 1;\n    setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &amp;sockopt, sizeof(sockopt));\n\n    \/\/ bind linsten\n    struct sockaddr_in s_addr, c_addr;\n    socklen_t addrlen = sizeof(struct sockaddr_in);\n    bzero(&amp;s_addr, addrlen);\n    bzero(&amp;c_addr, addrlen);\n    s_addr.sin_family = AF_INET;\n    s_addr.sin_addr.s_addr = htonl(INADDR_ANY);\n    s_addr.sin_port = htons(3000);\n    Bind(sfd, &amp;s_addr, sizeof(s_addr));\n    Listen(sfd, 128);\n\n    \/\/ fd_set\u3001nfds\u3001client[]\u3001select\n    fd_set readfds, allfds;\n    FD_ZERO(&amp;readfds);\n    FD_ZERO(&amp;allfds);\n    FD_SET(sfd, &amp;allfds);\n    int maxfd = sfd;\n    int selret;\n    int client[FD_SETSIZE], i, maxi = -1;\n    for (i = 0; i &lt; FD_SETSIZE; i++){\n        client[i] = -1;\n    }\n\n    while(1){\n        readfds = allfds;\n        \/\/ select\u51fd\u6570(\u963b\u585e)\n        selret = select(maxfd + 1, &amp;readfds, NULL, NULL, NULL);\n        if (selret &lt; 0){\n            perror(\"select error\");\n            exit(1);\n        }\n        \/\/ 1\u3001\u662f\u5426\u6709\u65b0\u8fde\u63a5,\u521b\u5efa\u8fde\u63a5,\u5904\u7406\u65b0\u5efa\u8fde\u63a5\u8bf7\u6c42(\u6587\u4ef6\u63cf\u8ff0\u7b26\u516c\u7528\uff0c\u751f\u4ea7\u5176\u4ed6\u6587\u4ef6\u63cf\u8ff0\u7b26)\n        if (FD_ISSET(sfd, &amp;readfds)){\n            \/\/ 1.1\u3001\u521b\u5efa\u8fde\u63a5\n            cfd = Accept(sfd, &amp;c_addr, &amp;addrlen);\n            char address[INET_ADDRSTRLEN];\n            printf(\"A new connect from %s:%d\\n\",\n                    inet_ntop(AF_INET, &amp;c_addr.sin_addr.s_addr, address, INET_ADDRSTRLEN),\n                    ntohs(c_addr.sin_port));\n            \/\/ 1.2\u3001\u5c06\u65b0\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26\u52a0\u5165\u5230\u6570\u7ec4\n            for (i = 0; i &lt; FD_SETSIZE; i++){\n                if (client[i] != -1) continue;\n                client[i] = cfd;\n                break;\n            }\n            if (maxi &lt; i) maxi = i;\n            if (maxfd &lt; cfd) maxfd = cfd;\n            \/\/ 1.3\u3001\u5c06\u65b0\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26\u52a0\u5165\u5230\u96c6\u5408\n            FD_SET(cfd, &amp;allfds);\n            if (--selret == 0) continue;\n        }\n        \/\/ 2\u3001\u73b0\u6709\u8fde\u63a5\u6570\u636e\u5904\u7406\n        for (i = 0; i &lt;= maxi; i++){\n            int fd = client[i];\n            if (fd == -1) continue;\n            if (FD_ISSET(fd, &amp;readfds)){\n                \/\/ \u5904\u7406\u6570\u636e\n                char buf[BUFSIZ];\n                int n = Readn(fd, &amp;buf, BUFSIZ);\n                if (n &lt;= 0){\n                    close(fd);\n                    client[i] = -1;\n                    FD_CLR(fd, &amp;allfds);\n                    continue;\n                }else{\n                    printf(\"readed %d bytes\\n\", n);\n                    exchange(buf, n);\n                    write(fd, buf, n);\n                }\n                if (--selret == 0) break;\n            }\n        }\n    }\n}\nvoid exchange(char *buf, int len)\n{\n    int i;\n    for (i = 0; i &lt; len; i++){\n        buf[i] = toupper(buf[i]);\n    }\n}\n<\/code><\/pre>\n<h3>2\u3001poll\u51fd\u6570<\/h3>\n<ul>\n<li>\u4fee\u6539\u6587\u4ef6\u63cf\u8ff0\u7b26\u9650\u5236\uff1a\/proc\/sys\/fs\/file-max<\/li>\n<li>\u4fee\u6539\u6587\u4ef6\u63cf\u8ff0\u7b26\u9650\u5236\u4ec5\u5bf9poll\u53caepoll\u6709\u6548\uff0c\u5bf9select\u65e0\u6548\uff0cselect\u7684\u6587\u4ef6\u63cf\u8ff0\u7b26\u4e0a\u9650FD_SETSIZE\u7531unix\u5185\u6838\u9650\u5236\u4e86\uff0c\u4fee\u6539\u9700\u8981\u91cd\u65b0\u7f16\u8bd1\u5185\u6838\uff1b<\/li>\n<\/ul>\n<pre><code class=\"language-c line-numbers\">* soft nofile 65535\n* hard nofile 100000\n<\/code><\/pre>\n<pre><code class=\"language-c line-numbers\">SYNOPSIS\n       #include &lt;poll.h&gt;\n\n       int poll(struct pollfd *fds, nfds_t nfds, int timeout);\n\nDESCRIPTION\n       poll() performs a similar task to select(2): it waits for one of a set of file descriptors to become ready to perform I\/O.\n\n       The set of file descriptors to be monitored is specified in the fds argument, which is an array of structures of the following form:\n\n           struct pollfd {\n               int   fd;         \/* file descriptor *\/\n               short events;     \/* requested events *\/\n               short revents;    \/* returned events *\/\n           };\n\n       The caller should specify the number of items in the fds array in nfds.\n<\/code><\/pre>\n<pre><code class=\"language-c line-numbers\">#include \"wrap.h\"\n#include &lt;arpa\/inet.h&gt;\n#include &lt;ctype.h&gt;\n#include &lt;strings.h&gt;\n#include &lt;poll.h&gt;\n\n#define OPEN_MAX 1024\nint main(){\n    \/\/ socket\n    int sfd, cfd;\n    sfd = Socket(AF_INET, SOCK_STREAM, 0);\n    \/\/ bind\n    struct sockaddr_in s_addr, c_addr;\n    socklen_t addrlen = sizeof(struct sockaddr_in);\n    bzero(&amp;s_addr, addrlen);\n    bzero(&amp;c_addr, addrlen);\n    s_addr.sin_family = AF_INET;\n    s_addr.sin_addr.s_addr = htonl(INADDR_ANY);\n    s_addr.sin_port = htons(3000);\n    int sockopt = 1;\n    setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &amp;sockopt, sizeof(sockopt));\n    Bind(sfd, &amp;s_addr, addrlen);\n    Listen(sfd, 128);\n\n    \/\/ pollfd\n    struct pollfd fds[OPEN_MAX];\n    fds[0].fd = sfd;\n    fds[0].events = POLLIN;\n\n    int i, maxi;\n    for(i = 1; i &lt; OPEN_MAX; i++){\n        fds[i].fd = -1;\n    }\n    maxi = 0;\n\n    nfds_t maxfd = sfd;\n    int pollret;\n    while(1){\n        pollret = poll(fds, maxfd + 1, -1);\n        if (pollret &lt; 0){\n            perror(\"poll error\");\n            exit(1);\n        }\n        \/\/ 1\u3001\u5224\u65ad\u662f\u5426\u6709\u65b0\u8fde\u63a5\n        if (fds[0].revents &amp; POLLIN){\n            cfd = Accept(sfd, &amp;c_addr, &amp;addrlen);\n            char address[INET_ADDRSTRLEN];\n            printf(\"A new client -- %s:%d\\n\",\n                    inet_ntop(AF_INET, &amp;c_addr.sin_addr.s_addr, address, INET_ADDRSTRLEN),\n                    ntohs(c_addr.sin_port));\n            for(i = 1; i &lt; OPEN_MAX; i++){\n                if (fds[i].fd != -1) continue;\n                fds[i].fd = cfd;\n                fds[i].events = POLLIN;\n                break;\n            }\n            if (maxfd &lt; cfd) maxfd = cfd;\n            if (maxi &lt; i) maxi = i;\n            if (--pollret == 0) continue;\n        }\n        \/\/ 2\u3001\u5224\u65ad\u662f\u5426\u6709\u6570\u636e\u4ea4\u4e92\n        for (i = 1; i &lt;= maxi; i++){\n            int fd = fds[i].fd;\n            if (fd == -1) continue;\n            \/\/ \u6709\u8bfb\u6570\u636e\n            if (fds[i].revents &amp; POLLIN){\n                char buf[BUFSIZ];\n                int n = Readn(fd, buf, BUFSIZ);\n                printf(\"readed %d bytes\\n\", n);\n                if (n &lt;= 0){\n                    close(fd);\n                    fds[i].fd = -1;\n                    continue;\n                }\n                \/\/ \u5904\u7406\u6570\u636e\n                for (i = 0; i &lt; n; i++){\n                    buf[i] = toupper(buf[i]);\n                }\n                write(fd, buf, n);\n                if (--pollret == -1) break;\n            }\n        }\n\n    }\n    return 0;\n}\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>1\u3001select\u51fd\u6570 #include &lt;sys\/select.h&gt; \/* According to earlier standards *\/ #include &lt;sys\/time.h&gt; #include &lt;sys\/types.h&gt; #include &lt;unistd.h&gt; int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); void FD_CLR(int fd, fd_set *set); int FD_ISSET(int fd, fd_set *set); void FD_SET(int fd, fd_set *set); void FD_ZERO(fd_set *set); demo\u793a\u4f8b<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[88],"tags":[310],"class_list":["post-1885","post","type-post","status-publish","format-standard","hentry","category-cpp","tag-linux"],"_links":{"self":[{"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/posts\/1885","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/comments?post=1885"}],"version-history":[{"count":0,"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/posts\/1885\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/media?parent=1885"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/categories?post=1885"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/tags?post=1885"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}