1 import java.nio.channels.AsynchronousServerSocketChannel; 2 import java.nio.channels.AsynchronousSocketChannel; 3 import java.net.InetSocketAddress; 4 import java.util.concurrent.Future; 5 import java.nio.ByteBuffer; 6 7 8 public class SimpleAIOServer{ 9 static final int PORT = 30000; 10 public static void main(String[] args) throws Exception{ 11 try( 12 //创建AsynchronousServerSocketChannel对象 13 AsynchronousServerSocketChannel serverChannel = AsynchronousServerSocketChannel.open() 14 ){ 15 //指定在指定地址、端口监听 16 serverChannel.bind(new InetSocketAddress(PORT)); 17 while(true){ 18 //采用循环接受来自客户端的连接 19 Future<AsynchronousSocketChannel> future = serverChannel.accept(); 20 //获取连接完成后返回的AsynchronousSocketChannel 21 AsynchronousSocketChannel socketChannel = future.get(); 22 //执行输出 23 socketChannel.write(ByteBuffer.wrap("欢迎你来到AIO的世界!".getBytes("UTF-8"))).get(); 24 } 25 } 26 } 27 }
1 import java.nio.channels.AsynchronousSocketChannel; 2 import java.nio.charset.Charset; 3 import java.net.InetSocketAddress; 4 import java.util.concurrent.Future; 5 import java.nio.ByteBuffer; 6 7 public class SimpleAIOClient{ 8 static final int PORT = 30000; 9 public static void main(String[] args) throws Exception{ 10 //用于读取数据的ByteBuffer 11 ByteBuffer buff = ByteBuffer.allocate(1024); 12 Charset utf = Charset.forName("utf-8"); 13 try( 14 //创建AsynchronousSocketChannel对象 15 AsynchronousSocketChannel clientChannel = AsynchronousSocketChannel.open() 16 ){ 17 //连接远程服务器 18 clientChannel.connect(new InetSocketAddress("127.0.0.1", PORT)); 19 buff.clear(); 20 //从clientChannel中读取数据 21 clientChannel.read(buff).get(); 22 buff.flip(); 23 //将buff中的内容转换为字符串 24 String content = utf.decode(buff).toString(); 25 System.out.println("服务器信息:" + content); 26 } 27 } 28 }
运行上述代码会出现Exception in thread "main" java.nio.channels.NotYetConnectedException并提示在at SimpleAIOClient.main(SimpleAIOClient.java:21)报错。
NotYetConnectedException是尚未连接的错误,代码出错原因:
客户端和服务端没有建立连接就执行了Socket通信,代码上的错误位置是:
SimpleAIOClient.java中第18行:
//连接远程服务器
clientChannel.connect(new InetSocketAddress("127.0.0.1", PORT));
因为这一行没有检查异步IO操作是否完成,只有异步IO操作完成客户端和服务端的连接才能建立。
而异步IO操作是否完成的标志是clientChannel有一个Future返回值,得到它才能确保异步IO操作执行完成:
//连接远程服务器
clientChannel.connect(new InetSocketAddress("127.0.0.1", PORT)).get();//得到Future返回值,否则连接不会建立。