Netty的深入浅出--31.NIO网络编程实例剖析
创建项目:
分析一下ServerSocketChannel
从源码可以看出来它也是一个抽象类
划重点:ServerSocketChannel是一种面向于流的监听性质的socket;
它是通过调用open方法来创建的。
有一个重要方法:
一定要配置成一种非阻塞式的连接:
获取一个socket对象:
绑定端口:
上面实现了绑定,接下来将要实现一个注册,来实现与selector的连接
SelectionKey.OP_ACCEPT:接受连接(基本上就选择这个,没啥要考虑的)
打印注册端口:
返回的是key的数量:
返回的是当前使用的SelectionKey:
获取集合的迭代器:
判断是否与client进行了连接:
那问题来了我们怎么去接受真正的连接呢?
我们应该将一个个的selector注册到了ServerSocketChannel里面
因此当事件发生之后,我们可以通过selectionkey来获取对应的ServerSocketChannel:
调用accept()方法获取连接对象socketChannel
设置为非阻塞式:
当前连接已经建立好了,我们需要将新的连接也添加到seletor中。因此我们还要注册一次,这次注册对应的是真正连接的通道;
当前我们关注的key是读
注册完之后一定要调用一次移除操作:
将socketchannel打印出来
运行程序:
通过命令行连接:
之前我们关注的是有没有数据进来,现在我们关注有没有数据写入
判断selectionKey是不是可读的
通过selectionKey获取相应的channel
读数据和之前的方式一样:
创建byteBuffer,通过channel来读取数据,这里的channel就是socketChannel
读完之后再写回去,将请求相应给客户端:
执行完之后一定要记得remove:
启动服务器:
命令行客户端 :
服务端收到请求信息,客户端收到服务端的响应信息:
我启动多个客户端窗口来连接一个服务端,而且服务端只有一个线程,这个可以说是很强大了!
现在总结一下,看下面的图,上面五个channel相当于我们要进行连接的5个客户端号(也就是我们),然后每个连接事件产生之后(也就是连接上了我们的5个端口号),就会产生了相应的selectionKey,然后每个selectionKey携带这它相对于的每一个channel。因此我们就可以获取相应的channel对象。这样的话,我们就可以通过channel对象来源源不断的获取对象。