NIO同步非阻塞Selector轮询实现网络socket

NIO同步非阻塞,详细原理见代码注释

  • 服务器端代码
package niodemo.niochat;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Set;

//如下的代码就实现了服务器仅仅通过1个线程(没有创建新的线程就是主线程)监听多个客户端的请求,可以写客户端测试,也可以用telnet
public class NIOSelectorServer {
   
    private static Charset charset = Charset.forName("unicode");

    public static void main(String[] args) throws IOException {
   

        //1. 创建ServerSocketChannel,通过open()获得channel实例
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

        //2.绑定ip
        InetSocketAddress inetSocketAddress = new InetSocketAddress(6666);
        serverSocketChannel.bind(inetSocketAddress);

        //3. 将serverSocketChannel设置成非阻塞的
        serverSocketChannel.configureBlocking(false);

        //4. 创建Selector
        Selector selector = Selector.open();

        //5. 将ServerSocketChannel注册到Selector上:注意:首次注册都是注册到selector上的所有的SelectionKey集合上
        //【Selector上注册的都是channel,在服务器端就一个channel就是ServerSocketChannel】
        //注册是以事件的方式注册到selector上,serverSocketChannel这个服务器端通道关注的事件是accept
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        /*
         * (1) SelectionKey类是Selector类上的集合,Selector上有3个SelectionKey,分别是:所有的SelectionKey,
         *     已选择的SelectionKey,和废弃的SelectionKey。
         * (2) SelectionKey上有4中事件类型(注册到selector上的channel都是通过事件注册的)分别是:
         *     OP_ACCEPT, OP_CONNECT, OP_READ, OP_WRITE
         * (3) 其中,服务器端的通道是ServerSocektChannel就一个,关注的事件是OP_ACCEPT
         *     服务器接收客户端请求的通道是SocketChannel是多个的,一个客户端一个SocketChannel,关注的事件是OP_READ和OP_WRITE
         *     写客户端的时候,客户端的SocketChannel关注的事件是OP_CONNECT
         * */

        //6. 在selector上使用select()方法轮询所有的SelectionKey集合
        System.out.println("select()自身以阻塞的方式等待客户端连接......");
        while (selector.select() > 0) {
       //select()的返回值大于0,说明所有的SelectionKey集合上有事件发生
            //有事件发生的就将其从selector上所有的SelectionKey集合转移到已选择的SelectionKey集合上。
            //7. 遍历已选择的SelectionKey集合,遍历是方法:迭代器,for循环

            //需要注意的是:selector.selectedKeys()方法返回的是已选择的SelectionKey集合,当有事件发生的时候遍历的就是已选择的SelectionKey集合
            //而selector.select()轮询的是所有的SelectionKey集合
            Set<SelectionKey> selectionKeys = selector.
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值