学习一下nio中的Scattering与Gathering,这在netty中非常的常用。也非常的重要
package com.miaomiao.nio;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
public class NioTest2 {
public static void main(String[] args) throws IOException {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
InetSocketAddress address = new InetSocketAddress(8899);
serverSocketChannel.socket().bind(address);
int messageLength =2+3+4;
ByteBuffer[] buffers = new ByteBuffer[3];
buffers[0] = ByteBuffer.allocate(2);
buffers[1] = ByteBuffer.allocate(3);
buffers[2] = ByteBuffer.allocate(4);
SocketChannel socketChannel = serverSocketChannel.accept();
while (true){
int bytesRead = 0;
while(bytesRead<messageLength){
long r = socketChannel.read(buffers);
bytesRead +=r;
System.out.println("bytesRead:"+bytesRead);
for (ByteBuffer buffer : buffers) {
System.out.println("position:"+buffer.position()+",limit:"+buffer.limit());
}
}
System.out.println("读入已经结束");
for (ByteBuffer buffer : buffers) {
buffer.flip();
}
long bytesWritten =0;
while(bytesWritten<messageLength){
long r = socketChannel.write(buffers);
bytesWritten +=r;
}
for (ByteBuffer buffer : buffers) {
buffer.clear();
}
System.out.println("bytesRead:"+bytesRead+",bytesWritten:"+bytesWritten+",messageLength:"+messageLength);
}
}
}
因为我这里是mac,所以我这里直接打开终端用命令:nc 127.0.0.1 8899 进行测试访问
大家可以输入8个字符,加一个回车,正好是9个字符。这就是一个大的while循环。
当大家输入的字符不满messageLength,
long r = socketChannel.read(buffers);
此代码会在此处进行等待终端的输入
这里会有这几种情况
- 终端输入刚好满足messageLength的大小,就刚好进行一轮的循环
- 终端输入小于messageLength的大小
while(bytesRead<messageLength){ long r = socketChannel.read(buffers); bytesRead +=r; System.out.println("bytesRead:"+bytesRead); for (ByteBuffer buffer : buffers) { System.out.println("position:"+buffer.position()+",limit:"+buffer.limit()); } }
会在此循环处,等待刚好满足 messageLength的大小,进行一轮的循环
-
终端输入大于messageLength的大小,把刚好满足的字符,进行一轮循环,多余的字符进行下一轮的循环