使用 AIO 完成网络通信

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

一 需求

使用 AsynchronousServerSocketChannel 搭建服务端,使用 AsynchronousSokectChannel 搭建客户端,完成客户端和服务端的一次通信。

二 实战

1 服务端代码

  1. package aio;
  2. import java.net.InetSocketAddress;
  3. import java.nio.ByteBuffer;
  4. import java.nio.channels.AsynchronousServerSocketChannel;
  5. import java.nio.channels.AsynchronousSocketChannel;
  6. import java.nio.channels.CompletionHandler;
  7. public class AIOServer {
  8. public static void main(String[] args) throws Exception {
  9. final AsynchronousServerSocketChannel channel = AsynchronousServerSocketChannel
  10. .open()
  11. .bind(new InetSocketAddress("127.0.0.1", 8888));
  12. while (true) {
  13. //接 收客户端请求的连接
  14. channel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {
  15. // 当接收到连接时,触发 completed()
  16. @Override
  17. public void completed(final AsynchronousSocketChannel client, Void attachment) {
  18. channel.accept(null, this);
  19. ByteBuffer buffer = ByteBuffer.allocate(1024);
  20. // 开始接收客户端发来的消息
  21. client.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {
  22. // 当接收到消息时,触发 completed ()
  23. @Override
  24. public void completed(Integer result_num, ByteBuffer dataBuffer) {
  25. dataBuffer.flip();
  26. String receive = new String(dataBuffer.array(), 0, dataBuffer.limit());
  27. System.out.println("接收到的客户端消息:" + receive);
  28. try {
  29. client.close();
  30. } catch (Exception e) {
  31. e.printStackTrace();//打印异常
  32. }
  33. }
  34. @Override
  35. public void failed(Throwable e, ByteBuffer attachment) {
  36. e.printStackTrace();
  37. }
  38. });
  39. }
  40. @Override
  41. public void failed(Throwable e, Void attachment) {
  42. e.printStackTrace();
  43. }
  44. });
  45. for (; ; ) {
  46. System.out.println("main 线程和用于读取客户端消息的线程是异步执行的...");
  47. Thread.sleep(1000);
  48. }
  49. }
  50. }
  51. }

2 客户端代码

  1. package aio;
  2. import java.net.InetSocketAddress;
  3. import java.nio.ByteBuffer;
  4. import java.nio.channels.AsynchronousSocketChannel;
  5. import java.util.concurrent.Future;
  6. public class AIOClient {
  7. public static void main(String[] args) throws Exception {
  8. AsynchronousSocketChannel channel = AsynchronousSocketChannel.open();
  9. channel.connect(new InetSocketAddress("127.0.0.1", 8888)).get();
  10. ByteBuffer buffer = ByteBuffer.wrap("Hello Server".getBytes());
  11. // 向服务端发送消息
  12. Future<Integer> future = channel.write(buffer);
  13. while (!future.isDone()) {
  14. System.out.println("在 channel 将消息发送完毕以前,main 可以异步处理其他事情..");
  15. Thread.sleep(1000);
  16. }
  17. Integer len = future.get();
  18. System.out.println("发送完毕!共发送字节数:" + len);
  19. }
  20. }

三 测试

依次启动服务端和客户端。

1 客户端运行结果

在 channel 将消息发送完毕以前,main 可以异步处理其他事情..

发送完毕!共发送字节数:12

2 服务端运行结果

main 线程和用于读取客户端消息的线程是异步执行的...

main 线程和用于读取客户端消息的线程是异步执行的...

main 线程和用于读取客户端消息的线程是异步执行的...

main 线程和用于读取客户端消息的线程是异步执行的...

main 线程和用于读取客户端消息的线程是异步执行的...

main 线程和用于读取客户端消息的线程是异步执行的...

接收到的客户端消息:Hello Server

main 线程和用于读取客户端消息的线程是异步执行的...

main 线程和用于读取客户端消息的线程是异步执行的...

main 线程和用于读取客户端消息的线程是异步执行的...

main 线程和用于读取客户端消息的线程是异步执行的...

main 线程和用于读取客户端消息的线程是异步执行的...

main 线程和用于读取客户端消息的线程是异步执行的...

相关文章