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异常。

      

  • 相关阅读:
    python 检测mobileprovision证书的过期时间
    dynamodb 分区键排序键介绍
    dynamodb 基本操作
    Python 实现一个栈
    openstack阅读链接
    mongoengine文档
    机器学习链接
    mongoengine的使用
    Timer(让函数定时执行)
    线程,进程,IO多路复用,协程的代码
  • 原文地址:https://www.cnblogs.com/juniorMa/p/14277389.html
Copyright © 2011-2022 走看看