您的位置:首页 > 编程语言

BIO, NIO和 AIO的代码例子

2016-03-16 17:27 393 查看
在BIO阻塞模式下server端:
1 new ServerSocket(int port) 监听端口
2 serverSocket.accept() 阻塞式等待客户端的连接,有连接才返回Socket对象
3 socket.getINputStream() 获取客户端发过来的信息流
4 socket.getOutputStream() 获取输出流对象,从而写入数据返回客户端

client端:
1 newSocket(String host,int port) 建立与服务器端的连接,如果服务器没启动,报Connection refused异常
2 socket.getInputStream() 读取服务器端返回的流
3 socket.getOutputStream() 获取输出流,写入数据发送到服务器端

在NIO模式下Server端:
 ServerSocketChannel.open() // 获取serverScoketChannel实例
 serverScoketChannel.configueBlocking(false) //设置channel为非阻塞模式
 serverSocketChannel.socket() //获取serverSocket对象
 serverSocket.bind(port) //监听端口
 Selector.open() //打开Selector,获取selector实例
 serverSocketChannel.register(Selector,int)// 向selector注册channel和感兴趣的事件
 while(true) //循环以保证正常情况下服务器端一直处于运行状态


   selector.select() //获取selector实例中需要处理的SelectionKey的数量

     for(SelectionKey key:selector.selectedKeys()) //遍历selector.selectedKeys,以对每个SelectionKey的事件进行处理
      {

        if( key.isAcceptable())   //判断SelectionKey的类型是否为客户端建立连接的类型

         {  ServerSocketChannel ssc=key.channel() //当SelectionKey的类型是acceptabel时,获取绑定的ServerSocketChannel对象
           

SocketChannel scoketchannel = ssc.accept() //接受客户端建立连接的请求,并返回SocketChannel对象
            socketChannel.regiseter(Selector,int) //向Selector注册感兴趣的事件类型,如read,write

            }

           key.isReadable() //判断SelectionKey是否为readable,如是则意味着有消息流在等待处理
           socketChannel.read(ByteBuffer) //从SelectionKey中绑定的SocketChannel对象读取消息流
           socketChannel.write(ByteBuffer) //从SelectionKey中绑定的SocketChannel对象输出消息流
             }

}

client端:

1 SocketChannel.open() 打开SocketChannel

2 SocketChannel.configureBlocking(false) 将SocketChannel配置为非阻塞模式

3 SocketChannel.connect(host,port) 连接到指定的目标地址

4 Selector.open() 打开Selector

5 SocketChannel.register(Selector,int) 向Selector注册感兴趣的事件,connected,read,write

6 while(true) 循环执行保证客户端一直处于运行状态

7 Selector.select() 从Selector中获取是否有可读的key信息

8 for(SelectionKey key:selector.selectedKeys()) 遍历selector中所有selectedKeys

9 SelectionKey.isConnectable() 判断是否为连接建立的类型

10 SelectionKey.channel() 获取绑定的SocketChannel

11 SocketChannel.finishConnect() 完成连接的建立(TCP/IP的三次握手)

12 SelectionKey.isReadable() 判断是否为可读类型

13 SelectionKey.channel() 获取绑定的SocketChannel

14 SocketChannel.read(ByteBuffer) 从SocketChannel中读取数到ByteBuffer中

15 SocketChannel.write(ByteBuffer) 向SocketChannel中写入ByteBuffer对象数据

AIO例子

Java7 AIO入门实例,首先是服务端实现:

服务端代码

SimpleServer:

 

Java代码  


public class SimpleServer {  

  

    public SimpleServer(int port) throws IOException {  

        final AsynchronousServerSocketChannel listener = AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(port));  

  

        listener.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {  

            public void completed(AsynchronousSocketChannel ch, Void att) {  

                // 接受下一个连接  

                listener.accept(null, this);  

  

                // 处理当前连接  

                handle(ch);  

            }  

  

            public void failed(Throwable exc, Void att) {  

  

            }  

        });  

  

    }  

  

    public void handle(AsynchronousSocketChannel ch) {  

        ByteBuffer byteBuffer = ByteBuffer.allocate(32);  

        try {  

            ch.read(byteBuffer).get();  

        } catch (InterruptedException e) {  

            // TODO Auto-generated catch block  

            e.printStackTrace();  

        } catch (ExecutionException e) {  

            // TODO Auto-generated catch block  

            e.printStackTrace();  

        }  

        byteBuffer.flip();  

        System.out.println(byteBuffer.get());  

        // Do something  

    }  

      

}  

跟着是客户端实现:

客户端代码

SimpleClient:

Java代码  


public class SimpleClient {  

      

    private AsynchronousSocketChannel client;  

      

    public SimpleClient(String host, int port) throws IOException, InterruptedException, ExecutionException {  

        this.client = AsynchronousSocketChannel.open();  

        Future<?> future = client.connect(new InetSocketAddress(host, port));  

        future.get();  

    }  

      

    public void write(byte b) {  

        ByteBuffer byteBuffer = ByteBuffer.allocate(32);  

        byteBuffer.put(b);  

        byteBuffer.flip();  

        client.write(byteBuffer);  

    }  

  

}  

写一个简单的测试用例来跑服务端和客户端,先运行testServer(),在运行testClient();

测试用例

AIOTest

 

Java代码  


public class AIOTest {  

      

    @Test  

    public void testServer() throws IOException, InterruptedException {  

        SimpleServer server = new SimpleServer(7788);  

          

        Thread.sleep(10000);  

    }  

      

    @Test  

    public void testClient() throws IOException, InterruptedException, ExecutionException {  

        SimpleClient client = new SimpleClient("localhost", 7788);  

        client.write((byte) 11);  

    }  

  

}  

因为是异步的,所以在运行server的时候没有发生同步阻塞,在这里我加了一个线程sleep(),如果没有的话,程序会直接跑完回收掉。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: