//客户端
@Test
public void client() throws IOException{
//1. 获取通道
SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1",8989));
//2. 切换非阻塞模式
socketChannel.configureBlocking(false);
//3. 分配指定大小的缓冲区
ByteBuffer buffer = ByteBuffer.allocate(1024);
//4. 发送数据给服务端
Scanner scanner = new Scanner(System.in);
while(scanner.hasNext()){
String data = scanner.next();
buffer.put((LocalDateTime.now().toString()+"\n" + data).getBytes());
buffer.flip();
socketChannel.write(buffer);
buffer.clear();
}
//5.关闭通道
socketChannel.close();
}
//服务端
@Test
public void server() throws IOException{
//1. 获取通道
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
//2. 切换非阻塞模式
serverSocketChannel.configureBlocking(false);
//3. 绑定连接
serverSocketChannel.bind(new InetSocketAddress(8989));
//4. 获取选择器
Selector selector = Selector.open();
//5. 将通道注册到选择器上, 并且指定“监听接收事件”
serverSocketChannel.register(selector,SelectionKey.OP_ACCEPT);
//6. 轮询式的获取选择器上已经“准备就绪”的事件
while(selector.select() > 0){
//7. 获取当前选择器中所有注册的“选择键(已就绪的监听事件)”
Set<SelectionKey> set = selector.selectedKeys();
Iterator<SelectionKey> it = set.iterator();
while(it.hasNext()){
//8. 获取准备“就绪”的是事件
SelectionKey selectionKey = it.next();
//9. 判断具体是什么事件准备就绪
if(selectionKey.isAcceptable()){
//10. 若“接收就绪”,获取客户端连接
SocketChannel socketChannel = serverSocketChannel.accept();
//11. 切换非阻塞模式
socketChannel.configureBlocking(false);
//12. 将该通道注册到选择器上
socketChannel.register(selector,selectionKey.OP_READ);
}else if(selectionKey.isReadable()){
//13. 获取当前选择器上“读就绪”状态的通道
SocketChannel socketChannel = (SocketChannel)selectionKey.channel();
//14. 读取数据
ByteBuffer buf = ByteBuffer.allocate(1024);
int len = 0;
while((len = socketChannel.read(buf)) > 0){
buf.flip();
System.out.println(new String(buf.array(),0,len));
buf.clear();
}
}
}
//15. 取消选择键 SelectionKey
it.remove();
}
}
使用Channel、Buffer、Selector完成网络通信--非阻塞(一)
最新推荐文章于 2022-09-16 09:27:03 发布