使用 AIO 完成网络通信

x33g5p2x  于2022-05-25 转载在 其他  
字(2.6k)|赞(0)|评价(0)|浏览(237)

一 需求

使用 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 线程和用于读取客户端消息的线程是异步执行的...

相关文章