网络通讯的同步:是指客户端和服务器端直接的通讯等待方式。这里的同步的反义词是异步,即无需等待另外一段操作完成。
AIO(Asynchronous I/O,异步I/O)
采用回调方法进行处理读写操作
- 异步非阻塞的通讯方式,就是不需要等待一方的数据操作完成,会自动执行回调函数处理的读写操作
- 主要类
- (1) AsynchronousServerSocketChannel 服务器接收请求通道
- bind 绑定到某个端口 accept 接受客户端请求
- (2) AsynchronousSocketChannel Socket 通讯通道
- read 读数据 write 写数据
- (3) CompletionHandler 异步处理类
- completed 操作完成后异步调用方法 failed 操作失败后异步调用方法
示例代码:
AioServer代码
package com.lihuan.network.demo06;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
public class AioServer {
public static void main(String[] args) throws IOException {
//创建服务器接收请求对象
final AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open();
//绑定IP与端口
server.bind(new InetSocketAddress("localhost", 8001));
System.out.println("服务器在8001端口守候...");
//开始等待客户端连接,一旦有连接,做completed任务
server.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() {
@Override
public void completed(final AsynchronousSocketChannel channel, Object attachment) {
server.accept(null, this); //持续接收新的客户端请求
ByteBuffer buffer = ByteBuffer.allocate(1024); //准备读取空间
//开始读取客户端内容,一旦读取结束做completed任务
channel.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer attachment) {
attachment.flip(); //反转此Buffer
CharBuffer charBuffer = CharBuffer.allocate(1024);
CharsetDecoder decoder = Charset.defaultCharset().newDecoder();
decoder.decode(attachment, charBuffer, false);
charBuffer.flip();
String data = new String(charBuffer.array(), 0, charBuffer.limit());
System.out.println("client said: " + data);
channel.write(ByteBuffer.wrap((data + " 666").getBytes()));
try {
channel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
System.out.println("read error " + exc.getMessage());
}
});
}
@Override
public void failed(Throwable exc, Object attachment) {
System.out.println("read error " + exc.getMessage());
}
});
while (true){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
AioClient代码
package com.lihuan.network.demo06;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.UUID;
public class AioClient {
public static void main(String[] args) {
try {
final AsynchronousSocketChannel channel = AsynchronousSocketChannel.open();
channel.connect(new InetSocketAddress("localhost", 8001), null, new CompletionHandler<Void, Object>() {
@Override
public void completed(Void result, Object attachment) {
final String str = UUID.randomUUID().toString();
channel.write(ByteBuffer.wrap(str.getBytes()), null,
new CompletionHandler<Integer, Object>() {
@Override
public void completed(Integer result, Object attachment) {
System.out.println("write " + str + ", and wait response");
ByteBuffer buffer = ByteBuffer.allocate(1024);
channel.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer attachment) {
attachment.flip();
CharBuffer charBuffer = CharBuffer.allocate(1024);
CharsetDecoder decoder = Charset.defaultCharset().newDecoder();
decoder.decode(attachment, charBuffer, false);
charBuffer.flip();
String data = new String(charBuffer.array(), 0, charBuffer.limit());
System.out.println("server said: " + data);
try {
channel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
System.out.println("read error " + exc.getMessage());
}
});
}
@Override
public void failed(Throwable exc, Object attachment) {
System.out.println("read error " + exc.getMessage());
}
});
}
@Override
public void failed(Throwable exc, Object attachment) {
System.out.println("read error " + exc.getMessage());
}
});
Thread.sleep(10000);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
每一个CompletionHandler 都可以定义俩个方法:completed和failed方法,当操作成功自动运行completed方法,失败自动调用failed方法