我的问题比以下场景更通用,尽管这个场景包含了所需的一切。它是关于Java和套接字编程的正确实践。
场景: - 一个服务器有多个客户端。使用非阻塞I/O。 - 该服务器是另一个服务器的客户端。使用阻塞I/O。 - 每种情况有两种情况:在一个情况下,所有数据都适合分配的字节缓冲区,而在第二种情况下,它们不适合(仅适用于一个迭代,而不是程序的生命周期)。
我找到的所有非阻塞I/O的示例都像这样。
这里的
在
场景: - 一个服务器有多个客户端。使用非阻塞I/O。 - 该服务器是另一个服务器的客户端。使用阻塞I/O。 - 每种情况有两种情况:在一个情况下,所有数据都适合分配的字节缓冲区,而在第二种情况下,它们不适合(仅适用于一个迭代,而不是程序的生命周期)。
我找到的所有非阻塞I/O的示例都像这样。
InetAddress host = InetAddress.getByName("localhost");
Selector selector = Selector.open();
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.bind(new InetSocketAddress(host, 1234));
serverSocketChannel.register(selector, SelectionKey. OP_ACCEPT);
while (true) {
if (selector.select() <= 0)
continue;
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectedKeys.iterator();
while (iterator.hasNext()) {
key = (SelectionKey) iterator.next();
iterator.remove();
if (key.isAcceptable()) {
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
// Do something or do nothing
}
if (key.isReadable()) {
SocketChannel socketChannel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
socketChannel.read(buffer);
// Something something dark side
if (result.length() <= 0) {
sc.close();
// Something else
}
}
}
这里的
read
是否会读取来自特定客户端和请求的所有传入数据(如果缓冲区足够大),或者我需要将其放在while
循环中?如果缓冲区不够大怎么办?在
write
的情况下,我只需要执行socketChannel.write(buffer)
,程序就可以继续运行吗?
此处的文档没有说明当所有传入数据都适合缓冲区时的情况。当我使用阻塞I/O时,这也使得问题有点混乱:
这是否意味着在这里(阻塞I/O)我无论如何都需要通过但是,如果通道处于阻塞模式并且缓冲区中至少剩余一个字节,则保证此方法将阻塞,直到读取至少一个字节。
while
循环进行read
(大多数我找到的示例都是这样做的)?那写操作呢?
总之,我的问题是,从中间服务器(客户端到第二个服务器)的角度来看,在我的情况下读写数据的正确方法是什么?
if (socketChannel.read(buffer) < 0)
。 - user207421