学习了几天 nio 2.0(使用AsynchronousServerSocketChannel),比较糊涂,不知道是否不支持长连接,如果支持,请大侠们给我一段代码,如支持100个长并发连接(24小时不断线,数据不定时发送),顺便说一下,我水平很烂,多指教,另外,是否并发100个并发socket需要100个线程(不一定同时发数据,但同时在线)?
nio2.0 长连接

解决方案 »

  1.   

    异步nio不需要100个线程。你要明白nio的工作原理
    到了SocketChannel这一层,长连接和短连接没有区别,只取决于你传完数据之后有没有close
      

  2.   

    我知道一般不需要100个线程,我有一个这样的需求,(500台终端连接主机,每6秒发一个心跳包维持连接,并且不定时发送数据给主机。如果主机关闭连接,终端会不停的向主机发起连接请求),不知道可不可以用java nio2.0实现,然后这500台终端(AsynchronousSocketChannel)是否需要500个线程维持。如果我不关socket,下次传数据如何找到同一台终端。
      

  3.   


    nio 实现这个没问题的。nio 的目的就是解决线程复用的问题,使用一个线程来监听多路 socket 链接。你的情况是每秒约有100个心跳包到服务器,你可以根据处理心跳包的复杂度,来决定是使用单一线程来响应,或者是接收到消息之后,再扔到你自己的线程池里处理。
      

  4.   

    能不能给个示例代码,用AsynchronousServerSocketChannel实现,我在网上找的例子全是处理完成后关闭AsynchronousSocketChannel的。例如:
    1. public class AIOEchoServer {  
    2.     private AsynchronousServerSocketChannel server;  
    3.   
    4.     public static void main(String[] args) throws IOException {  
    5.         AIOEchoServer aioServer = new AIOEchoServer();  
    6.         aioServer.init("localhost", 6025);  
    7.     }  
    8.   
    9.     private void init(String host, int port) throws IOException {  
    10.         //ChannelGroup用来管理共享资源  
    11.         AsynchronousChannelGroup group = AsynchronousChannelGroup.withCachedThreadPool(Executors.newCachedThreadPool(), 10);  
    12.         server = AsynchronousServerSocketChannel.open(group);  
    13.         //通过setOption配置Socket  
    14.         server.setOption(StandardSocketOptions.SO_REUSEADDR, true);  
    15.         server.setOption(StandardSocketOptions.SO_RCVBUF, 16 * 1024);  
    16.         //绑定到指定的主机,端口  
    17.         server.bind(new InetSocketAddress(host, port));  
    18.         System.out.println("Listening on " + host + ":" + port);  
    19.         //输出provider  
    20.         System.out.println("Channel Provider : " + server.provider());  
    21.         //等待连接,并注册CompletionHandler处理内核完成后的操作。  
    22.         server.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() {  
    23.             final ByteBuffer buffer = ByteBuffer.allocate(1024);  
    24.   
    25.             @Override  
    26.             public void completed(AsynchronousSocketChannel result, Object attachment) {  
    27.                 System.out.println("waiting....");  
    28.                 buffer.clear();  
    29.                 try {  
    30.                     //把socket中的数据读取到buffer中  
    31.                     result.read(buffer).get();  
    32.                     buffer.flip();  
    33.                     System.out.println("Echo " + new String(buffer.array()).trim() + " to " + result);  
    34.                      
    35.                     //把收到的直接返回给客户端  
    36.                     result.write(buffer);  
    37.                     buffer.flip();  
    38.                 } catch (InterruptedException e) {  
    39.                     e.printStackTrace();  
    40.                 } catch (ExecutionException e) {  
    41.                     e.printStackTrace();  
    42.                 } finally {  
    43.                     try {  
    44.                         //关闭处理完的socket,并重新调用accept等待新的连接  
    45.                         result.close();   //这里不关闭,下次我如何找到指定 result传输数据?
    46.                         server.accept(null, this);  
    47.                     } catch (IOException e) {  
    48.                         e.printStackTrace();  
    49.                     }  
    50.                 }  
    51.             }  
    52.   
    53.             @Override  
    54.             public void failed(Throwable exc, Object attachment) {  
    55.                 System.out.print("Server failed...." + exc.getCause());  
    56.             }  
    57.         });  
    58.   
    59.         //因为AIO不会阻塞调用进程,因此必须在主进程阻塞,才能保持进程存活。  
    60.         try {  
    61.             Thread.sleep(Integer.MAX_VALUE);  
    62.         } catch (InterruptedException e) {  
    63.             e.printStackTrace();  
    64.         }  
    65.     }  
    66. }