NIO笔记

来源:互联网 发布:通用网址和域名的区别 编辑:程序博客网 时间:2024/05/06 15:31
最近在研究NIO,在网上找了个实例:
  1. import java.io.IOException;
  2. import java.net.InetSocketAddress;
  3. import java.net.ServerSocket;
  4. import java.nio.ByteBuffer;
  5. import java.nio.channels.SelectionKey;
  6. import java.nio.channels.Selector;
  7. import java.nio.channels.ServerSocketChannel;
  8. import java.nio.channels.SocketChannel;
  9. import java.util.Iterator;
  10. import java.util.Set;

  11. public class NIOServer {
  12.     
  13.     /*标识数字*/
  14.     private int flag = 0;
  15.     /*缓冲区大小*/
  16.     private int BLOCK = 4096;
  17.     /*接受数据缓冲区*/
  18.     private ByteBuffer sendbuffer = ByteBuffer.allocate(BLOCK);
  19.     /*发送数据缓冲区*/
  20.     private ByteBuffer receivebuffer = ByteBuffer.allocate(BLOCK);
  21.     private Selector selector;

  22.     public NIOServer(int port) throws IOException {
  23.         // 打开服务器套接字通道

  24.         ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
  25.         // 服务器配置为非阻塞

  26.         serverSocketChannel.configureBlocking(false);
  27.         // 检索与此通道关联的服务器套接字

  28.         ServerSocket serverSocket = serverSocketChannel.socket();
  29.         // 进行服务的绑定

  30.         serverSocket.bind(new InetSocketAddress(port));
  31.         // 通过open()方法找到Selector

  32.         selector = Selector.open();
  33.         // 注册到selector,等待连接

  34.         serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
  35.         System.out.println("Server Start----8888:");
  36.     }


  37.     // 监听

  38.     private void listen() throws IOException {
  39.         while (true) {
  40.             // 选择一组键,并且相应的通道已经打开

  41.             selector.select();
  42.             // 返回此选择器的已选择键集。

  43.             Set<SelectionKey> selectionKeys = selector.selectedKeys();
  44.             Iterator<SelectionKey> iterator = selectionKeys.iterator();
  45.             while (iterator.hasNext()) {        
  46.                 SelectionKey selectionKey = iterator.next();
  47.                 iterator.remove();
  48.                 handleKey(selectionKey);
  49.             }
  50.         }
  51.     }

  52.     // 处理请求

  53.     private void handleKey(SelectionKey selectionKey) throws IOException {
  54.         // 接受请求

  55.         ServerSocketChannel server = null;
  56.         SocketChannel client = null;
  57.         String receiveText;
  58.         String sendText;
  59.         int count=0;
  60.         // 测试此键的通道是否已准备好接受新的套接字连接。

  61.         if (selectionKey.isAcceptable()) {
  62.             // 返回为之创建此键的通道。

  63.             server = (ServerSocketChannel) selectionKey.channel();
  64.             // 接受到此通道套接字的连接。

  65.             // 此方法返回的套接字通道(如果有)将处于阻塞模式。

  66.             client = server.accept();
  67.             // 配置为非阻塞

  68.             client.configureBlocking(false);
  69.             // 注册到selector,等待连接

  70.             client.register(selector, SelectionKey.OP_READ);
  71.         } else if (selectionKey.isReadable()) {
  72.             // 返回为之创建此键的通道。

  73.             client = (SocketChannel) selectionKey.channel();
  74.             //将缓冲区清空以备下次读取

  75.             receivebuffer.clear();
  76.             //读取服务器发送来的数据到缓冲区中

  77.             count = client.read(receivebuffer);    
  78.             if (count > 0) {
  79.                 receiveText = new String( receivebuffer.array(),0,count);
  80.                 System.out.println("服务器端接受客户端数据--:"+receiveText);
  81.                 client.register(selector, SelectionKey.OP_WRITE);
  82.             }
  83.         } else if (selectionKey.isWritable()) {
  84.             //将缓冲区清空以备下次写入

  85.             sendbuffer.clear();
  86.             // 返回为之创建此键的通道。

  87.             client = (SocketChannel) selectionKey.channel();
  88.             sendText="message from server--" + flag++;
  89.             //向缓冲区中输入数据

  90.             sendbuffer.put(sendText.getBytes());
  91.              //将缓冲区各标志复位,因为向里面put了数据标志被改变要想从中读取数据发向服务器,就要复位

  92.             sendbuffer.flip();
  93.             //输出到通道

  94.             client.write(sendbuffer);
  95.             System.out.println("服务器端向客户端发送数据--:"+sendText);
  96.             client.register(selector, SelectionKey.OP_READ);
  97.         }
  98.     }

  99.     /**
  100.      * @param args
  101.      * @throws IOException
  102.      */
  103.     public static void main(String[] args) throws IOException {
  104.         // TODO Auto-generated method stub

  105.         int port = 8888;
  106.         NIOServer server = new NIOServer(port);
  107.         server.listen();
  108.     }
  109. }
