AIO异步非阻塞学习
Client:客户端
package aio; import java.io.UnsupportedEncodingException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousSocketChannel; import java.util.concurrent.ExecutionException; /** * * @Description:异步非阻塞 * @date 2018年8月4日,下午4:06:55 */ public class Client implements Runnable{ //异步客户端通道 private AsynchronousSocketChannel asc ; //调用客户端则打开通道 public Client() throws Exception { asc = AsynchronousSocketChannel.open(); } //客户端的连接 public void connect(){ asc.connect(new InetSocketAddress("127.0.0.1", 8765)); } //写操作 public void write(String request){ try { //把客户端的数据写入缓冲区交给服务端 asc.write(ByteBuffer.wrap(request.getBytes())).get(); read(); } catch (Exception e) { e.printStackTrace(); } } //读操作 private void read() { //创建字节缓冲区大小 ByteBuffer buf = ByteBuffer.allocate(1024); try { //读取服务端响应的数据 asc.read(buf).get(); //复位 buf.flip(); byte[] respByte = new byte[buf.remaining()]; buf.get(respByte); System.out.println("读取服务器响应的数据----》"+new String(respByte,"utf-8").trim()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } //防止程序停止运行 @Override public void run() { while(true){ } } public static void main(String[] args) throws Exception { //new一个Client客户端,则打开一个客户端通道 Client c1 = new Client(); c1.connect(); Client c2 = new Client(); c2.connect(); Client c3 = new Client(); c3.connect(); new Thread(c1, "c1").start(); new Thread(c2, "c2").start(); new Thread(c3, "c3").start(); Thread.sleep(1000); c1.write("c1 aaa"); c2.write("c2 bbbb"); c3.write("c3 ccccc"); } } Client:客户端
Server:服务器端
package aio; import java.net.InetSocketAddress; import java.nio.channels.AsynchronousChannelGroup; import java.nio.channels.AsynchronousServerSocketChannel; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Server { //线程池 //jdk api功能说明:一个Executor,提供管理终止的方法和可以生成Future的方法,用于跟踪一个或多个异步任务的进度。 private ExecutorService executorService; //线程组 private AsynchronousChannelGroup threadGroup; //服务器通道 //jdk api功能说明:用于资源共享的一组异步通道。 public AsynchronousServerSocketChannel assc; public Server(int port){ try { //创建一个缓存池 executorService = Executors.newCachedThreadPool(); //创建线程组 //jdk api功能说明:创建具有给定线程池的异步通道组,该线程池根据需要创建新线程。 threadGroup = AsynchronousChannelGroup.withCachedThreadPool(executorService, 1); //打开服务器通道 assc = AsynchronousServerSocketChannel.open(threadGroup); //进行绑定 assc.bind(new InetSocketAddress(port)); System.out.println("server start , port : " + port); //进行阻塞 assc.accept(this, new ServerCompletionHandler()); //一直阻塞 不让服务器停止 Thread.sleep(Integer.MAX_VALUE); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { Server server = new Server(8765); } }
ServerCompletionHandler:服务器端数据处理
package aio; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousSocketChannel; import java.nio.channels.CompletionHandler; import java.util.concurrent.ExecutionException; /** * @Description:服务器数据处理 * @date 2018年8月5日,下午12:35:39 */ //CompletionHandler<AsynchronousSocketChannel, Server>:AsynchronousSocketChannel是固定不变的,Server:是指服务器类 //必须覆写成功completed()和失败failed()两个方法 public class ServerCompletionHandler implements CompletionHandler<AsynchronousSocketChannel, Server> { @Override public void completed(AsynchronousSocketChannel asc, Server attachment) { //当有下一个客户端接入的时候 直接调用Server的accept方法,这样反复执行下去,保证多个客户端都可以阻塞 //使用递归 attachment.assc.accept(attachment, this); read(asc); } private void read(final AsynchronousSocketChannel asc) { //读取数据 ByteBuffer buf = ByteBuffer.allocate(1024); asc.read(buf, buf, new CompletionHandler<Integer, ByteBuffer>() { @Override public void completed(Integer resultSize, ByteBuffer attachment) { //进行读取之后,重置标识位 attachment.flip(); //获得读取的字节数 System.out.println("Server -> " + "收到客户端的数据长度为:" + resultSize); //获取读取的数据 String resultData = new String(attachment.array()).trim(); System.out.println("Server -> " + "收到客户端的数据信息为:" + resultData); String response = "服务器响应, 收到了客户端发来的数据: " + resultData; write(asc, response); } @Override public void failed(Throwable exc, ByteBuffer attachment) { exc.printStackTrace(); } }); } private void write(AsynchronousSocketChannel asc, String response) { try { ByteBuffer buf = ByteBuffer.allocate(1024); buf.put(response.getBytes()); buf.flip(); asc.write(buf).get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } @Override public void failed(Throwable exc, Server attachment) { exc.printStackTrace(); } }
美梦成真,变为事实。