04-netty基础-AIO编程

1.JDK1.7升级了NIO类库,升级后的NIO类库被称为NIO 2.0,Java 正式提供了异步文件I/O操作,同时提供了与UNIX网络编程实践驱动I/O对应的AIO。

2.NIO 2.0引入了新的异步通道的概念,并提供了异步文件通道和异步套接字通道的实现,异步通道提供两种方式获取通道结果。

一是通过java.util.concurrent.Future 类来表示异步操作的结果。

二是在执行异步操作的时候传入一个java.nio.channels。

CompletionHandler接口的实现类作为操作完成的回调。

NIO 2.0的异步套接字通道是真正的异步非阻塞I/O,对应于UNIX网络编程实践驱动I/O(AIO)。它不需要通过多路复用器(Selector)对注册的通道进行轮询操作即可实现异步读写,从而简化了NIO 的编程模型。

3.AIO TimeServer.java 源码:

package com.pats.file.aio;

public class TimeServer {
 
	public static void main(String[] args) {
	int port = 8080;
	if(args != null&& args.length > 0 ) {
     port = Integer.valueOf(args[0]);		
	}
	AsyncTimeServerHandler timeServer = new AsyncTimeServerHandler(port);

	new Thread(timeServer,"NIO-MultiplexerTimeServer-001").start();
}
}

AsyncTimeServerHandler.java

package com.pats.file.aio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.util.concurrent.CountDownLatch;

public class AsyncTimeServerHandler implements Runnable{

	private int port;
	CountDownLatch latch;
	AsynchronousServerSocketChannel asynchronousServerSocketChannel;
	
	public AsyncTimeServerHandler(int port) {
     this.port = port;
     try {
		asynchronousServerSocketChannel = AsynchronousServerSocketChannel.open();
		asynchronousServerSocketChannel.bind(new InetSocketAddress(port));
		System.out.println("The time server is start in port : "+ port);
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	}
	@Override
	public void run() {

		latch = new CountDownLatch(1);
		doAccept();
		try {
			latch.await();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private void doAccept() {

		asynchronousServerSocketChannel.accept(this, new AcceptCompletionHandler());
		
	}

}

AcceptCompletionHandler.java

package com.pats.file.aio;

import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;

public class AcceptCompletionHandler implements CompletionHandler {
   
	
	@Override
	public void completed(AsynchronousSocketChannel result, AsyncTimeServerHandler attachment) {

		attachment.asynchronousServerSocketChannel.accept(attachment,this);
		ByteBuffer buffer = ByteBuffer.allocate(1024);
		result.read(buffer,buffer,new ReadCompletionHandler(result));
		
	}

	@Override
	public void failed(Throwable exc, AsyncTimeServerHandler attachment) {

		exc.printStackTrace();
		attachment.latch.countDown();
	}



}

4.AIO创建 TimeClient.java 源码:

package com.pats.file.aio;


public class TimeClient {

	public static void main(String[] args) {
		
		int port = 8080;
		if(args!=null && args.length > 0) {
			port = Integer.valueOf(args[0]);
		}
	  new Thread(new AsyncTimeClientHandler("127.0.0.1", port),"Aio-AsyncTimeClientHandler-001").start();	
		
}
}

AsyncTimeClientHandler.java

package com.pats.file.aio;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.CountDownLatch;



public class AsyncTimeClientHandler implements CompletionHandler,Runnable {

	private AsynchronousSocketChannel client;
	private String host;
	private int port;
	private CountDownLatch latch;
	
	
	public AsyncTimeClientHandler(String host, int port) {
    this.host = host;
    this.port = port;
    try {
		client = AsynchronousSocketChannel.open();
		
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	}
	
	@Override
	public void run() {

		latch = new CountDownLatch(1);
		client.connect(new InetSocketAddress(host, port),this,this);
		try {
			latch.await();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			client.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	@Override
	public void completed(Void result, AsyncTimeClientHandler attachment) {
		byte[] req = "QUERY TIME ORDER".getBytes();
		ByteBuffer writeBuffer = ByteBuffer.allocate(req.length);
		writeBuffer.put(req);
		writeBuffer.flip();
		client.write(writeBuffer, writeBuffer, new CompletionHandler() {

			@Override
			public void completed(Integer result, ByteBuffer buffer) {
            if(buffer.hasRemaining()) {
            	client.write(buffer,buffer,this);
            }else {
              ByteBuffer readBuffer = ByteBuffer.allocate(1024);
              client.read(readBuffer,readBuffer,new CompletionHandler() {

				@Override
				public void completed(Integer result, ByteBuffer buffer) {
					buffer.flip();
					byte[] bytes = new byte[buffer.remaining()];
					buffer.get(bytes);
					String body;
					
					try {
						body = new String(bytes,"UTF-8");
						System.out.println("Now is : "+ body);
						latch.countDown();
					} catch (UnsupportedEncodingException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}

				@Override
				public void failed(Throwable exc, ByteBuffer attachment) {
					try {
						client.close();
						latch.countDown();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
            	  
			});
            }
				
			}

			@Override
			public void failed(Throwable exc, ByteBuffer buffer) {
				try {
					client.close();
					latch.countDown();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
	}

	@Override
	public void failed(Throwable exc, AsyncTimeClientHandler attachment) {
		exc.printStackTrace();
		try {
			client.close();
			latch.countDown();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}


}

ReadCompletionHandler.java

package com.pats.file.aio;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.Date;

public class ReadCompletionHandler implements CompletionHandler {

    private AsynchronousSocketChannel channel;
    
    public ReadCompletionHandler( AsynchronousSocketChannel channel) {
        if(this.channel == null) 
        this.channel = channel;
        
    }
	@Override
	public void completed(Integer result, ByteBuffer attachment) {
		attachment.flip();
		byte[] body = new byte[attachment.remaining()];
		attachment.get(body);
		
		try {
			String req = new String(body,"UTF-8");
			System.out.println("The time server receive order : "+req);
			String currentTime = "QUERY TIME ORDER".equalsIgnoreCase(req)? new Date(System.currentTimeMillis()).toString() : "BAD ORDER";
    		doWrite(currentTime);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

	private void doWrite(String currentTime) {

		if(currentTime!=null && currentTime.trim().length() > 0) {
		byte[] bytes = (currentTime).getBytes();
		ByteBuffer writeBuffer = ByteBuffer.allocate(bytes.length);
		writeBuffer.put(bytes);
		writeBuffer.flip();
		channel.write(writeBuffer,writeBuffer,new CompletionHandler() {

			@Override
			public void completed(Integer result, ByteBuffer buffer) {
			//:如果没有发送完继续发送	
             if(buffer.hasRemaining()) {
            	channel.write(buffer,buffer,this); 
             }
				
			}

			@Override
			public void failed(Throwable exc, ByteBuffer attachment) {
             try {
				channel.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
				
			}
			
			
			
		});
		}
	}
	@Override
	public void failed(Throwable exc, ByteBuffer attachment) {
		try {
			this.channel.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
	}

}

5.运行程序:

客户端:

04-netty基础-AIO编程_第1张图片

服务端:

04-netty基础-AIO编程_第2张图片

 

 

你可能感兴趣的:(netty)