<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-23  評論-58  文章-0  trackbacks-0
    Reactor 模式的 JAVA NIO 多線程服務器,這是比較完善的一版了。Java 的 NIO 網絡模型實在是不好用,還是使用現成的好。
    public class NIOServer implements Runnable 
    {
        
    private static final Log log = LogFactory.getLog(NIOServer.class);

        
    private ExecutorService executor=null;
        
    private final Selector sel;
        
    private final ServerSocketChannel ssc;
        
    private HandleUtil ho;
        
        
    public NIOServer(int portnumber,HandleUtil ho) throws IOException
        
    {
            
    this.ho=ho;
            sel 
    = Selector.open();
            ssc 
    = ServerSocketChannel.open();
            ssc.socket().bind(
    new InetSocketAddress(portnumber));
            ssc.configureBlocking(
    false);
            ssc.register(sel,SelectionKey.OP_ACCEPT,
    new Acceptor());
        }

        
        
    public NIOServer(int portnumber,HandleUtil ho,ExecutorService executor) throws IOException
        
    {
            
    this.ho=ho;
            
    this.executor=executor;
            sel 
    = Selector.open();
            ssc 
    = ServerSocketChannel.open();
            ssc.socket().bind(
    new InetSocketAddress(portnumber));
            ssc.configureBlocking(
    false);
            ssc.register(sel,SelectionKey.OP_ACCEPT,
    new Acceptor());
        }

        
        @Override
        
    public void run()
        
    {
            
    try
            
    {
                
    while(sel.isOpen())
                
    {
                    
    int nKeys=sel.select(100);
                    
    if(nKeys==0)
                        Thread.sleep(
    100);
                    
    else if(nKeys>0)
                    
    {
                        Iterator
    <SelectionKey> it = sel.selectedKeys().iterator();
                        
    while (it.hasNext()) 
                        
    {
                            SelectionKey sk 
    = it.next();
                            it.remove();
                            
    if(sk.isAcceptable()||sk.isReadable()||sk.isWritable())
                            
    {
                                Runnable r 
    = (Runnable)sk.attachment();
                                r.run();
                            }

                        }

                    }

                }

            }

            
    catch(IOException | InterruptedException e)        { log.info(ExceptionUtil.getExceptionMessage(e));    }
        }

        
        
    class Acceptor implements Runnable 
        
    {
            @Override
            
    public void run() 
            
    {
                
    try
                
    {
                    SocketChannel sc 
    = ssc.accept();
                    
    if (sc != null)
                    
    {
                        sc.configureBlocking(
    false);
                        sc.socket().setTcpNoDelay(
    true);
                        sc.socket().setSoLinger(
    false-1);
                        SelectionKey sk
    =sc.register(sel, SelectionKey.OP_READ);
                        sk.attach(
    new Reader(sk));
                        sel.wakeup();
                    }

                }

                
    catch(IOException e) { log.info(ExceptionUtil.getExceptionMessage(e)); }
            }

        }

        
        
    class Reader implements Runnable 
        
    {
            
    private byte[] bytes=new byte[0];
            
    private SelectionKey sk;
            
            
    public Reader(SelectionKey sk)
            
    {
                
    this.sk=sk;
            }

            
            @Override
            
    public void run()
            
    {
                
    try
                
    {
                    SocketChannel sc 
    = (SocketChannel) sk.channel();
                    Handle handle
    =null;
                    
    if(ho.getParameterTypes()==null)
                        handle
    =(Handle)HandleUtil.getObjectByClassName(ho.getClassname());
                    
    else
                        handle
    =(Handle)HandleUtil.getObjectByClassName(ho.getClassname(), ho.getParameterTypes(), ho.getParameters());
                    handle.setSocketChannel(sc);
                    ByteBuffer buffer
    =ByteBuffer.allocate(1024);
                    
    int len=-1;
                    
    while(sc.isConnected() && (len=sc.read(buffer))>0)
                    
    {
                        buffer.flip();
                          
    byte [] content = new byte[buffer.limit()];
                        buffer.get(content);
                        bytes
    =StringUtil.arrayCoalition(bytes,content);
                        buffer.clear();
                    }

                    
    if(len==0)
                    
    {
                        
    if(executor==null)
                        
    {
                            
    byte[] bb=handle.execute(bytes);
                            sk.interestOps(SelectionKey.OP_WRITE);
                            sk.attach(
    new Writer(sk,ByteBuffer.wrap(bb)));
                            sk.selector().wakeup();
                        }

                        
    else
                        
    {
                            handle.setData(bytes);
                            Future
    <byte[]> future=executor.submit(handle);
                            sk.interestOps(SelectionKey.OP_WRITE);
                            sk.attach(
    new Writer(sk,future));
                            sk.selector().wakeup();
                        }

                    }

                    
    else if(len==-1)
                    
    {
                        sk.cancel();
                        sk.selector().selectNow();
                        sc.close();
                    }

                }

                
    catch(Exception e)
                
    {
                    sk.cancel();
                    log.info(ExceptionUtil.getExceptionMessage(e));
                }

            }

        }

        
        
    public class Writer implements Runnable 
        
    {
            
    private SelectionKey sk;
            
    private ByteBuffer output;
            
            
    public Writer(SelectionKey sk,ByteBuffer output)
            
    {
                
    this.sk=sk;
                
    this.output=output;
            }

            
            
    public Writer(SelectionKey sk,Future<byte[]> future) throws InterruptedException, ExecutionException
            
    {
                
    this.sk=sk;
                
    this.output=ByteBuffer.wrap(future.get());
            }

            
            @Override
            
    public void run()
            
    {
                SocketChannel sc 
    = (SocketChannel) sk.channel();
                
    try
                
    {
                    
    while(sc.isConnected() && output.hasRemaining())
                    
    {
                        
    int len=sc.write(output);
                        
    if(len<0)
                            
    throw new EOFException();
                        
    else if(len==-1)
                        
    {
                            sk.cancel();
                            sk.selector().selectNow();
                            sc.close();
                        }

                    }

                    
    if(!output.hasRemaining())
                    
    {
                        output.clear();
                        sk.interestOps(SelectionKey.OP_READ);
                        sk.attach(
    new Reader(sk));
                        sk.selector().wakeup();
                    }

                }

                
    catch(Exception e)
                
    {
                    sk.cancel();
                    log.info(ExceptionUtil.getExceptionMessage(e));
                }

            }

        }

        
        
    public void send(SocketChannel sc,byte[] bytes) throws ClosedChannelException
        
    {
            SelectionKey sk
    =sc.register(sel, SelectionKey.OP_WRITE);
            sk.attach(
    new Writer(sk,ByteBuffer.wrap(bytes)));
            sel.wakeup();
        }

    }


    posted on 2013-05-14 16:31 nianzai 閱讀(2736) 評論(1)  編輯  收藏 所屬分類: NIO

    評論:
    # re: JAVA NIO 多線程服務器 1.3版 [未登錄] 2013-09-18 15:34 | z
    Handle 這個方法里面寫的是什么處理呢?能否也貼出來看看  回復  更多評論
      
    主站蜘蛛池模板: 人人揉揉香蕉大免费不卡| 成人免费一级毛片在线播放视频| 久久免费精彩视频| 亚洲综合色丁香麻豆| 一个人免费观看视频在线中文| 国产免费无码一区二区| 免费jjzz在在线播放国产| 亚洲av永久无码精品三区在线4| xvideos永久免费入口| 久久精品亚洲精品国产色婷| 成人A毛片免费观看网站| 四虎永久免费观看| 亚洲欧美精品午睡沙发| 69xx免费观看视频| 日韩亚洲AV无码一区二区不卡| 热99re久久精品精品免费| 亚洲嫩草影院在线观看| 久久WWW免费人成一看片| 色偷偷亚洲第一综合| 日本高清免费不卡在线| 亚洲AV无码国产剧情| 国产在线观看免费视频播放器| 亚洲av成人无码网站…| 久久亚洲AV无码精品色午夜麻| 岛国岛国免费V片在线观看| 亚洲国产成人精品激情| 国产精品视频免费| 伊人久久五月丁香综合中文亚洲| 午夜视频在线在免费| 色婷婷亚洲一区二区三区| 99久久亚洲精品无码毛片| 国产成人免费a在线视频app| 最近中文字幕免费2019| 亚洲黄色免费观看| 久久精品女人天堂AV免费观看| 亚洲中文字幕乱码熟女在线| 亚洲狠狠婷婷综合久久久久| 久久久久免费看成人影片| 亚洲第一区二区快射影院| 小小影视日本动漫观看免费| 亚洲免费在线视频播放|