zoukankan      html  css  js  c++  java
  • 复习复习nio的api之--SocketChannel read

    突然想到了netty是怎么读数据的,其实底层还是依赖jdk的nio,但是有想不起来了nio的api怎么调用的了。感觉找找过去自己写过的代码

    private void read(SelectionKey key) {
            try {
                //建立写缓冲区
                ByteBuffer readBuf = ByteBuffer.allocate(1024);
                //2 获取之前注册的socket通道对象
                SocketChannel sc = (SocketChannel) key.channel();
                //3 读取数据
                int count = sc.read(readBuf);
                //4 如果没有数据
                if(count == -1){
                    key.channel().close();
                    key.cancel();
                    return;
                }
                //5 有数据则进行读取 读取之前需要进行复位方法(把position 和limit进行复位)
                readBuf.flip();
                //6 根据缓冲区的数据长度创建相应大小的byte数组,接收缓冲区的数据
                byte[] bytes = new byte[readBuf.remaining()];
                //7 接收缓冲区数据
                readBuf.get(bytes);
                //8 打印结果
                String body = new String(bytes).trim();
                System.out.println("客户端已接受到服务端返回的数据: " + body);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

      就是这么简简单单的一句话,不过实现类就是操作系统底层的东西了。

    abstract int    read(ByteBuffer dst)
    从该通道读取到给定缓冲区的字节序列。

      上面的示例只是简单情况,一般都是这么写的

    while (socketChannel.read(buf) > 0) {
      processBuf(buf);
    }

      同时注意返回值有三种

      1 读取的字节数,能读到会大于0

      2 可能为零,说明本次epoll已经读完了

      3 如果通道已达到流出端, 则为-1。read返回-1说明客户端的数据发送完毕,并且主动的close socket。所以在这种场景下,(服务器程序)你需要关闭socketChannel并且取消key,最好是退出当前函数。注意,这个时候服务端要是继续使用该socketChannel进行读操作的话,就会抛出“远程主机强迫关闭一个现有的连接”的IO异常。

      

  • 相关阅读:
    打击目标
    面试中的坑,你能爬出来几个?
    [linux] 小问题:管道符,换行问题等;[nginx]启动,重启,关闭命令;以及升级nginx切换命令
    xshell下使用vim的编辑一个文件Ctrl+S和Ctrl+Q
    [PHP] 调用微博API 发微博OAuth2.0
    [YII2] 视图层过滤客户恶意代码
    [YII2] 增删改查2
    [YII2] 增删改查
    [YII2] 自带分页调整
    [JS] 自己弄得个倒计时
  • 原文地址:https://www.cnblogs.com/juniorMa/p/14277389.html
Copyright © 2011-2022 走看看