服务器nio协议,java Nio使用NioSocket客户端与服务端交互实现方式

本文介绍了Java NIO在服务器端和客户端交互的应用,包括NIO的优势、组成以及如何通过NioSocket实现客户端与服务端的交互。详细讲述了NIO的非阻塞特性、Selector的使用,以及ServerHandler接口处理读写事件。同时,给出了服务端和客户端的代码示例,展示了如何建立连接、读取和写入数据。最后简要提到了WebSocket协议和使用Java NIO实现聊天室的部分代码。
摘要由CSDN通过智能技术生成

NioSocket 客户端与服务端交互实现

java Nio是jdk1.4新增的io方式—–nio(new IO),这种方式在目前来说算不算new,更合适的解释应该是non-block IO。

non-block是相对于传统的io方式来讲的。传统的Io方式是阻塞的,我们拿网络io来举例,传统的io模型如下:

4f65e6d4a189b19d1b3bf3f5ff3f5c18.png

服务端主线程负责不断地server.accept(),如果没有客户端请求主线程就会阻塞,当客户端请求时,主线程会通过线程池创建一个新的线程执行。

简单解释就是一个线程负责一个客户端的socket,当客户端因网络等原因传递速度慢的时候,服务端对应的客户端的线程就会等待,很浪费资源。

同时线程过少的话会影响服务的吞吐量,而线程过多的话由于上下文切换等原因会导致效率十分低下,传统的io方式并不适合如今的网络流量。

Nio的模型如下:

64dc960a831aaa56301241c65e5a5abb.png

nio相比传统的io模型,最大的特点是优化了线程的使用。

nio通过selector可以使用一个线程去管理多个socket句柄,说是管理也不太合适,nio是采用的事件驱动模型,selector负责的是监控各个连接句柄的状态,不是去轮询每个句柄,而是在数据就绪后,将消息通知给selector,而具体的socket句柄管理则是采用多路复用的模型,交由操作系统来完成。

selector充当的是一个消息的监听者,负责监听channel在其注册的事件,这样就可以通过一个线程完成了大量连接的管理,当注册的事件发生后,再调用相应线程进行处理。

这样就不需要为每个连接都使用一个线程去维持长连接,减少了长连接的开销,同时减少了上下文的切换提高了系统的吞吐量。

java Nio的组成

java Nio主要由三个核心部分组成:

- Buffer

- Channel

- Selector

所有的io的Nio都是从一个channel开始的,Channel有点类似于流,但是和流不同的是,channel是可以双向读写的。Channel有几种类型,主要包含文件io操作和网络io:

- FileChannel (文件io)

- DatagramChannel (udp数据报)

- SocketChannel (tcp客户端)

- ServerSocketChannel (tcp服务端)

Buffer是一个中间缓存区,数据可以从channel读取到buffer,也可以从buffer写到channel中,在java中,传统方式与io的交互,需要将数据从堆内存读取到直接内存中,然后交由c语言来调用系统服务完成io的交互。

而使用Buffer可以直接在直接内存中开辟内存区域,减少了io复制的操作,从而提高了io操作的效率。

#基本数据类型的buffer

- ByteBuffer

- CharBuffer

- DoubleBuffer

- FloatBuffer

- IntBuffer

- LongBuffer

- ShortBuffer

#文件内存映射buffer

- MappedByteBuffer

#直接内存区buffer

- DirectBuffer

Selector允许单个线程处理多个channel,可以将多个channel教给selector管理,并注册相应的事件,而selector则采用事件驱动的方式,当注册的事件就绪后,调用相应的相应的线程处理该时间,不用使用线程去维持长连接,减少了线程的开销。

Selector通过静态工厂的open方法建立,然后通过channel的register注册到Channel上。

注册后通过select方法等待请求,select请求有long类型参数,代表等待时间,如果等待时间内接受到操作请求,则返回可以操作请求的数量,否则超时往下走。

传入参数为零或者无参方法,则会采用阻塞模式知道有相应请求。

收到请求后调用selectedKeys返回SelectionKey的集合。

SelectionKey保存了处理当前请求的Channel和Selector,并且提供了不同的操作类型。

SelectionKey的操作有四种:

- SelectionKey.OP_CONNECT

- SelectionKey.OP_ACCEPT

- SelectionKey.OP_READ

- SelectionKey.OP_WRITE

下面为一个客户端与服务端实用NioSocket交互的简单例子:

//对selectionKey事件的处理

/**

* description:

*

* @author wkGui

*/

interface ServerHandlerBs {

void handleAccept(SelectionKey selectionKey) throws IOException;

String handleRead(SelectionKey selectionKey) throws IOException;

}

/**

* description:

*

* @author wkGui

*/

public class ServerHandlerImpl implements ServerHandlerBs {

private int bufferSize = 1024;

private String localCharset = "UTF-8";

public ServerHandlerImpl() {

}

public ServerHandlerImpl(int bufferSize) {

this(bufferSize, null);

}

public ServerHandlerImpl(String localCharset) {

this(-1, localCharset);

}

public ServerHandlerImpl(int bufferSize, String localCharset) {

this.bufferSize = bufferSize > 0 ? bufferSize : this.bufferSize;

this.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值