package com.hao.demo.netty.nio;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Arrays;
/**
* @author
* @date 2020-05-13
*/
public class SactteringAndGatheringTest {
/**
* 1、Sacttering:将数据写入到buffer时,可以采用buffer数组 依次写入 分散
* 2、Gathering:采用buffer读取数据时,可以采用buffer数组 依次读
* 3、 测试的话 telent 127.0.0.1 7000
* @param args
*/
public static void main(String[] args) throws Exception {
// 使用 ServerSocketChannel 和 SocketChannel 网络
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
InetSocketAddress inetSocketAddress = new InetSocketAddress(7000);
// 绑定端口 并启动
serverSocketChannel.socket().bind(inetSocketAddress);
// 创建buffer数组
ByteBuffer[] byteBuffers = new ByteBuffer[2];
byteBuffers[0] = ByteBuffer.allocate(5);
byteBuffers[1] = ByteBuffer.allocate(3);
// 等待客户端连接
SocketChannel socketChannel = serverSocketChannel.accept();
int messageLength = 8; // 假定从客户端接收8个字节
// 循环读取
while (true) {
int byteRead = 0;
while (byteRead < 8) {
long l = socketChannel.read(byteBuffers);
System.out.println("byteRead=" + byteRead);
byteRead += 1; // 累计读取的字节
// 使用流打印, 看看当前的这个buffer的position 和 limit
Arrays.asList(byteBuffers).stream().map(byteBuffer -> "position =" +
byteBuffer.position() + ", limit =" + byteBuffer.limit()).forEach(System.out::println);
}
// 将所有的buffer 进行反转
Arrays.asList(byteBuffers).forEach(ByteBuffer::flip);
long byteWrite = 0;
while (byteWrite < messageLength) {
long l = socketChannel.write(byteBuffers);// 回送
byteWrite += 1; // 累计写入的字节
}
// 将所有的buffer 复位 clear
Arrays.asList(byteBuffers).forEach(ByteBuffer::clear);
System.out.println("byteRead: = "+ byteRead + "byteWriter: =" +byteWrite
+ "messageLength =" + messageLength);
}
}
}