Netty-NIO-案例
NIO非阻塞网络编程原理分析图
- 当客户端连接时,会通过ServerSocketChannel得到对应的SocketChannel
- Selector进行监听(select()方法),返回有事件发生的通道的个数
- 将SocketChannel注册到Selector上
register(Selector sel,int ops)
,一个Selector上可以注册多个SocketChannel - 注册后返回一个SelectionKey,会和该Selector关联(以集合的方式)
- 进一步得到各个SelectionKey(有事件发生)
- 再通过SelectionKey反向获取SocketChannel,方法是channel()
- 可以通过得到的channel,完成业务处理
案例1-简单通讯
1 | public class NIOServer { |
1 | public class NIOClient { |
SelectionKey
SelectionKey,表示Selector和网络通信的注册关系,共四种:
int OP_ACCEPT:有新的网络连接可以accept,值为16
int OP_CONNECT:代表连接已经建立,值为8
int OP_READ:代表读操作,值为1
int OP_WRITE:代表写操作,值为4
SelectionKey相关方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14// 得到与之关联的Selector对象
public abstract Selector selector();
// 得到与之关系的通道
public abstract SelectableChannel channel();
// 得到与之关联的共享数据
public final Object attachment();
// 设置或改变监听事件
public abstract SelectionKey interestOps(int ops);
// 是否可以accpet
public final boolean isAcceptable();
// 是否可以读
public final boolean isReadable();
// 是否可以写
public final boolean isWriteable();
ServerSocketChannel
ServerSocketChannel在服务器端监听新的客户端Socket连接
相关方法
1
2
3
4
5
6
7
8
9
10// 得到一个ServerSocketChannel通道
public static ServerSocketChannel open();
// 设置服务器端端口号
public final ServerSocketChannel bind(SocketAddress local);
// 设置阻塞或非阻塞模式,取值false表示采用非阻塞模式
public final SelectableChannel configureBlocking(boolean block);
// 接受一个连接,返回代表这个连接的通道对象
public SocketChannel accept();
// 注册一个选择器并设置监听事件
public final SelectionKey register(Selector sel,int ops);
SocketChannel
SocketChannel,网络IO通道,具体负责进行读写操作。NIO把缓冲区的数据写入通道,或者把通道里的数据读到缓冲区
相关方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16// 得到一个SocketChannel通道
public static SocketChannel open();
// 设置阻塞或非阻塞模式,取值false表示采用非阻塞模式
public final SelectableChannel configureBlocking(boolean block);
// 连接服务器
public boolean connect(SocketAddress remote);
// 如果上面的方法连接失败,接下来就要通过该方法完成连接操作
public boolean finishConnect();
// 往通道里写数据
public int write(ByteBuffer src);
// 从通道里读数据
public int read(ByteBuffer dst);
// 注册一个选择器并设置监听事件,最后一个参数可以设置共享数据
public final SelectionKey register(Selector sel,int ops,Object att);
// 关闭通道
public final void close();
案例2-群聊系统
功能要求:
- 实现服务器和客户端之间数据简单通讯
- 实现多人群聊
- 服务器端可以监测用户上线、离线并实现消息转发功能
- 客户端可以无阻塞发送消息给其它用户,同时可以接收其它用户发送的消息
1 | public class Server { |
1 | public class Client { |