AioClient 客户端主程序
import static cn.enjoyedu.ch01.Ch01Const.DEFAULT_PORT;
import static cn.enjoyedu.ch01.Ch01Const.DEFAULT_SERVER_IP;
public class AioClient {
private static AioClientHandler clientHandle;
public static void start(){
if(clientHandle!=null)
return;
clientHandle = new AioClientHandler(DEFAULT_SERVER_IP,DEFAULT_PORT);
new Thread(clientHandle,"Client").start();
}
public static boolean sendMsg(String msg) throws Exception{
if(msg.equals("q")) return false;
clientHandle.sendMessag(msg);
return true;
}
public static void main(String[] args) throws Exception{
AioClient.start();
System.out.println("请输入请求消息:");
Scanner scanner = new Scanner(System.in);
while(AioClient.sendMsg(scanner.nextLine()));
}
}
Ch01Const常量类
public class Ch01Const {
public static int DEFAULT_PORT = 12345;
public static String DEFAULT_SERVER_IP = "127.0.0.1";
public static String response(String msg){
return "Hello,"+msg+",Now is "+new java.util.Date(
System.currentTimeMillis()).toString() ;
}
}
AioClientHandler通信处理器,负责连接服务器,对外暴露对服务端发送数据的API
public class AioClientHandler
implements CompletionHandler<Void,AioClientHandler>,Runnable {
private AsynchronousSocketChannel clientChannel;
private String host;
private int port;
private CountDownLatch latch;
public AioClientHandler(String host, int port) {
this.host = host;
this.port = port;
try {
clientChannel = AsynchronousSocketChannel.open();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
latch = new CountDownLatch(1);
clientChannel.connect(new InetSocketAddress(host,port),
null,this);
try {
latch.await();
clientChannel.close();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void completed(Void result, AioClientHandler attachment) {
System.out.println("已经连接到服务端。");
}
@Override
public void failed(Throwable exc, AioClientHandler attachment) {
System.err.println("连接失败。");
exc.printStackTrace();
latch.countDown();
try {
clientChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void sendMessag(String msg){
byte[] bytes = msg.getBytes();
ByteBuffer writeBuffer = ByteBuffer.allocate(bytes.length);
writeBuffer.put(bytes);
writeBuffer.flip();
clientChannel.write(writeBuffer,writeBuffer,
new AioClientWriteHandler(clientChannel,latch));
}
}
AioClientWriteHandler网络写的处理器
public class AioClientWriteHandler
implements CompletionHandler<Integer, ByteBuffer> {
private AsynchronousSocketChannel clientChannel;
private CountDownLatch latch;
public AioClientWriteHandler(AsynchronousSocketChannel clientChannel,
CountDownLatch latch) {
this.clientChannel = clientChannel;
this.latch = latch;
}
@Override
public void completed(Integer result, ByteBuffer buffer) {
if(buffer.hasRemaining()){
clientChannel.write(buffer,buffer,this);
}else{
ByteBuffer readBuffer = ByteBuffer.allocate(1024);
clientChannel.read(readBuffer,readBuffer,
new AioClientReadHandler(clientChannel,latch));
}
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
System.err.println("数据发送失败...");
try {
clientChannel.close();
latch.countDown();
} catch (IOException e) {
}
}
}
网络读的处理器
public class AioClientReadHandler
implements CompletionHandler<Integer, ByteBuffer> {
private AsynchronousSocketChannel clientChannel;
private CountDownLatch latch;
public AioClientReadHandler(AsynchronousSocketChannel clientChannel,
CountDownLatch latch) {
this.clientChannel = clientChannel;
this.latch = latch;
}
@Override
public void completed(Integer result,ByteBuffer buffer) {
buffer.flip();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
String msg;
try {
msg = new String(bytes,"UTF-8");
System.out.println("accept message:"+msg);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
@Override
public void failed(Throwable exc,ByteBuffer attachment) {
System.err.println("数据读取失败...");
try {
clientChannel.close();
latch.countDown();
} catch (IOException e) {
}
}
}
AioServer服务器主程序
public class AioServer {
private static AioServerHandler serverHandle;
public volatile static long clientCount = 0;
public static void start(){
if(serverHandle!=null)
return;
serverHandle = new AioServerHandler(DEFAULT_PORT);
new Thread(serverHandle,"Server").start();
}
public static void main(String[] args){
AioServer.start();
}
}
AioServerHandler响应网络操作的处理器
public class AioServerHandler implements Runnable {
public CountDownLatch latch;
public AsynchronousServerSocketChannel channel;
public AioServerHandler(int port) {
try {
channel = AsynchronousServerSocketChannel.open();
channel.bind(new InetSocketAddress(port));
System.out.println("Server is start,port:"+port);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
latch = new CountDownLatch(1);
channel.accept(this,new AioAcceptHandler());
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
AioAcceptHandler处理用户连接的处理器
public class AioAcceptHandler
implements CompletionHandler<AsynchronousSocketChannel,
AioServerHandler> {
@Override
public void completed(AsynchronousSocketChannel channel,
AioServerHandler serverHandler) {
AioServer.clientCount++;
System.out.println("连接的客户端数:" + AioServer.clientCount);
serverHandler.channel.accept(serverHandler,this);
ByteBuffer readBuffer = ByteBuffer.allocate(1024);
channel.read(readBuffer,readBuffer,
new AioReadHandler(channel));
}
@Override
public void failed(Throwable exc, AioServerHandler serverHandler) {
exc.printStackTrace();
serverHandler.latch.countDown();
}
}
AioReadHandler读数据的处理器
public class AioReadHandler
implements CompletionHandler<Integer, ByteBuffer> {
private AsynchronousSocketChannel channel;
public AioReadHandler(AsynchronousSocketChannel channel) {
this.channel = channel;
}
@Override
public void completed(Integer result, ByteBuffer attachment) {
if(result == -1) {
try {
channel.close();
} catch (IOException e) {
e.printStackTrace();
}
return;
}
attachment.flip();
byte[] message = new byte[attachment.remaining()];
attachment.get(message);
try {
System.out.println(result);
String msg = new String(message,"UTF-8");
System.out.println("server accept message:"+msg);
String responseStr = response(msg);
doWrite(responseStr);
} catch (Exception e) {
e.printStackTrace();
}
}
private void doWrite(String result) {
byte[] bytes = result.getBytes();
ByteBuffer writeBuffer = ByteBuffer.allocate(bytes.length);
writeBuffer.put(bytes);
writeBuffer.flip();
channel.write(writeBuffer, writeBuffer,
new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer attachment) {
if(attachment.hasRemaining()){
channel.write(attachment,attachment,this);
}else{
ByteBuffer readBuffer = ByteBuffer.allocate(1024);
channel.read(readBuffer,readBuffer,
new AioReadHandler(channel));
}
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
try {
channel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
try {
this.channel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}