美文网首页
NIO的服务端客户端DEMO

NIO的服务端客户端DEMO

作者: SYFHEHE | 来源:发表于2018-08-08 20:35 被阅读0次

    服务端代码:

    package cn.nio;
    
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.CancelledKeyException;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    import java.nio.channels.ServerSocketChannel;
    import java.nio.channels.SocketChannel;
    import java.util.Iterator;
    import java.util.Scanner;
    
    /**
     * NIO服务端
     * 
     */
    public class NIOServer implements Runnable {
    
      // 通道管理器
      private Selector selector;
      private ByteBuffer readBuffer = ByteBuffer.allocate(1024);
      private ByteBuffer writeBuffer = ByteBuffer.allocate(1024);
    
    
      public NIOServer(int port) {
        init(port);
      }
    
      /**
       * 获得一个ServerSocket通道,并对该通道做一些初始化的工作
       * 
       * @param port 绑定的端口号
       */
      public void initServer(int port) throws IOException {
        init(port);
      }
    
      private void init(int port) {
        try {
          System.out.println("Server staring at port: " + port);
          // 开启多路复用器
          this.selector = Selector.open();
          // 开启服务通道
          ServerSocketChannel serverChannel = ServerSocketChannel.open();
          serverChannel.configureBlocking(false);
          serverChannel.bind(new InetSocketAddress(port));
          serverChannel.register(this.selector, SelectionKey.OP_ACCEPT);
          System.out.println("Server started");
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    
      /**
       * 采用轮询的方式监听selector上是否有需要处理的事件,如果有,则进行处理
       * 
       */
      public void run() {
        while (true) {
          try {
            this.selector.select();
            Iterator<SelectionKey> keys = this.selector.selectedKeys().iterator();
            while (keys.hasNext()) {
              SelectionKey key = keys.next();
              keys.remove();
              if (key.isValid()) {
                try {
                  if (key.isAcceptable()) {
                    accept(key);
                  }
                } catch (CancelledKeyException cke) {
                  key.cancel();
                }
                try {
                  if (key.isReadable()) {
                    read(key);
                  }
                } catch (CancelledKeyException cke) {
                  key.cancel();
                }
                try {
                  if (key.isWritable()) {
                    write(key);
                  }
                } catch (CancelledKeyException cke) {
                  key.cancel();
                }
              }
            }
          } catch (IOException e) {
            e.printStackTrace();
          }
        }
      }
    
      private void accept(SelectionKey key) {
        try {
          ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
          SocketChannel channel = serverChannel.accept();
          channel.configureBlocking(false);
          channel.register(this.selector, SelectionKey.OP_READ);
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    
      private void read(SelectionKey key) {
        try {
          this.readBuffer.clear();
          SocketChannel channel = (SocketChannel) key.channel();
          int readLength = channel.read(readBuffer);
          if (readLength == -1) {
            key.channel().close();
            key.cancel();
            return;
          }
          this.readBuffer.flip();
          byte[] datas = new byte[readBuffer.remaining()];
          readBuffer.get(datas);
          System.out
              .println("From " + channel.getRemoteAddress() + "Clinet: " + new String(datas, "UTF-8"));
          channel.register(this.selector, SelectionKey.OP_WRITE);
        } catch (IOException e) {
          e.printStackTrace();
    
        }
      }
    
      @SuppressWarnings("resource")
      private void write(SelectionKey key) {
        this.writeBuffer.clear();
        SocketChannel channel = (SocketChannel) key.channel();
        Scanner reader = new Scanner(System.in);
        try {
          String line = reader.nextLine();
          writeBuffer.put(line.getBytes("UTF-8"));
          writeBuffer.flip();
          channel.write(writeBuffer);
          channel.register(this.selector, SelectionKey.OP_READ);
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    
      /**
       * 启动服务端测试
       * 
       * @throws IOException
       */
      public static void main(String[] args) throws IOException {
        new Thread(new NIOServer(9999)).start();
      }
    
    }
    
    

    客户端代码:

    package cn.nio;
    
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.SocketChannel;
    import java.util.Scanner;
    
    /**
     * NIO客户端
     * 
     * @author 小路
     */
    public class NIOClient {
    
      /**
       * 启动客户端测试
       * 
       */
      @SuppressWarnings("resource")
      public static void main(String[] args) throws IOException {
        InetSocketAddress remote = new InetSocketAddress("localhost", 9999);
        SocketChannel channel = null;
        ByteBuffer buffer = ByteBuffer.allocate(1024);
    
        try {
          channel = SocketChannel.open();
          channel.connect(remote);
          Scanner reader = new Scanner(System.in);
          while (true) {
            System.out.println("Put message send to server>");
            String line = reader.nextLine();
            if (line.equals("exit")) {
              break;
            }
            buffer.put(line.getBytes("UTF-8"));
            buffer.flip();
            channel.write(buffer);
            buffer.clear();
    
            int readLength = channel.read(buffer);
            if (readLength == -1) {
              break;
            }
            buffer.flip();
            byte[] datas = new byte[buffer.remaining()];
            buffer.get(datas);
            System.out.println("From server " + new String(datas, "UTF-8"));
            buffer.clear();
          }
        } catch (IOException e) {
          e.printStackTrace();
        } finally {
          if (null != channel) {
            channel.close();
          }
        }
      }
    }
    
    

    先启动server 再启动client 就能数据互通了

    • client console:


      image.png
    • server console:


      image.png

    相关文章

      网友评论

          本文标题:NIO的服务端客户端DEMO

          本文链接:https://www.haomeiwen.com/subject/xsxfbftx.html