Python 官方文档:入门教程 => 点击学习
目录Java NIO 通信基础介绍Nio 和 OIO 的对比使用 FileChannel 完成文件复制的实践案例使用 DatagramChannel 数据包通道发送数据的实践案例使用
高性能的 Java 通信,绝对离不开 Java NIO 技术,现在主流的技术框架或中间件服务器,都使 用了 Java NIO 技术,譬如:Tomcat、Jetty、Netty。
Java NIO 由以下三个核心组件组成:
在 Java 中,NIO 和 OIO 的区别,主要体现在三个方面:
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class MyCopyFile {
private File inFile;
private File outFile;
private FileInputStream fis = null;
private FileOutputStream fos = null;
private FileChannel fisChannel = null;
private FileChannel fosChannel = null;
//复制文件
public void copyFile(String srcPath, String destPath) throws IOException {
try {
inFile = new File(srcPath);
outFile = new File(destPath);
fis = new FileInputStream(inFile);
fos = new FileOutputStream(outFile);
fisChannel = fis.getChannel();
fosChannel = fos.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
int length = -1;
while ((length = fisChannel.read(buffer)) != -1) {
buffer.flip();
int outLenth = 0;
while ((outLenth = fosChannel.write(buffer)) != 0) {
System.out.println("读取的字节数为:" + outLenth);
}
buffer.clear();
}
//强制刷新磁盘
fosChannel.force(true);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
fosChannel.close();
fos.close();
fisChannel.close();
fis.close();
}
}
public static void main(String[] args) throws IOException {
MyCopyFiletest = new MyCopyFile();
String s1 = "D:\\maze.txt";
String s2 = "D:\\maze1.txt";
MyCopyFile.copyFile(s1, s2);
}
}
功能:
获取用户的输入数据,通过 DatagramChannel 数据报通道,将数据发送到远程的服务器。
客户端代码:
public class Client {
//Client发送信息
public void send() throws IOException {
DatagramChannel dChannel = DatagramChannel.open();
dChannel.configureBlocking(false);
ByteBuffer buf = ByteBuffer.allocate(1024);
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
String s = sc.nextLine();
buf.put(s.getBytes());
buf.flip();
dChannel.send(buf, new InetSocketAddress("127.0.0.1", 9999));
buf.clear();
}
dChannel.close();
}
public static void main(String[] args) throws IOException {
new Client().send();
}
}
服务端代码:
public class Server {
//服务端接收 用户发来的信息
public void receive() throws IOException {
DatagramChannel serverChannel = DatagramChannel.open();
//设置成非阻塞模式
serverChannel.configureBlocking(false);
serverChannel.bind(new InetSocketAddress("127.0.0.1", 9999));
Selector selector = Selector.open();
serverChannel.reGISter(selector, SelectionKey.OP_READ);
while (selector.select() > 0) {
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (iterator.hasNext()) {
SelectionKey next = iterator.next();
if (next.isReadable()) {
SocketAddress receive = serverChannel.receive(buffer);
buffer.flip();
String s = new String(buffer.array(), 0, buffer.limit());
System.out.println(s);
buffer.clear();
}
}
iterator.remove();
}
//关闭选择器和通道
selector.close();
serverChannel.close();
}
public static void main(String[] args) throws IOException {
new Server().receive();
}
}
功能:
仅仅读取客户端通道的输入数据,读取完成后直接关闭客户端通道;并且读取到的数据直接抛弃掉
Discard 服务器代码:
public class SocketServerDemo {
public void receive() throws IOException {
//创建服务器的通道
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
//设置为非阻塞模式
serverSocketChannel.configureBlocking(false);
//开启选择器
Selector selector = Selector.open();
//绑定链接
serverSocketChannel.bind(new InetSocketAddress(9999));
//将通道的某个IO事件 注册到选择器上
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
//轮询所有就绪的IO事件
while (selector.select() > 0) {
//逐个获取IO事件
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
//逐个判断该IO事件是否为想要的
while (iterator.hasNext()) {
SelectionKey next = iterator.next();
if (next.isAcceptable()) {
//如果为该事件为“连接就绪”事件,就获取客户端的链接
SocketChannel clientSocket = serverSocketChannel.accept();
//将客户端的链接设置为非阻塞模式
clientSocket.configureBlocking(false);
//将新的通道的可读事件,注册到选择器上
clientSocket.register(selector, SelectionKey.OP_READ);
} else if (next.isReadable()) {
//若IO事件为“可读事件”,读取数据
SocketChannel clientSocket = (SocketChannel) next.channel();
//创建缓冲区
ByteBuffer buffer = ByteBuffer.allocate(1024);
int length = 0;
//读取事件 让后丢弃
while ((length = clientSocket.read(buffer)) > 0) {
buffer.flip();
String s = new String(buffer.array(), 0, length);
System.out.println(s);
buffer.clear();
}
clientSocket.close();
}
//移除选择键
iterator.remove();
}
}
serverSocketChannel.close();
}
public static void main(String[] args) throws IOException {
new SocketServerDemo().receive();
}
}
客户端的 DiscardClient 代码:
public class SocketClientDemo {
public void socketClient() throws IOException {
SocketChannel clientSocket = SocketChannel.open(new InetSocketAddress(9999));
//切换成非阻塞模式
clientSocket.configureBlocking(false);
//如果没有连接完成 就一直链接
while (!clientSocket.finishConnect()){
}
//执行到这里说明已经连接完成了
ByteBuffer buffer = ByteBuffer.allocate(1024);
buffer.put("Hello SocketService".getBytes());
buffer.flip();
clientSocket.write(buffer);
clientSocket.shutdownInput();
clientSocket.close();
}
public static void main(String[] args) throws IOException {
new SocketClientDemo().socketClient();
}
}
与 Java OIO 相比,Java NIO 编程大致的特点如下:
(1)在 NIO 中,服务器接收新连接的工作,是异步进行的。不像 Java 的 OIO 那样,服务器监听连接,是同步的、阻塞的。NIO 可以通过选择器(也可以说成:多路复用器),后续不断地轮询选择器的选择键集合,选择新到来的连接。
(2)在 NIO 中,SocketChannel 传输通道的读写操作都是异步的。如果没有可读写的数据,负责 IO 通信的线程不会同步等待。这样,线程就可以处理其他连接的通道;不需要像 OIO 那样,线程一直阻塞,等待所负责的连接可用为止。
(3)在 NIO 中,一个选择器线程可以同时处理成千上万个客户端连接,性能不会随着客户端的增加而线性下降。
以上就是Java NIO通信基础示例详解的详细内容,更多关于Java NIO通信基础的资料请关注编程网其它相关文章!
--结束END--
本文标题: JavaNIO通信基础示例详解
本文链接: https://www.lsjlt.com/news/175845.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-03-01
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0