Java NIO实现非阻塞式socket通信

博主知识水平有限,只能提供一个个人的狭隘的理解,如果有新人读到这儿,建议看一下其他教程或者API,如果不明白,再来看一下;如果有dalao读到这儿,希望能指出理解中的问题~谢谢

Java提供了用于网络通信的socket和serversocket包,然而实现方式是阻塞式的,同一时间点上只能进行一个连接,这会带来不好的体验。当然了,我们也可以通过不断创建线程的方式管理连接,但线程多了的话反而会降低效率。于是Java推出了非阻塞式IO——channel。并且channel提供关于网络通信的相关channel。

channel将传统的输入输出流合并了,即一个channel既可以输入内容,也可以输出内容。

并且,使用channel的同时,要用NIO提供的buffer作为中介。

channel类型:

  • FileChannel
  • DatagramChannel
  • SocketChannel
  • ServerSocketChannel

buffer类型:

  • ByteBuffer
  • CharBuffer
  • DoubleBuffer
  • FloatBuffer
  • IntBuffer
  • LongBuffer
  • ShortBuffer

为了使用socketchannel与serversocketchannel,请使用工厂模式创建byteBuffer:

ByteBuffer byteBuffer = ByteBuffer.allocate(12);

创建Channel方法:

ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

下条语句将指定channel设为非阻塞式:

serverSocketChannel.configureBlocking(false);

与某端口绑定:

serverSocketChannel.bind(new InetSocketAddress(PORT));

相应的如果是socketChannel,方法是connect,这里仅拿ServerSocketChannel举例。

到此为止,我们还没有看到channel是如何实现非阻塞式IO的,于是NIO提供了一种工具——Selector。

Selector,简单来说,是对多个channel的管理工具,我们可以把多个channel一股脑加进去,如果哪个channel准备好读或者写(或者其他操作)就会通知我们。

Selector中有一个interest的概念,意思是在我们把某个通道注册给selector时,我们指明selector要监视channel的哪一种行为,毕竟,一种channel可以read,write,accept,connect。

Selector实例化:

Selector selector = Selector.open();

channel注册

serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

第二个参数为interest类型

interest类型:

  1. SelectionKey.OP_CONNECT
  2. SelectionKey.OP_ACCEPT
  3. SelectionKey.OP_READ
  4. SelectionKey.OP_WRITE

一般的我们给serverSocketChannel注册一个accept就好。

然后,当我们调用selector.select()时,selector会等待已经注册的channel,直到有一个channel准备好。这个过程是阻塞式的,当然了阻塞又有什么关系呢,其实IO还是非阻塞式的。

之后我们引用selector.selectedKeys()会返回一个集合,包含了可以响应的channel,迭代集合,我们得到一个个channel。

噢,其实并不是得到channel,而是另一种东西——SelectionKey。

SelectionKey包含了挺多信息的,你可以得到他的selector,channel还有注册时的信息。

我们可以通过selectionKey.isReadable,isAcceptable,isConnectable,isWritable获得我们注册时的信息,然后具体的对每种响应类型处理。

还有,记得迭代完要把对象remove掉。

时间: 2024-10-26 07:20:39

Java NIO实现非阻塞式socket通信的相关文章

Java基础:非阻塞式IO

转载请注明出处:jiq?钦's technical Blog 引言 JDK1.4中引入了NIO,即New IO,目的在于提高IO速度.特别注意JavaNIO不完全是非阻塞式IO(No-Blocking IO),因为其中部分通道(如FileChannel)只能运行在阻塞模式下,而其他的通道可以在阻塞式和非阻塞式之间进行选择. 尽管这样,我们还是习惯将Java NIO看作是非阻塞式IO,而前面介绍的面向流(字节/字符)的IO类库则是非阻塞的,详细来看,两者区别如下: IO NIO 面向流(Strea

java nio学习三:NIO 的非阻塞式网络通信

一.阻塞和非阻塞 传统的 IO 流都是阻塞式的.也就是说,当一个线程调用 read() 或 write()时,该线程被阻塞,直到有一些数据被读取或写入,该线程在此期间不能执行其他任务.因此,在完成网络通信进行 IO 操作时,由于线程会阻塞,所以服务器端必须为每个客户端都提供一个独立的线程进行处理,当服务器端需要处理大量客户端时,性能急剧下降.Java NIO 是非阻塞模式的.当线程从某通道进行读写数据时,若没有数据可用时,该线程可以进行其他任务.线程通常将非阻塞 IO 的空闲时间用于在其他通道上