客户端

  1. import java.io.IOException;
  2. import java.net.InetSocketAddress;
  3. import java.nio.ByteBuffer;
  4. import java.nio.channels.SelectionKey;
  5. import java.nio.channels.Selector;
  6. import java.nio.channels.SocketChannel;
  7. import java.util.Iterator;
  8. import java.util.Set;

  9. public class NIOClient {

  10.     /*标识数字*/
  11.     private static int flag = 0;
  12.     /*缓冲区大小*/
  13.     private static int BLOCK = 4096;
  14.     /*接受数据缓冲区*/
  15.     private static ByteBuffer sendbuffer = ByteBuffer.allocate(BLOCK);
  16.     /*发送数据缓冲区*/
  17.     private static ByteBuffer receivebuffer = ByteBuffer.allocate(BLOCK);
  18.     /*服务器端地址*/
  19.     private final static InetSocketAddress SERVER_ADDRESS = new InetSocketAddress(
  20.             "localhost", 1111);

  21.     public static void main(String[] args) throws IOException {
  22.         // TODO Auto-generated method stub

  23.         // 打开socket通道

  24.         SocketChannel socketChannel = SocketChannel.open();
  25.         // 设置为非阻塞方式

  26.         socketChannel.configureBlocking(false);
  27.         // 打开选择器

  28.         Selector selector = Selector.open();
  29.         // 注册连接服务端socket动作

  30.         socketChannel.register(selector, SelectionKey.OP_CONNECT);
  31.         // 连接

  32.         socketChannel.connect(SERVER_ADDRESS);
  33.         // 分配缓冲区大小内存

  34.         
  35.         Set<SelectionKey> selectionKeys;
  36.         Iterator<SelectionKey> iterator;
  37.         SelectionKey selectionKey;
  38.         SocketChannel client;
  39.         String receiveText;
  40.         String sendText;
  41.         int count=0;

  42.         while (true) {
  43.             //选择一组键,其相应的通道已为 I/O 操作准备就绪。

  44.             //此方法执行处于阻塞模式的选择操作。

  45.             selector.select();
  46.             //返回此选择器的已选择键集。

  47.             selectionKeys = selector.selectedKeys();
  48.             //System.out.println(selectionKeys.size());

  49.             iterator = selectionKeys.iterator();
  50.             while (iterator.hasNext()) {
  51.                 selectionKey = iterator.next();
  52.                 if (selectionKey.isConnectable()) {
  53.                     System.out.println("client connect");
  54.                     client = (SocketChannel) selectionKey.channel();
  55.                     // 判断此通道上是否正在进行连接操作。

  56.                     // 完成套接字通道的连接过程。

  57.                     if (client.isConnectionPending()) {
  58.                         client.finishConnect();
  59.                         System.out.println("完成连接!");
  60.                         sendbuffer.clear();
  61.                         sendbuffer.put("Hello,Server".getBytes());
  62.                         sendbuffer.flip();
  63.                         client.write(sendbuffer);
  64.                     }
  65.                     client.register(selector, SelectionKey.OP_READ);
  66.                 } else if (selectionKey.isReadable()) {
  67.                     client = (SocketChannel) selectionKey.channel();
  68.                     //将缓冲区清空以备下次读取

  69.                     receivebuffer.clear();
  70.                     //读取服务器发送来的数据到缓冲区中

  71.                     count=client.read(receivebuffer);
  72.                     if(count>0){
  73.                         receiveText = new String( receivebuffer.array(),0,count);
  74.                         System.out.println("客户端接受服务器端数据--:"+receiveText);
  75.                         client.register(selector, SelectionKey.OP_WRITE);
  76.                     }

  77.                 } else if (selectionKey.isWritable()) {
  78.                     sendbuffer.clear();
  79.                     client = (SocketChannel) selectionKey.channel();
  80.                     sendText = "message from client--" + (flag++);
  81.                     sendbuffer.put(sendText.getBytes());
  82.                      //将缓冲区各标志复位,因为向里面put了数据标志被改变要想从中读取数据发向服务器,就要复位

  83.                     sendbuffer.flip();
  84.                     client.write(sendbuffer);
  85.                     System.out.println("客户端向服务器端发送数据--:"+sendText);
  86.                     client.register(selector, SelectionKey.OP_READ);
  87.                 }
  88.             }
  89.             selectionKeys.clear();
  90.         }
  91.     }
  92. }

0 0
原创粉丝点击