gpt4 book ai didi

java - java nio select 和 linux epoll 有什么区别?

转载 作者:行者123 更新时间:2023-12-02 09:33:54 24 4
gpt4 key购买 nike

java nio select 的代码和 linux epoll 的代码看起来是一样的。不存在循环获取socket fd这样的东西,linux select代码片段确实使用了循环获取socket fd。

所以我的问题是,java nio select 和 linux epoll 是一样的吗?

java nio选择


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 电子投票

   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选择


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 */
}
}
}

最佳答案

JAVA NIO是Java对非阻塞io的抽象。不同平台上会有不同的底层实现。在Linux上,它是使用epool实现的。在其他平台上,使用其他技术,例如kqueue。

这导致NIO与epoll非常相似,但是java希望你学习它的nio抽象,而不必关心底层实现。

关于java - java nio select 和 linux epoll 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57706441/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com