Java中的NIO详解Day08-SocketChannel

不念不忘少年蓝@ 2023-03-03 05:52 95阅读 0赞

SocketChannel

  • 基本概念
  • SocketChannel的开启
  • SocketChannel的关闭
  • 从SocketChannel中读取数据
  • 向SocketChannel中写入数据
  • 非阻塞模式
      • connect()
      • write()
      • read()
      • 非阻塞模式与选择器

基本概念

  • Java NIO中的SocketChannel是一个连接到TCP网络套接字的通道
  • 创建SocketChannel有两种方式:

    • 打开一个SocketChannel并连接到互联网上的某台服务器
    • 一个新连接到达ServerSocketChannel时,会创建一个SocketChannel

SocketChannel的开启

  • 打开一个SocketChannel:

    SocketChannel socketChannel = SocketChannel.open();
    socketChannel.connect(url, 80);

SocketChannel的关闭

  • 当使用完毕SocketChannel之后调用SocketChannel.close() 方法关闭SocketChannel:

    socketChannel.close();

从SocketChannel中读取数据

  • 通过调用SocketChannel中的read() 方法从SocketChannel中读取数据

    ByteBuffer buffer = ByteBuffer.allocate(64);
    int bytesRead = SocketChannel.read(buffer);

  • 首先,分配一个Buffer,从SocketChannel读取到的数据将会存放到这个Buffer中

  • 然后,调用SocketChannel.read()方法,该方法将数据从SocketChannel读取到Buffer中:

    • read() 方法返回的int值表示读取了多少字节进Buffer
    • 如果返回的是 -1, 表示已经读到了Socket流的末尾,连接关闭了

向SocketChannel中写入数据

  • 通过调用SocketChannel.write() 方法向SocketChannel中写入数据
  • write() 方法以一个Buffer作为参数

    ByteBuffer buffer = ByteBuffer.allocate(64);
    buffer.clear();
    buffer.put(data.getBytes());
    buffer.flip();
    while (buffer.hasRemaining()) {

    1. socketChannel.write(buffer);

    }

  • SocketChannel.write() 方法调用的是在一个while循环中

  • write() 方法无法保证能写多少字节到SocketChannel中,所以重复调用write() 直到Buffer没有要写的字节为止

非阻塞模式

  • 可以设置SocketChannel为非阻塞模式non-blocking model
  • 设置之后,就可以在异步模式下调用connect(),read()write() 方法

connect()

  • 如果SocketChannel在非阻塞模式下,此时调用connect(), 该方法可能在连接建立之前就返回了
  • 为了确定连接是否建立,可以调用finishConnect() 方法

    socketChannel.configureBlocking(false);
    socketChannel.connect(new InetSocketAddress(url, 80));
    while(!sockeChannel.finishConnect()) {

    1. // 等待连接建立或者进行其余操作

    }

write()

  • 非阻塞模式下 ,write() 方法在尚未写出任何内容时可能就返回了
  • 所以需要在循环中调用write()

read()

  • 非阻塞模式下 ,read() 方法在尚未读取到任何数据时可能就返回了
  • 所以需要关注返回的int,int的值表示读取了多少字节

非阻塞模式与选择器

  • 非阻塞模式与选择器Selector结合起来一起使用
  • 通过将一个或者多个SocketChannel注册到Selector中,可以询问选择器Selector哪个通道已经准备好了读取,写入等

发表评论

表情:
评论列表 (有 0 条评论,95人围观)

还没有评论,来说两句吧...

相关阅读