JAVA-NIO之Socket/ServerSocket Channel(详解)

 更新时间:2017年06月13日 08:13:03   投稿:jingxian  
下面小编就为大家带来一篇JAVA-NIO之Socket/ServerSocket Channel(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

一、ServerSocketChannel

Java NIO中的 ServerSocketChannel 是一个可以监听新进来的TCP连接的通道, 就像标准IO中的ServerSocket一样。ServerSocketChannel类在 java.nio.channels包中。

打开 ServerSocketChannel

通过调用 ServerSocketChannel.open() 方法来打开ServerSocketChannel.

关闭 ServerSocketChannel

通过调用ServerSocketChannel.close() 方法来关闭ServerSocketChannel.

监听新进来的连接

通过 ServerSocketChannel.accept() 方法监听新进来的连接。当 accept()方法返回的时候,它返回一个包含新进来的连接的 SocketChannel。因此, accept()方法会一直阻塞到有新连接到达。

通常不会仅仅只监听一个连接,在while循环中调用 accept()方法.

当然,也可以在while循环中使用除了true以外的其它退出准则。

非阻塞模式

ServerSocketChannel可以设置成非阻塞模式。在非阻塞模式下,accept() 方法会立刻返回,如果还没有新进来的连接,返回的将是null。 因此,需要检查返回的SocketChannel是否是null.如:

/**
   * socket server channel
   */
  @Test
  public void text2() throws IOException {
    ServerSocketChannel channel = ServerSocketChannel.open();  //新建channel
    channel.socket().bind(new InetSocketAddress(9999));   //监听端口
    channel.configureBlocking(true);               //设置阻塞

    while (true) {
      SocketChannel accept = channel.accept();          //设置为阻塞,则此方法阻塞,直到有连接
      //如果设置为非阻塞,需要在这里判断 accept == null?
      ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
      accept.read(byteBuffer);
      byteBuffer.flip();                  //反转
      while (byteBuffer.hasRemaining()) {          //判断
        System.err.println((char)byteBuffer.get());    //输出
      }
    }
  }

二、SocketChannel

Java NIO中的SocketChannel是一个连接到TCP网络套接字的通道。可以通过以下2种方式创建SocketChannel:

打开一个SocketChannel并连接到互联网上的某台服务器。

一个新连接到达ServerSocketChannel时,会创建一个SocketChannel。

打开 SocketChannel

下面是SocketChannel的打开方式:

关闭 SocketChannel

当用完SocketChannel之后调用SocketChannel.close()关闭SocketChannel:

从 SocketChannel 读取数据

要从SocketChannel中读取数据,调用一个read()的方法之一。

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

然后,调用SocketChannel.read()。该方法将数据从SocketChannel 读到Buffer中。read()方法返回的int值表示读了多少字节进Buffer里。如果返回的是-1,表示已经读到了流的末尾(连接关闭了)。

写入 SocketChannel

写数据到SocketChannel用的是SocketChannel.write()方法,该方法以一个Buffer作为参数。

注意SocketChannel.write()方法的调用是在一个while循环中的。Write()方法无法保证能写多少字节到SocketChannel。所以,我们重复调用write()直到Buffer没有要写的字节为止。

非阻塞模式

可以设置 SocketChannel 为非阻塞模式(non-blocking mode).设置之后,就可以在异步模式下调用connect(), read() 和write()了。

connect()

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

write()

非阻塞模式下,write()方法在尚未写出任何内容时可能就返回了。所以需要在循环中调用write()。前面已经有例子了,这里就不赘述了。

read()

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

非阻塞模式与选择器

非阻塞模式与选择器搭配会工作的更好,通过将一或多个SocketChannel注册到Selector,可以询问选择器哪个通道已经准备好了读取,写入等。Selector与SocketChannel的搭配使用会在后面详讲。

/**
   * socket channel
   */
  @Test
  public void test3() throws IOException {
    SocketChannel channel = SocketChannel.open();                //新建服务端
    channel.connect(new InetSocketAddress("127.0.0.1",9999));  //连接服务端地址
    ByteBuffer byteBuffer = ByteBuffer.allocate(1024); //缓冲区
    byteBuffer.put("123".getBytes());
    byteBuffer.flip();                 //反转
    while (byteBuffer.hasRemaining()) {         //判断
      channel.write(byteBuffer);
    }
  }

以上这篇JAVA-NIO之Socket/ServerSocket Channel(详解)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java实现的Windows资源管理器实例

    Java实现的Windows资源管理器实例

    这篇文章主要介绍了Java实现的Windows资源管理器,实例分析了基于java实现windows资源管理器的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07
  • 解读@Scheduled任务调度/定时任务非分布式

    解读@Scheduled任务调度/定时任务非分布式

    这篇文章主要介绍了解读@Scheduled任务调度/定时任务非分布式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • 详解Maven optional关键字透彻图解

    详解Maven optional关键字透彻图解

    这篇文章主要介绍了详解Maven optional关键字透彻图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-11-11
  • Spring学习之Bean的装配多种方法

    Spring学习之Bean的装配多种方法

    本篇文章主要介绍了Spring学习之Bean的装配三种方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • SpringMVC的详细架构你了解嘛

    SpringMVC的详细架构你了解嘛

    这篇文章主要为大家介绍了SpringMVC的详细架构,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-01-01
  • Springboot2 session设置超时时间无效的解决

    Springboot2 session设置超时时间无效的解决

    这篇文章主要介绍了Springboot2 session设置超时时间无效的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • 浅析Spring IOC 依赖查找你需要知道的几种方式

    浅析Spring IOC 依赖查找你需要知道的几种方式

    这篇文章主要介绍了浅析Spring IOC 依赖查找的几种方式,Spring是Java面试中最常考的,学Java的小伙伴快来看看吧
    2021-08-08
  • 关于MyBatis 查询数据时属性中多对一的问题(多条数据对应一条数据)

    关于MyBatis 查询数据时属性中多对一的问题(多条数据对应一条数据)

    这篇文章主要介绍了MyBatis 查询数据时属性中多对一的问题(多条数据对应一条数据),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • Java并发编程ArrayBlockingQueue的使用

    Java并发编程ArrayBlockingQueue的使用

    ArrayBlockingQueue是一个备受瞩目的有界阻塞队列,本文将全面深入地介绍ArrayBlockingQueue的内部机制、使用场景以及最佳实践,感兴趣的可以了解一下
    2024-08-08
  • 详解Java单例模式的实现与原理剖析

    详解Java单例模式的实现与原理剖析

    单例模式是Java中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。本文将详解单例模式的实现及原理剖析,需要的可以参考一下
    2022-05-05

最新评论