`
teasp
  • 浏览: 61552 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Java AIO小例子

阅读更多

    Java7 NIO里面的新特性AIO出来也很久了,一直都没用过,今天没事写个小例子体验一下。感觉AIO要比同步NIO要简单点,写出正确的AIO比写同步NIO要容易一些,但是更不好理解,异步编程就是这样,不符合人类的直观感受。

 

    服务端代码:

 

public class TestAioServer
{
    private static AtomicInteger recvNum = new AtomicInteger(0);
    private static AtomicInteger sentNum = new AtomicInteger(0);
    
    private final byte[] resp;
    
    private static final int readLen = 1800;
    
    private ByteBuffer[] genBuf()
    {
        ByteBuffer[] buf = new ByteBuffer[2];
        buf[0] = ByteBuffer.allocate(readLen);
        buf[1] = ByteBuffer.wrap(resp);
        
        return buf;
    }

    public TestAioServer(int port) throws IOException
    {
        StringBuilder sb = new StringBuilder();
        for (int i=0; i<1000; i++)
        {
            sb.append("how are you? ");
        }
        resp = sb.toString().getBytes();
        
        final AsynchronousServerSocketChannel serverChannel = AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(port));  
        serverChannel.accept(genBuf(), new CompletionHandler<AsynchronousSocketChannel, ByteBuffer[]>() {   
            public void completed(AsynchronousSocketChannel ch, ByteBuffer[] att) {
                // 接受下一个连接   
                serverChannel.accept(genBuf(), this);   
                // 处理当前连接   
                handle(ch, att);   
            }   
  
            public void failed(Throwable exc, ByteBuffer[] att) {
                System.out.println("建立连接失败");
                serverChannel.accept(null, this);
            }   
        });
          
        System.out.println("Server is listening at : " + port);
    }   
          
    public void handle(final AsynchronousSocketChannel ch, final ByteBuffer[] att) {
        final ByteBuffer dst = att[0];
        ch.read(dst, att, new ReadCompletionHandler(dst, ch));
    }  
    
    private static class ReadCompletionHandler implements CompletionHandler<Integer, ByteBuffer[]>
    {
        ByteBuffer dst;
        AsynchronousSocketChannel ch;
        private CompletionHandler<Integer, ByteBuffer[]> writeCompletionHandler = getWriteCompletionHandler();
        
        public ReadCompletionHandler(ByteBuffer dst, AsynchronousSocketChannel ch)
        {
            this.dst = dst;
            this.ch = ch;
        }
        
        @Override
        public void completed(Integer result, ByteBuffer[] attachment)
        {
//            System.out.println("result len = " + result);
            if (dst.position() == dst.capacity())
            {//读完了
                recvNum.incrementAndGet();
                dst.clear();//为下次读做准备
//                System.out.println("read : " + new String(dst.array()));
                ch.write(attachment[1], attachment, writeCompletionHandler);
            }
        }

        @Override
        public void failed(Throwable exc, ByteBuffer[] attachment)
        {
            System.out.println("read failed." );
            exc.printStackTrace();
        }
        
        public synchronized CompletionHandler<Integer, ByteBuffer[]> getWriteCompletionHandler()
        {
            if (writeCompletionHandler == null)
            {
                writeCompletionHandler = new CompletionHandler<Integer, ByteBuffer[]>()
                    {
                    @Override
                    public void completed(Integer result, ByteBuffer[] attachment)
                    {
//                        System.out.println("written len : " + result);
                        //要是没写完,继续
                        if (attachment[1].hasRemaining())
                        {
                            ch.write(attachment[1], attachment, this);
                        }
                        else
                        {//已经写完
                            sentNum.incrementAndGet();
                            attachment[1].rewind();//为下次写做准备
                            //写完了才继续读,生产中不要这么做,此处只是为了简单
                            ch.read(dst, attachment, ReadCompletionHandler.this);
                        }
                    }

                    @Override
                    public void failed(Throwable exc, ByteBuffer[] attachment)
                    {
                        System.out.println("write failed." );
                        exc.printStackTrace();
                    }
                 };
            }
            
            return writeCompletionHandler;
        }
    }

    public static void main(String[] args) throws IOException, InterruptedException
    {
        int port = 1234;
        new TestAioServer(port);
        
        Thread.sleep(15000);
        recvNum.set(0);
        sentNum.set(0);
        Thread.sleep(30000);
        System.out.println(recvNum.get()+":"+sentNum.get());
        
        Thread.sleep(30*60*1000);
    }
}

 

    客户端的代码是阻塞式IO:

public class TestSocketClient
{
    private static final byte[] req; 
    
    static
    {
        StringBuilder sb = new StringBuilder();
        for (int i=0; i<100; i++)
        {
            sb.append("This is a request.");
        }
        req = sb.toString().getBytes();
    }
    
    private static final byte[] resp = new byte[13000];

    public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException
    {
        int port = 1234;
        Socket socket = new Socket();
        socket.connect(new InetSocketAddress(InetAddress.getByName("localhost"), port));
        final InputStream is = socket.getInputStream();
        OutputStream os = socket.getOutputStream();
        
        new Thread ()
        {
            public void run()
            {
                long startTime = System.currentTimeMillis();
                int loopTimes = 1;
                for (;; loopTimes++)
                {
                    try
                    {
                        int len = is.read(resp); //不一定会读满
                        for (; len<resp.length;)
                        {
                            len += is.read(resp, len-1, resp.length-len);
                        }
                    }
                    catch (IOException e)
                    {
                        e.printStackTrace();
                        break;
                    }
//                    System.out.println(new String(b));
                    System.out.println("-" + loopTimes);
                    if (loopTimes == 30000)
                    {
                        System.out.println("time cost : " + (System.currentTimeMillis() - startTime));
                    }
                }
            }
        }.start();
        
        for (int i=0; i<30000; i++)
        {
            os.write(req);
//            os.flush();
            System.out.println("written");
            Thread.sleep(1);
        }
    }
}

 

1
3
分享到:
评论
3 楼 ggd543 2014-06-10  
ReadCompletionHandler 的completed函数中, 如果未读完,要继续读

 @Override
        public void completed(Integer result, ByteBuffer[] attachment) {
            System.out.println("result len = " + result);
            if (dst.position() == dst.capacity()) {   //读完了
                recvNum.incrementAndGet();
                dst.clear();  //为下次读做准备
                System.out.println("read : " + new String(dst.array()));
                ch.write(attachment[1], attachment, writeCompletionHandler);
            } else {
                System.out.println(" 还没读完,继续...");
                ch.read(dst, attachment, new ReadCompletionHandler(dst, ch));
            }
        }
2 楼 teasp 2013-06-20  
aa1asdasd 写道
不错不错,楼主辛苦了

谢谢,不过这代码离生产应用还差很远呢。
1 楼 aa1asdasd 2013-06-20  
不错不错,楼主辛苦了

相关推荐

    java 之异步套接字编程实例(AIO)

    Java中的异步套接字编程,也称为非阻塞I/O(Non-blocking I/O, NIO)或异步I/O(Asynchronous I/O, AIO),是Java在JDK 7引入的一种高级I/O模型,它极大地提高了网络编程的效率。AIO的主要目标是提供一种方法,使得...

    Java网络编程好例子

    本教程通过"Java网络编程好例子"提供了一种深入理解Java网络编程的途径,尤其关注Socket编程的基础和应用。 首先,我们来看看“Socket套接字—Java套接字编程(上1).chm”这个文件。Socket编程是Java网络编程的核心...

    SocketIO-BIO-NIO-AIO.zip

    这个文件很可能是系列教程的一部分,可能包含了关于如何使用Java的Socket编程来实现BIO、NIO和AIO的例子代码。Socket是Java进行网络通信的基础,通过Socket,我们可以建立客户端与服务器之间的连接,进行数据交换。 ...

    Java Network Programming 4th Edition

    5. **异步I/O(AIO)**:讲解Java 7引入的异步I/O模型,如何使用AsynchronousServerSocketChannel和AsynchronousSocketChannel实现高性能的网络应用。 6. **HTTP协议与Web服务**:学习如何使用Java编写HTTP客户端和...

    BIO,NIO,AIO,Netty面试题

    本文将深入探讨四个关键的概念:BIO( Blocking I/O)、NIO(Non-blocking I/O)、AIO(Asynchronous I/O)以及Netty,这些都是Java平台上的网络编程模型。在面试中,对这些概念的理解和应用能力常常被用来评估候选...

    java网络编程源码

    7. **异步I/O(AIO)**:Java NIO的进一步扩展,提供了异步读写操作,允许应用程序在等待I/O完成时执行其他任务。 8. **网络异常处理**:网络编程中,网络连接的断开、超时等问题是常见的,因此源码会包含如何捕获...

    java网络编程第4版源码java network programming 4th edition source code

    10. **异步I/O(AIO)**:Java 7引入了`java.nio.channels.AsynchronousSocketChannel`和`AsynchronousServerSocketChannel`,提供了异步网络编程的支持,源码可能涵盖这方面的内容。 通过阅读和分析这些源码,你...

    Java三种IO模型原理实例详解

    Java中的IO模型可以分为三种:BIO(同步阻塞)、NIO(同步非阻塞)和AIO(异步非阻塞)。每种模型都有其特点和应用场景。 BIO(同步阻塞) BIO是最古老的IO模型,在JDK1.4之前都是使用BIO模式。在BIO模式下,...

    Java精华,不可错过

    4. **IO/NIO/BIO**:对比和理解不同I/O模型,如BufferedReader、FileWriter,NIO(非阻塞I/O)以及AIO(异步I/O)。 5. **设计模式**:学习常见的23种设计模式,如单例、工厂、装饰器、代理等,提升代码的可维护性和...

    java多线程Socket简单实现

    Java多线程Socket实现是网络编程中的重要概念,它结合了Java的并发处理能力和Socket通信技术,用于构建...同时,为了提高性能,可以使用NIO(非阻塞I/O)或者异步I/O(AIO)进行优化,但这些技术超出了本次讨论的范围。

    java深度历险

    《Java深度历险》这本书是Java开发者深入理解这门编程语言的重要参考资料,它涵盖了Java的各个方面,包括核心特性、高级特性和...通过实践书中的例子和挑战,我们将在Java的世界里游刃有余,成为一名真正的Java大师。

    Java典型应用彻查1000例-网络应用开发

    7. **网络编程模型**:非阻塞I/O(NIO,New I/O)和异步I/O(AIO,Asynchronous I/O)是Java提供的高效网络编程模型。NIO通过选择器(Selector)实现了一对多的I/O模型,而AIO进一步引入了事件驱动,提高了处理高...

    通过Socket传送文件的例子

    本文将基于给定的标题“通过Socket传送文件的例子”和描述来深入探讨Socket编程以及如何利用它进行文件传输。 首先,Socket是网络编程中的一个接口,它允许应用程序通过网络发送和接收数据。在Java中,Socket类提供...

    java 深度历险

    王森可能会以生动的例子和深入浅出的解释,使读者掌握这些基础知识。 其次,深入讨论了Java的面向对象特性,如封装、继承、多态,以及接口与抽象类的区别和使用场景。这部分内容对于理解和应用Java的OOP设计原则至...

    构建高性能的大型分布式java应用

    Hadoop HDFS、Google File System (GFS) 是其中的两个著名例子。 **7.4 分布式事务** 分布式事务是指跨越多个节点或资源管理器的事务。为了保证事务的一致性,通常采用两阶段提交 (2PC) 或三阶段提交 (3PC) 协议来...

    java聊天程序

    10. **扩展性**:为了支持大量并发用户,服务器可能需要使用多线程或异步I/O模型(如NIO或AIO)来处理来自不同客户端的连接,提高性能。 总的来说,创建一个Java聊天程序涉及到网络编程、多线程、用户交互和数据...

    java基础知识要点

    - `int method(int x)` 和 `int method(int x, String y)` 参数数量不同,也是重载的例子。 - **特点**: - 方法返回值类型不影响方法的重载。 - 方法的访问修饰符(如`public`、`private`等)不影响重载。 - ...

    java简易版开心农场源码-t-io:t-i

    java简易版开心农场源码 公告 t-io master分支(默认分支)只支持jdk1.8了,想要兼容jdk1.7的,请前往: 置顶链接 t-io: 不仅仅是百万级TCP长连接框架 t-io是基于jdk aio实现的易学易用、稳定、性能强悍、将多线程...

    leetcode下载-study:学习笔记

    AIO OSI 七层模型 ARP 协议 Mysql Mysql 数据存储原理 Mysql 索引 abc 复合索引 数据库隔离级别 InnoDB 与 MySAIM 区别 Mysql MVCC JVM Java 类加载过程 Java 类加载机制 新生代频繁 gc 如何调整 CMS 垃圾回收器 锁 ...

Global site tag (gtag.js) - Google Analytics