您当前的位置: 首页 >  网络

小志的博客

暂无认证

  • 2浏览

    0关注

    1217博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Netty——网络编程 NIO(Selector处理write事件 写入内容过多问题)代码示例

小志的博客 发布时间:2022-09-18 22:28:11 ,浏览量:2

目录
    • 一、写入内容过多问题概述
    • 二、写入内容过多问题的代码示例
      • 2.1、服务端代码示例
      • 2.2、客户端代码示例
      • 2.3、启动服务端和客户端进行测试
    • 三、解决写入内容过多问题的代码示例
      • 3.1、修改服务端代码示例
      • 3.2、服务端修改后的完整代码
      • 3.3、启动服务端和客户端进行测试

一、写入内容过多问题概述
  • 非阻塞模式下,无法保证把 buffer 中所有数据都写入 channel,因此需要追踪 write 方法的返回值(代表实际写入字节数)。
  • 用 selector 监听所有 channel 的可写事件,每个 channel 都需要一个 key 来跟踪 buffer,但这样又会导致占用内存过多,就有两阶段策略。 (1)、当消息处理器第一次写入消息时,才将 channel 注册到 selector 上; (2)、selector 检查 channel 上的可写事件,如果所有的数据写完了,就取消 channel 的注册,如果不取消,会每次可写均会触发 write 事件
二、写入内容过多问题的代码示例 2.1、服务端代码示例
  • 服务端代码

    package com.example.nettytest.nio.day3;
    
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    import java.nio.channels.ServerSocketChannel;
    import java.nio.channels.SocketChannel;
    import java.nio.charset.Charset;
    import java.util.Iterator;
    
    /**
     * @description: NIO(Selector处理write事件 写入内容过多问题)代码示例
     * @author: xz
     * @create: 2022-09-18
     */
    public class Test6Server {
        public static void main(String[] args) throws IOException {
            writeServer1();
        }
        /**
         * Selector写入内容过多问题 代码示例
         * */
        public static void writeServer1() throws IOException{
            ServerSocketChannel ssc = ServerSocketChannel.open();
            ssc.configureBlocking(false);
            Selector selector = Selector.open();
            ssc.register(selector, SelectionKey.OP_ACCEPT);
            ssc.bind(new InetSocketAddress(8080));
            while (true) {
                selector.select();
                Iterator iter = selector.selectedKeys().iterator();
                while (iter.hasNext()) {
                    SelectionKey key = iter.next();
                    iter.remove();
                    if (key.isAcceptable()) {
                        SocketChannel sc = ssc.accept();
                        sc.configureBlocking(false);
                        SelectionKey sckey = sc.register(selector, 0, null);
                        sckey.interestOps(SelectionKey.OP_READ);
                        // 1. 向客户端发送大量数据
                        StringBuilder sb = new StringBuilder();
                        for (int i = 0; i             
关注
打赏
1661269038
查看更多评论
0.0426s