赞
踩
System.out.println(“server back message…”);
byte[] bytes = new byte[1024];
int len = socket.getInputStream().read(bytes);
String backMessage=new String(bytes,0,len);
System.out.println(backMessage);
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
分别启动服务端和客户端,测试效果如下:
BIO 是一种最简单的IO交互方式。实现方式也很简单,就是同步阻塞,就是当没有收到消息时,就会一直处于等待状态,不会做其他事情。所以效率不高,一般项目中不会使用。
NIO :同步非阻塞的IO (no-blocking IO) .
服务器实现模式为一个请求一个通道,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有IO请求时才启动一个线程进行处理。
所以我们先来了解一些基本概念:
通道
NIO 引入的最重要的概念就是通道,Channel(通道)是指数据通道,也就是数据传输的通道。 数据可以从 buffer 中读取到 channel 中,也可以冲channel 中读取到 buffer 中。
缓冲区
buffer 缓存中像是一个缓存,暂时的存放数据,数据可以从 buffer 中读取到 channel 中,也可以冲channel 中读取到 buffer 中。
选择器
选择器是线程与通道之间的桥梁。使用选择器,借助单线程就可以对众多的 IO 通道进行监控和维护。
那 NIO 有什么特点呢?
我们上面可以看到,一个线程就可以处理多个通道。一个通道对应一个连接,所以当创建一个连接,都会注册到多路复用器,也就是 selector 。然后selector 通过轮寻的方式,每个一段时间执行有传输数据的通道。
有一个例子:就是幼儿园每个小孩上厕所都需要老师陪同。NIO就是,为整个幼儿园分配一个老师,老师会定期的询问,想要上厕所的孩子举手,然后统一带领这些孩子去上厕所。这样就避免了每个孩子上厕所,老师都要去一趟。通过多路复用,简化流程。
我们现在也手写一个NIO的例子,一样的分为客户端和服务端。我们先写服务端。
服务端主要做如下操作:
1、声明多路复用器
2、定义读写缓存区
3、编写初始化方法
4、编写启动类
5、编写执行方法
初始化 init 的方法中主要是
1、开启多路复用器
2、开启通道
3、设置非阻塞
4、绑定端口
5、注册通道
整体代码如下:
public class NIOServer extends Thread{
//1.声明多路复用器
private Selector selector;
//2.定义读写缓冲区
private ByteBuffer readBuffer = ByteBuffer.allocate(1024);
private ByteBuffer writeBuffer = ByteBuffer.allocate(1024);
//3.定义构造方法初始化端口
public NIOServer(int port) {
init(port);
}
//4.main方法启动线程
public static void main(String[] args) {
new Thread(new NIOServer(8888)).start();
}
//5.初始化
private void init(int port) {
try {
System.out.println(“服务器正在启动…”);
//1)开启多路复用器
this.selector = Selector.open();
//2) 开启服务通道
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
//3)设置为非阻塞
serverSocketChannel.configureBlocking(false);
//4)绑定端口
serverSocketChannel.bind(new InetSocketAddress
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。