摘要:非阻塞模式下方法在尚未读取到任何数据时可能就返回了。非阻塞模式与选择器非阻塞模式与选择器搭配会工作的更好,通过将一或多个注册到,可以询问选择器哪个通道已经准备好了读取,写入等。
Java NIO中的SocketChannel是一个连接到TCP网络套接字的通道。可以通过以下2种方式创建SocketChannel:
1.打开一个SocketChannel并连接到互联网上的某台服务器。 2.一个新连接到达ServerSocketChannel时,会创建一个SocketChannel。
打开 SocketChannel
下面是SocketChannel的打开方式:
SocketChannel socketChannel = SocketChannel.open(); socketChannel.connect(new InetSocketAddress("http://jenkov.com", 80)); ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); ServerSocket ss = serverSocketChannel.socket(); ss.bind(new InetSocketAddress("localhost", 9026));// 绑定地址
关闭 SocketChannel
当用完SocketChannel之后调用SocketChannel.close()关闭SocketChannel:
socketChannel.close();
从 SocketChannel 读取数据
要从SocketChannel中读取数据,调用一个read()的方法之一。以下是例子:
ByteBuffer buf = ByteBuffer.allocate(48); int bytesRead = socketChannel.read(buf);
首先,分配一个Buffer。从SocketChannel读取到的数据将会放到这个Buffer中。
然后,调用SocketChannel.read()。该方法将数据从SocketChannel 读到Buffer中。
read()方法返回的int值表示读了多少字节进Buffer里。
如果返回的是-1,表示已经读到了流的末尾(连接关闭了)。
写入 SocketChannel
写数据到SocketChannel用的是SocketChannel.write()方法,该方法以一个Buffer作为参数。示例如下:
String newData = "New String to write to file..." + System.currentTimeMillis(); ByteBuffer buf = ByteBuffer.allocate(48); buf.clear(); buf.put(newData.getBytes()); buf.flip(); while(buf.hasRemaining()) { channel.write(buf); }
注意SocketChannel.write()方法的调用是在一个while循环中的。Write()方法无法保证能写多少字节到SocketChannel。所以,我们重复调用write()直到Buffer没有要写的字节为止。
非阻塞模式
可以设置 SocketChannel 为非阻塞模式(non-blocking mode).设置之后,就可以在异步模式下调用connect(), read() 和write()了。
connect()
如果SocketChannel在非阻塞模式下,此时调用connect(),该方法可能在连接建立之前就返回了。为了确定连接是否建立,可以调用finishConnect()的方法。像这样:
socketChannel.configureBlocking(false);//非阻塞 socketChannel.connect(new InetSocketAddress("http://jenkov.com", 80)); while(! socketChannel.finishConnect() ){ //wait, or do something else... }
write()
非阻塞模式下,write()方法在尚未写出任何内容时可能就返回了。所以需要在循环中调用write()。
read()
非阻塞模式下,read()方法在尚未读取到任何数据时可能就返回了。所以需要关注它的int返回值,它会告诉你读取了多少字节。
非阻塞模式与选择器
非阻塞模式与选择器搭配会工作的更好,通过将一或多个SocketChannel注册到Selector,可以询问选择器哪个通道已经准备好了读取,写入等。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/71756.html
摘要:编程核心是通道和选择器,选择器通过不断轮询,执行对应的函数。所以我们需要捕获这个异常,并且开始不断重连。如果客户端关闭那么服务器也要主动关闭他数据库代码及实体类如果还想实现数据库方面代码,私我 ...
摘要:为解决这问题,我们发现元凶处在一线程一请求上,如果一个线程能同时处理多个请求,那么在高并发下性能上会大大改善。这样一个线程可以同时发起多个调用,并且不需要同步等待数据就绪。表示当前就绪的事件类型。 JAVA NIO 一步步构建I/O多路复用的请求模型 摘要:本文属于原创,欢迎转载,转载请保留出处:https://github.com/jasonGeng88/blog 文章一:JAVA ...
摘要:通道可以异步读写。使用的方法读取数据创建一个读数据缓冲区对象从通道中读取数据使用的方法写入数据创建一个写数据缓冲区对象写入数据关闭完成使用后,您必须关闭它。五提供了一种被称为的新功能,也称为本地矢量。功能是通道提供的并不是。 历史回顾: Java NIO 概览 Java NIO 之 Buffer(缓冲区) 其他高赞文章: 面试中关于Redis的问题看这篇就够了 一文轻松搞懂redis集...
摘要:是什么就不在此文展开,这篇主要来介绍下我们要怎样通过来构建一个服务客户端程序的。的通信完全依赖与,数据的写入和读取都是通过从中写入读取。和上的调用一样的功能,监听已经注册在上面的文件描述符,监听上的事件。 NIO是什么就不在此文展开,这篇主要来介绍下我们要怎样通过java NIO来构建一个服务客户端程序的。 0x01 涉及知识点 NIO建立一个服务端和客户端程序主要涉及的知识点有: ...
摘要:通常来说所有的的操作都是从开始的一个类似于一个和对比我们可以在同一个中执行读和写操作然而同一个仅仅支持读或写可以异步地读写而是阻塞的同步读写总是从中读取数据或将数据写入到中类型有文件操作操作操作操作使用在服务器端这些通道涵盖了和网络以及文件 Java NIO Channel 通常来说, 所有的 NIO 的 I/O 操作都是从 Channel 开始的. 一个 channel 类似于一个 ...
摘要:抽象类有一个方法用于使通道处于阻塞模式或非阻塞模式。注意抽象类的方法是由抽象类实现的,都是直接继承了抽象类。大家有兴趣可以看看的源码,各种抽象类和抽象类上层的抽象类。 历史回顾: Java NIO 概览 Java NIO 之 Buffer(缓冲区) Java NIO 之 Channel(通道) 其他高赞文章: 面试中关于Redis的问题看这篇就够了 一文轻松搞懂redis集群原理及搭建...
阅读 3080·2021-11-24 10:47
阅读 3831·2021-11-02 14:43
阅读 2228·2021-09-26 10:15
阅读 2253·2021-09-08 09:35
阅读 560·2019-08-30 12:45
阅读 2781·2019-08-29 17:04
阅读 3214·2019-08-26 14:05
阅读 1259·2019-08-26 12:10