<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                [TOC] ## 概述 今天無意中發現了關于epoll的問題,事情是這樣的,我在寫關于epoll的echo服務器程序, 客戶端連接上了之后,發消息,可以正常返回,但是當客戶端連接斷開后,服務端程序開始死循環,具體代碼如下: ``` #include <sys/epoll.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> int main() { int socketfd = socket(AF_INET, SOCK_STREAM, 0); if (socketfd == -1) return -1; struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = htons(8088); if (bind(socketfd, (struct sockaddr_in*)&addr, sizeof addr) == -1) { printf("bind error\n"); return -1; } if (listen(socketfd, 1024) == -1) { printf("listen error\n"); return -1; } int epoll_fd = epoll_create1(EPOLL_CLOEXEC); if (epoll_fd == -1) { printf("epoll_fd error\n"); return -1; } struct epoll_event event; event.data.fd = socketfd; event.events = EPOLLIN; epoll_ctl(epoll_fd, EPOLL_CTL_ADD,socketfd, &event); while (1) { int nfds = epoll_wait(epoll_fd, &event, 1024, -1); if (nfds <= 0) { continue; } if (event.data.fd == socketfd) { struct sockaddr_in connaddr; socklen_t addr_len = sizeof(connaddr); int connfd = accept(socketfd, (struct sockaddr*)&connaddr, &addr_len); if (connfd == -1) { printf("connfd error\n"); return -1; } event.data.fd = connfd; event.events = EPOLLIN; epoll_ctl(epoll_fd, EPOLL_CTL_ADD, connfd, &event); }else { int connfd = event.data.fd; char buf[1024]; int n = recv(connfd, buf, 1024, 0); if (n <= 0) { printf("recv error\n"); continue; } buf[n] = '\0'; printf("recv msg: %s\n", buf); } } } ``` 編譯&運行 ``` $ gcc -o server epoll.c $ ./server ``` 我使用的是 sokit當作客戶端,真的很好用,安利一波。 * 客戶端連接上8088端口,然后發送消息,正常。 * 斷開客戶端連接,服務器開始死循環不斷的輸出`printf("recv error\n");` 我在想,把監聽的描述符替換成了連接描述符 `connfd`,斷開客戶端連接后,epoll_wait 應該檢測不到有事件就緒了,應該是處于阻塞狀態的。 我引用一段epoll的manual page: ``` > Will closing a file descriptor cause it to be removed from all epoll sets automatically? > > Yes, but be aware of the following point. A file descriptor is a reference to an open file description (see open(2)). Whenever a descriptor is duplicated via dup(2), dup2(2), fcntl(2) F\_DUPFD, or fork(2), a new file descriptor referring to the same open file description is created. An open file description continues to exist until all file descriptors referring to it have been closed. A file descriptor is removed from an epoll set only after all the file descriptors referring to the underlying open file description have been closed (or before if the descriptor is explicitly removed using epoll\_ctl(2) EPOLL\_CTL\_DEL). This means that even after a file descriptor that is part of an epoll set has been closed, events may be reported for that file descriptor if other file descriptors referring to the same underlying file description remain open. ``` 總結起來就是一句話,epoll接口操作的是文件描述符,而epoll的內核維護的是文件描述。 http://www.ilovecpp.com/2019/01/20/effective-epoll/
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看