Java中NIO基本介绍(4)——channel

1 基本概括

Java中NIO基本介绍(4)——channel

2 主要介绍

2.1 Java (Socket,ServerSocket)与(SocketChannel,ServerSocketChannel)区别和联系

Socket 和ServerSocke 是一对 他们是java.net下面实现socket通信的类SocketChannel 和ServerSocketChannel是一对 他们是java.nio下面实现通信的类 支持异步通信

服务器必须先建立ServerSocket或者ServerSocketChannel 来等待客户端的连接客户端必须建立相对应的Socket或者SocketChannel来与服务器建立连接服务器接受到客户端的连接受,再生成一个Socket或者 SocketChannel与此客户端通信

不过Socket和SocketChannel可以通过 socket.channel() SocketChannel.socket() 方法相互转换同理ServerSocket 和ServerSocketChannel 也可以相互转换

2.2 channel的介绍

在Java NIO的世界中,Selector是中央控制器,Buffer是承载数据的容器,而Channel可以说是最基础的

门面,它是本地I/O设备、网络I/O的通信桥梁,只有搭建了这座桥梁,数据才能被写入Buffer,连接才能被Selector控制。

Channel这座桥梁分别为本地I/O设备和网络I/O提供了以下实现,并且和Java IO体系的类是一一对应的:

网络I/O设备:

DatagramChannel:读写UDP通信的数据,对应DatagramSocket类

SocketChannel:读写TCP通信的数据,对应Socket类

ServerSocketChannel:监听新的TCP连接,并且会创建一个可读写的SocketChannel,对应ServerSocket类

本地I/O设备:

FileChannel:读写本地文件的数据,不支持Selector控制,对应File类

2.3 Socket简单介绍

什么是 TCP/IP 和UDP

TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,是一个工业标准的协议集,它是为广域网(WANs)设计的。

UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是属于TCP/IP协议族中的一种。

Java中NIO基本介绍(4)——channel

socket:Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

Java中NIO基本介绍(4)——channel

2.4 Channel和流的区别

1 Channel 可以是双向的,既可以通过Channel读数据,也可以写数据,流的话要么是输入流,要么是输出流

2 不能直接通过 Channel 读写数据,必须通过buffer操作,程序通过Buffer间接的和Channel打交道,程序永远不能绕过buffer直接操作Channel,而流是可以直接读写的

3 Channel的读写可以是非阻塞的,而流是阻塞的

3 用例

3.1 SocketChannel通信代码

/** * 服务端,接收数据 */public class NioServer{ public static void main(String[] args) throws IOException { //打开一个服务连接通道 ServerSocketChannel channel = ServerSocketChannel.open(); //创建服务连接地址 InetSocketAddress socketAddress = new InetSocketAddress(8888); //通道绑定服务地址 channel.bind(socketAddress); //设置服务端通道非阻塞 channel.configureBlocking(false); //打开选择处理器 Selector selector = Selector.open(); //模拟多个用户,使用selector选择器进行响应 //首先第一步进来的所有连接都是为了接入 channel.register(selector,SelectionKey.OP_ACCEPT); //selector 处理接入 while (selector.select()>0){ //阻塞体现在Selector上 //可能客户到请求一次进来多个,进行判断 Iterator<SelectionKey> iterator = selector.selectedKeys().iterator(); while (iterator.hasNext()){ //获取其中的每个请求 SelectionKey next = iterator.next(); //判断请求是属于 连接过的还是未连接过的 if(next.isAcceptable()){ //没连接过,直接跟踪,设置为读取状态 SocketChannel accept = channel.accept();//通道允许接入请求 accept.configureBlocking(false);//设置非阻塞 accept.register(selector,SelectionKey.OP_READ); //设置为读取数据 } if(next.isReadable()){ //连接过,直接读取 SelectableChannel channel2 = next.channel(); channel2.configureBlocking(false); //读取通道信息 readMsg(channel2); } iterator.remove(); } } } private static void readMsg(SelectableChannel channel2) throws IOException { SocketChannel channel = (SocketChannel) channel2; SocketAddress localAddress = channel.getLocalAddress(); //设置缓存区 ByteBuffer buffer = ByteBuffer.allocate(1024); //读取数据 int len; byte[] b = new byte[1024]; while ((len = channel.read(buffer))>0){ buffer.flip();//刷新缓存区 buffer.get(b, 0, len); System.out.println("服务端接受到数据为:" new String(b,0,len)); } }}

/** * 客户端 发送数据 */public class NioClient { public static void main(String[] args) throws IOException { //声明连接地址对象 nio框架使用tcp协议绑定ip和端口 InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1", 8888); //打开一个和服务端连接的通道 SocketChannel channel = SocketChannel.open(); channel.connect(socketAddress); //设置通道为非阻塞 channel.configureBlocking(false); //设置缓存区大小 ByteBuffer buffer = ByteBuffer.allocate(1024); //控制台的输入数据输出 Scanner scanner = new Scanner(System.in); while (scanner.hasNext()){ //清除缓存区的数据 buffer.clear(); //获取控制台的数据 String data = scanner.nextLine(); buffer.put(data.getBytes()); //刷新 缓存区的数据,与IO流的flush类似 buffer.flip(); channel.write(buffer); } }

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

(0)
上一篇 2024年5月20日 下午4:02
下一篇 2024年5月20日 下午4:13

相关推荐