赞
踩
一个线程维护一个Selector,一个Selector下面又维护多个通道,通道与每个客户端之间有一个缓存Buffer(底层是一个数组),Buffer既可以读也可以写(flip方法切换),通道是双向的。
MappedByteBuffer map = channel.map(FileChannel.MapMode.READ_WRITE, 0, 5);
参数1 FileChannel.MapMode.READ_WRITE 使用的读写模式
参数2 0:可直接修改的起始位置
参数3 5:映射到内存的大小(将1.txt的多少个字节映射到内存)
可以直接修改的范围就是0-5(不是下标为5而是最多5个字节)
SocketChannel socketChannel=SocketChannel.open();//获取socket通道 socketChannel.connect(new InetSocketAddress("127.0.0.1",10086));//绑定服务器 FileChannel channel = new FileInputStream("1.exe").getChannel();//获取文件输出通道 long start=System.currentTimeMillis(); long fileLength=channel.size();//获取文件大小 int m8=1024*1024*8;//每次最多发送的字节数 long count=fileLength/m8+1;//发送次数 +1 是为了例如 8m+1字节的文件,当除了之后为1,需要把剩下的字节也输出 int index=0;//每次的定位 for (int i=0;i<count-1;i++){ index += channel.transferTo(index,m8,socketChannel);//发送给对方的socket通道 } if (fileLength-index!=0){//当有剩余的就把剩余的发送了 index += channel.transferTo(index,fileLength-index,socketChannel); } System.out.println((System.currentTimeMillis()-start)+"ms"); System.out.println("总字节数"+index);
Math.max(1, SystemPropertyUtil.getInt("io.netty.eventLoopThreads", NettyRuntime.availableProcessors() * 2))
可知。public interface ChannelFuture extends Future<Void>
),可添加监听器,当监听的事件发生时,再去处理相应的逻辑,不用阻塞的等待这个事件处理完,更加的稳定。static final EventExecutorGroup group=new DefaultEventExecutorGroup(16);//线程池处理业务 private final Mytask mytask=new Mytask();//具体实现业务的类 @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { System.out.println("NettyServerHandler__"+Thread.currentThread().getName()); //将任务提交到线程池 mytask.setParam((ByteBuf)msg,ctx); group.submit(mytask);
channel.pipeline().addLast(new DefaultEventExecutorGroup(2),new NettyServerHandler());//任务直接交给前面那个线程池处理。new DefaultEventExecutorGroup(2)可以用一个静态变量取代,这样写了之后业务就会直接用这里面的线程处理,没加的话就是默认的。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。