Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between java nio select and linux epoll?

The code for java nio select and the code for linux epoll look the same. There is no such thing as loop to get socket fd, and the linux select code fragment does use loop to get socket fd.

So my question is, is the java nio select and linux epoll the same way?

java nio select


        while (true) {
            try {
                selector.select();
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                selectionKeys.forEach((selectionKey) -> {
                    final SocketChannel client;
                    try {
                        if (selectionKey.isAcceptable()) {
                            ServerSocketChannel server = (ServerSocketChannel) selectionKey.channel();
                            client = server.accept();
                            client.configureBlocking(false);
                            client.register(selector, SelectionKey.OP_READ);

                            String key = "[" + UUID.randomUUID().toString() + "]";

                            clientMap.put(key, client);
                        } else if (selectionKey.isReadable()) {
                            client = (SocketChannel) selectionKey.channel();

                            ByteBuffer readBuffer = ByteBuffer.allocate(1024);

                            int count = client.read(readBuffer);
                            if (count > 0) {
                                //...
                            }

                        }
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                });

                selectionKeys.clear();

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

linux e poll

   for (;;) {
        nfds = epoll_wait(epfd, events, 20, 500);

        for (i = 0; i < nfds; ++i) {
            if (events[i].data.fd == listenfd)

            {
                connfd = accept(listenfd, (sockaddr *) &clientaddr, &clilen);
                if (connfd < 0) {
                    perror("connfd<0");
                    exit(1);
                }
                //setnonblocking(connfd);

                char *str = inet_ntoa(clientaddr.sin_addr);
                ev.data.fd = connfd;

                ev.events = EPOLLIN | EPOLLET;

                epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev);
            } else if (events[i].events & EPOLLIN)

            {
                cout << "EPOLLIN" << endl;
                if ((sockfd = events[i].data.fd) < 0)
                    continue;
                if ((n = read(sockfd, line, MAXLINE)) < 0) {
                    if (errno == ECONNRESET) {
                        close(sockfd);
                        events[i].data.fd = -1;
                    } else
                        std::cout << "readline error" << std::endl;
                } else if (n == 0) {
                    close(sockfd);
                    events[i].data.fd = -1;
                }
                line[n] = '/0';
                cout << "read " << line << endl;

                ev.data.fd = sockfd;

                ev.events = EPOLLOUT | EPOLLET;

                //epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);

            } else if (events[i].events & EPOLLOUT) 
            {
                sockfd = events[i].data.fd;
                write(sockfd, line, n);

                ev.data.fd = sockfd;

                ev.events = EPOLLIN | EPOLLET;

                epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
            }
        }
    }

linux select


    for (;;) {
        rset = allset;        /* structure assignment */
        nready = select(maxfd + 1, &rset, NULL, NULL, NULL);

        if (FD_ISSET(listenfd, &rset)) /* new client connection */
        {
            clilen = sizeof(cliaddr);
            connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen);
#ifdef    NOTDEF
            printf("new client: %s, port %d\n",
                    inet_ntop(AF_INET, &cliaddr.sin_addr, 4, NULL),
                    ntohs(cliaddr.sin_port));
#endif

            for (i = 0; i < FD_SETSIZE; i++)
                if (client[i] < 0) {
                    client[i] = connfd;    /* save descriptor */
                    break;
                }
            if (i == FD_SETSIZE) {
                printf("too many clients");
                exit(0);
            }

            FD_SET(connfd, &allset);    /* add new descriptor to set */
            if (connfd > maxfd)
                maxfd = connfd;            /* for select */
            if (i > maxi)
                maxi = i;                /* max index in client[] array */

            if (--nready <= 0)
                continue;                /* no more readable descriptors */
        }

        for (i = 0; i <= maxi; i++)    /* check all clients for data */
        {
            if ((sockfd = client[i]) < 0)
                continue;
            if (FD_ISSET(sockfd, &rset)) {
                if ((n = read(sockfd, buf, MAXLINE)) == 0)/* connection closed by client */
                {
                    close(sockfd);
                    FD_CLR(sockfd, &allset);
                    client[i] = -1;
                } else
                    write(sockfd, buf, n);

                if (--nready <= 0)
                    break;                /* no more readable descriptors */
            }
        }
    }

like image 566
lvqiang Avatar asked Jul 21 '26 19:07

lvqiang


1 Answers

JAVA NIO is Java's abstraction of non-blocking io. There will be different underlying implementations on different platforms. On Linux, it is implemented using epool. On other platforms, other technologies such as kqueue are used.

This causes NIO to be very similar to epoll, but java wants you to learn its nio abstraction, without having to care about the underlying implementation.

like image 102
xiao yang Avatar answered Jul 23 '26 08:07

xiao yang



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!