我的问题比以下场景更通用,尽管这涵盖了所需的一切。这是针对Java和socket编程的正确做法。
设想:
一台服务器有多个客户端。非阻塞 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
?如果缓冲区不够大?
如果是 a write
,我也可以这样做吗socketChannel.write(buffer)
(至少从程序的角度来看)?
这里的文档没有指定所有传入数据都适合缓冲区的情况。当我有阻塞 I/O 时,这也会让人有点困惑:
然而,可以保证的是,如果通道处于阻塞模式并且缓冲区中至少剩余一个字节,则此方法将阻塞,直到至少读取一个字节。
这是否意味着这里(阻塞 I/O)我需要以任何一种方式read
通过while
循环(我发现的大多数示例都是这样做的)?做手术怎么办write
?
所以,总而言之,我的问题是,从中间服务器(客户端到第二个服务器)的角度来看,在我的场景中读写数据的正确方法是什么?
白板的微信
相关分类