1 package com.slp.nio; 2 3 import org.junit.Test; 4 5 import java.io.IOException; 6 import java.net.InetSocketAddress; 7 import java.nio.ByteBuffer; 8 import java.nio.channels.SelectionKey; 9 import java.nio.channels.Selector; 10 import java.nio.channels.ServerSocketChannel; 11 import java.nio.channels.SocketChannel; 12 import java.time.LocalDateTime; 13 import java.util.Date; 14 import java.util.Iterator; 15 import java.util.Scanner; 16 17 /** 18 * Created by sanglp on 2017/3/2. 19 * 一、使用NIO完成网络通信的三个核心 20 * 1、通道:负责连接 21 * |--java.nio.channels.channel接口 22 * |--SelectableChannel 23 * |--SocketChannel 24 * |--ServerSocketChannel 25 * |--DatagramChannel 26 * 27 * |--Pipe.SinkChannel 28 * |--Pipe.SourceChannel 29 * 2、缓冲区:负责数据的存取 30 * 3、选择器:是SelectableChannel的多路复用器,用于监控SelectableChannel的IO状况 31 * 32 */ 33 public class TestNonBlockingNIO { 34 35 @Test 36 public void client() throws IOException { 37 //获取通道 38 SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1",9898)); 39 //切换为非阻塞模式 40 socketChannel.configureBlocking(false); 41 //分配缓冲区 42 ByteBuffer buf = ByteBuffer.allocate(1024); 43 //发送数据给服务端 44 45 Scanner scanner = new Scanner(System.in); 46 while (scanner.hasNext()){ 47 String str = scanner.next(); 48 buf.put((new Date().toString()+"\n"+str).getBytes()); 49 buf.flip(); 50 socketChannel.write(buf); 51 buf.clear(); 52 } 53 54 55 //关闭通道 56 socketChannel.close(); 57 58 } 59 60 @Test 61 public void server() throws IOException { 62 //获取通道 63 ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); 64 //切换非阻塞模式 65 serverSocketChannel.configureBlocking(false); 66 //绑定连接 67 serverSocketChannel.bind(new InetSocketAddress(9898)); 68 //获取一个选择器 69 Selector selector = Selector.open(); 70 //将通道注册到选择器上 并且指定监听接收事件 71 serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); 72 //轮询式的获取选择器上已经准备就绪的事件 73 while (selector.select()>0){ 74 //获取当前选择器中所有注册的选择键(已就绪的监听事件) 75 Iterator<SelectionKey> it = selector.selectedKeys().iterator(); 76 while (it.hasNext()){ 77 //获取准备就绪的事件 78 SelectionKey sk = it.next(); 79 //判断具体是什么事件准备就绪 80 if(sk.isAcceptable()){ 81 //获取额护短连接 82 SocketChannel socketChannel = serverSocketChannel.accept(); 83 //切换非阻塞模式 84 socketChannel.configureBlocking(false); 85 //将该通道注册到选择器上 86 socketChannel.register(selector,SelectionKey.OP_READ); 87 }else if(sk.isReadable()){ 88 //获取当前选择器上读就绪状态的通道 89 SocketChannel socketChannel = (SocketChannel) sk.channel(); 90 //读取数据 91 ByteBuffer buffer = ByteBuffer.allocate(1024); 92 int len =0; 93 while ((len=socketChannel.read(buffer))>0){ 94 buffer.flip(); 95 System.out.println(new String(buffer.array(),0,len)); 96 buffer.clear(); 97 } 98 } 99 //取消选择键 100 it.remove(); 101 } 102 } 103 } 104 }
时间: 2024-10-14 09:01:58