一 需求
使用 AsynchronousServerSocketChannel 搭建服务端,使用 AsynchronousSokectChannel 搭建客户端,完成客户端和服务端的一次通信。
二 实战
1 服务端代码
package aio;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
public class AIOServer {
public static void main(String[] args) throws Exception {
final AsynchronousServerSocketChannel channel = AsynchronousServerSocketChannel
.open()
.bind(new InetSocketAddress("127.0.0.1", 8888));
while (true) {
//接 收客户端请求的连接
channel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {
// 当接收到连接时,触发 completed()
@Override
public void completed(final AsynchronousSocketChannel client, Void attachment) {
channel.accept(null, this);
ByteBuffer buffer = ByteBuffer.allocate(1024);
// 开始接收客户端发来的消息
client.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {
// 当接收到消息时,触发 completed ()
@Override
public void completed(Integer result_num, ByteBuffer dataBuffer) {
dataBuffer.flip();
String receive = new String(dataBuffer.array(), 0, dataBuffer.limit());
System.out.println("接收到的客户端消息:" + receive);
try {
client.close();
} catch (Exception e) {
e.printStackTrace();//打印异常
}
}
@Override
public void failed(Throwable e, ByteBuffer attachment) {
e.printStackTrace();
}
});
}
@Override
public void failed(Throwable e, Void attachment) {
e.printStackTrace();
}
});
for (; ; ) {
System.out.println("main 线程和用于读取客户端消息的线程是异步执行的...");
Thread.sleep(1000);
}
}
}
}
2 客户端代码
package aio;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.util.concurrent.Future;
public class AIOClient {
public static void main(String[] args) throws Exception {
AsynchronousSocketChannel channel = AsynchronousSocketChannel.open();
channel.connect(new InetSocketAddress("127.0.0.1", 8888)).get();
ByteBuffer buffer = ByteBuffer.wrap("Hello Server".getBytes());
// 向服务端发送消息
Future<Integer> future = channel.write(buffer);
while (!future.isDone()) {
System.out.println("在 channel 将消息发送完毕以前,main 可以异步处理其他事情..");
Thread.sleep(1000);
}
Integer len = future.get();
System.out.println("发送完毕!共发送字节数:" + len);
}
}
三 测试
依次启动服务端和客户端。
1 客户端运行结果
在 channel 将消息发送完毕以前,main 可以异步处理其他事情..
发送完毕!共发送字节数:12
2 服务端运行结果
main 线程和用于读取客户端消息的线程是异步执行的...
main 线程和用于读取客户端消息的线程是异步执行的...
main 线程和用于读取客户端消息的线程是异步执行的...
main 线程和用于读取客户端消息的线程是异步执行的...
main 线程和用于读取客户端消息的线程是异步执行的...
main 线程和用于读取客户端消息的线程是异步执行的...
接收到的客户端消息:Hello Server
main 线程和用于读取客户端消息的线程是异步执行的...
main 线程和用于读取客户端消息的线程是异步执行的...
main 线程和用于读取客户端消息的线程是异步执行的...
main 线程和用于读取客户端消息的线程是异步执行的...
main 线程和用于读取客户端消息的线程是异步执行的...
main 线程和用于读取客户端消息的线程是异步执行的...