4.NIO的非阻塞式网络通信

/*阻塞 和 非阻塞 是对于 网络通信而言的*/ /*原先IO通信在进行一些读写操作 或者 等待 客户机连接 这种,是阻塞的,必须要等到有数据被处理,当前线程才被释放*/ /*NIO 通信 是将这个阻塞的过程 丢给了选择器,客户端和 服务器端 之间建立的通道,都会注册到 选择器上,然后用选择器 实时监控 我们这些通道上的状况*/ /*当某一个通道上 某一个请求的事件 完全准备就绪时,那么选择器才会将 这个任务 分配到服务器上的一个 或多个线程中*/ /*阻塞 与 非阻塞*/ 传统的IO 流都是

非阻塞式socket的select()用法

Select在Socket编程中还是比较重要的,可是对于初学Socket的人来说都不太爱用Select写程序,他们只 是习惯写诸如 connect.accept.recv或recvfrom这样的阻塞程序(所谓阻塞方式block,顾名思义,就 是进程或是线程执行到这些函数时必须等待某个事件的发生,如果事件没有发生,进程或线程就被阻塞 ,函数不能立即返回).可是使用Select就可以完成非阻塞(所谓非阻塞方式non- block,就是进程或线 程执行此函数时不必非要等待事件的发生,一旦执行肯定返回,

JAVA基础知识之网络编程——-基于NIO的非阻塞Socket通信

阻塞IO与非阻塞IO 通常情况下的Socket都是阻塞式的, 程序的输入输出都会让当前线程进入阻塞状态, 因此服务器需要为每一个客户端都创建一个线程. 从JAVA1.4开始引入了NIO API, NIO可以实现非阻塞IO, 这样就可以使用一个线程处理所有的客户请求. 基于NIO的非阻塞Socket通信 服务器将用来监听客户端请求的channel注册到selector上,启动一个线程,使用selector的select()获取求情的客户端的channel数量, 当监听到有客户端请求时,就通过Sel

Java基础知识强化之多线程笔记07:同步、异步、阻塞式、非阻塞式 的联系与区别

1. 同步: 所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回.但是一旦调用返回,就必须先得到返回值了. 换句话话说,调用者主动等待这个"调用"的结果. 对于同步调用来说,很多时候当前线程还是激活的,只是从逻辑上当前函数没有返回而已. 2. 异步: 所谓异步,"调用"在发出之后,这个调用就直接返回了,所以没有返回结果. 换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果.而是在"调用"发出后,"被调用者&q

前段时间用java做了个非阻塞式仿飞秋聊天程序

采用Swing 布局 NIO非阻塞式仿飞秋聊天程序, 切换皮肤颜色什么的小功能以后慢慢做 启动主程序. 当用户打开主程序后自动获取局域网段IP可以在 设置 --> IP网段过滤, 拥有 JMF 视频聊天功能(取得视频流读取到ByteBuffer然后写入DatagramChannel), 其实什么功能都是可以加的后期, 简单介绍下 双击用户进行聊天 (第一版是基于channel通道的操作, 非阻塞式, 这一版本为阻塞式) 当有消息发来时自动开启一个线程处理客户端请求并接受数据,并在标题上提示收到新

socket 客户端编程:非阻塞式连接,错误判断及退出重连

本文将探讨 socket 客户端的非阻塞式连接,连接成功后的错误判断及退出重连. 1. 连接方法 关于socket 客户端的非阻塞 connect 编程,网上找到的实现方式一般都是, 套接字创建之后,默认是阻塞式的,对其执行 connect 操作,如果服务端在监听,则会成功建立连接,但这只是理想情况.如果服务端没有开启,或是网络异常呢,connect 会一直阻塞到连接超时,这个超时时间在 Linux 下一般是 75 s 到几分钟.那么,如果在服务端未打开的时候 connect,连接建立会阻塞,即

Java Nio 十一、Java NIO:非堵塞服务器

最后更新时间:2015-10-23 甚至如果你理解JAVA NIO的非堵塞特点的工作方式(Selector,Channel,Buffer等等),而设计一个非堵塞服务器也是难得.相对堵塞IO来说,非堵塞IO包含几个挑战.这个非堵塞服务器教程将会讨论非堵塞服务器的主要挑战,并且对于他们描述一些潜在的解决方案. 关于设计一个非堵塞服务器发现一些好的信息是难得.因此在这个教程中提供的解决方案是基于我自己的工作经验和想法.如果你有一些另类的或者更好的想法,我将会很高兴的听到关于这些想法.你可以写一个评论在