NIO非阻塞服务器适合长连接吗?

时间:2022-09-05 14:50:51
NIO非阻塞服务器适合长连接吗?每次通讯的数据量很小。

16 个解决方案

#1


啊?
NIO是阻塞在系统上,也就是选择器上,相比旧IO阻塞在代码上要好

#2


可以采用长连接

#3


不过 NIO 的开发比普通阻塞的 IO 复杂很多,一不小心就会出错。

#4


引用 2 楼 bao110908 的回复:
可以采用长连接

使用长连接后。性能会不会受影响。并发访问会不会受影响?

#5


引用 3 楼 bao110908 的回复:
不过 NIO 的开发比普通阻塞的 IO 复杂很多,一不小心就会出错。


阻塞的 IO服务器的话。每一个连接都要一个线程来处理。系统开销又会很大。

#6


用线程池,不过这里难度就高了,因为你要确保每次的通信是接着上一次的通信的数据,而且要保证每个连接之间的数据不会互相干扰

#7


引用 6 楼 soli11722984 的回复:
用线程池,不过这里难度就高了,因为你要确保每次的通信是接着上一次的通信的数据,而且要保证每个连接之间的数据不会互相干扰


晕了。。不知道你有没有例子给俺一个。。现在是不知道怎么下手了。

#8


参考各大服务器吧,因为都用了NIO了

TOMCAT好像6.0开始采用NIO

#9


引用 8 楼 soli11722984 的回复:
参考各大服务器吧,因为都用了NIO了

TOMCAT好像6.0开始采用NIO


谢谢啦。

#10


当有大量客户端访问的时候 适合NIO非阻塞服务器
当服务器需要主动向客户端发送数据的时候适合长连接
是不是长连接跟 是否适合NIO没有直接联系

#11


import java.nio.*;

import java.nio.channels.*;

import java.net.*;

import java.util.*;

import java.io.IOException;



public class ChargenServer {

    

  public static int DEFAULT_PORT = 19;

  

  public static void main(String[] args) {

  

    int port;

    try {

      port = Integer.parseInt(args[0]);

    }

    catch (Exception ex) {

      port = DEFAULT_PORT;   

    }

    System.out.println("Listening for connections on port " + port);



    byte[] rotation = new byte[95*2];

    for (byte i = ' '; i <= '~'; i++) {

        rotation[i-' '] = i;    

        rotation[i+95-' '] = i;    

    }

    

    ServerSocketChannel serverChannel;

    Selector selector;

    try {

      serverChannel = ServerSocketChannel.open( );

      ServerSocket ss = serverChannel.socket( );

      InetSocketAddress address = new InetSocketAddress(port);

      ss.bind(address);

      serverChannel.configureBlocking(false);

      selector = Selector.open( );

      serverChannel.register(selector, SelectionKey.OP_ACCEPT);

    }

    catch (IOException ex) {

      ex.printStackTrace( );

      return;   

    }

    

    while (true) {

      

      try {

        selector.select( );

      }

      catch (IOException ex) {

        ex.printStackTrace( );

        break;

      }

        

      Set readyKeys = selector.selectedKeys( );

      Iterator iterator = readyKeys.iterator( );

      while (iterator.hasNext( )) {

        

        SelectionKey key = (SelectionKey) iterator.next( );

        iterator.remove( );

        try {

          if (key.isAcceptable( )) {

            ServerSocketChannel server = (ServerSocketChannel) key.channel( );

            SocketChannel client = server.accept( );

            System.out.println("Accepted connection from " + client);

            client.configureBlocking(false);

            SelectionKey key2 = client.register(selector, SelectionKey.

                                                                    OP_WRITE);

            ByteBuffer buffer = ByteBuffer.allocate(74);

            buffer.put(rotation, 0, 72);

            buffer.put((byte) '\r');

            buffer.put((byte) '\n');

            buffer.flip( );

            key2.attach(buffer);

          }

          else if (key.isWritable( )) {

            SocketChannel client = (SocketChannel) key.channel( );

            ByteBuffer buffer = (ByteBuffer) key.attachment( );

            if (!buffer.hasRemaining( )) {

              // Refill the buffer with the next line

              buffer.rewind( ); 

              // Get the old first character

              int first = buffer.get( );

              // Get ready to change the data in the buffer

              buffer.rewind( );

              // Find the new first characters position in rotation

              int position = first - ' ' + 1;

              // copy the data from rotation into the buffer

              buffer.put(rotation, position, 72);

              // Store a line break at the end of the buffer

              buffer.put((byte) '\r');

              buffer.put((byte) '\n');

              // Prepare the buffer for writing

              buffer.flip( );

            }

            client.write(buffer);

          }

        }

        catch (IOException ex) {

          key.cancel( );

          try {

            key.channel( ).close( );

          }

          catch (IOException cex) {}

        }

        

      }



    }

  

  }



}

#12


你看这个NIO,无论有多少个客户端都只要一个线程就够了。
如果不用NIO就要 一个客户端一个线程了 

#13


想的有些简单了吧.

#14


引用 12 楼 bill_hai 的回复:
你看这个NIO,无论有多少个客户端都只要一个线程就够了。
如果不用NIO就要 一个客户端一个线程了


现在越来越倾向与NIO了。可是怎么写业务呢?不是很明白。

#15


该回复于2010-09-17 14:09:02被版主删除

#16


别说"越来越倾向"这个词,其实从想写java网络程序,只要你的jdk是1.4以后的,那答案其实只有一个就是NIO.
怎么用的话,你去搜搜mina/netty这两个framework的关键字就知道了

#1


啊?
NIO是阻塞在系统上,也就是选择器上,相比旧IO阻塞在代码上要好

#2


可以采用长连接

#3


不过 NIO 的开发比普通阻塞的 IO 复杂很多,一不小心就会出错。

#4


引用 2 楼 bao110908 的回复:
可以采用长连接

使用长连接后。性能会不会受影响。并发访问会不会受影响?

#5


引用 3 楼 bao110908 的回复:
不过 NIO 的开发比普通阻塞的 IO 复杂很多,一不小心就会出错。


阻塞的 IO服务器的话。每一个连接都要一个线程来处理。系统开销又会很大。

#6


用线程池,不过这里难度就高了,因为你要确保每次的通信是接着上一次的通信的数据,而且要保证每个连接之间的数据不会互相干扰

#7


引用 6 楼 soli11722984 的回复:
用线程池,不过这里难度就高了,因为你要确保每次的通信是接着上一次的通信的数据,而且要保证每个连接之间的数据不会互相干扰


晕了。。不知道你有没有例子给俺一个。。现在是不知道怎么下手了。

#8


参考各大服务器吧,因为都用了NIO了

TOMCAT好像6.0开始采用NIO

#9


引用 8 楼 soli11722984 的回复:
参考各大服务器吧,因为都用了NIO了

TOMCAT好像6.0开始采用NIO


谢谢啦。

#10


当有大量客户端访问的时候 适合NIO非阻塞服务器
当服务器需要主动向客户端发送数据的时候适合长连接
是不是长连接跟 是否适合NIO没有直接联系

#11


import java.nio.*;

import java.nio.channels.*;

import java.net.*;

import java.util.*;

import java.io.IOException;



public class ChargenServer {

    

  public static int DEFAULT_PORT = 19;

  

  public static void main(String[] args) {

  

    int port;

    try {

      port = Integer.parseInt(args[0]);

    }

    catch (Exception ex) {

      port = DEFAULT_PORT;   

    }

    System.out.println("Listening for connections on port " + port);



    byte[] rotation = new byte[95*2];

    for (byte i = ' '; i <= '~'; i++) {

        rotation[i-' '] = i;    

        rotation[i+95-' '] = i;    

    }

    

    ServerSocketChannel serverChannel;

    Selector selector;

    try {

      serverChannel = ServerSocketChannel.open( );

      ServerSocket ss = serverChannel.socket( );

      InetSocketAddress address = new InetSocketAddress(port);

      ss.bind(address);

      serverChannel.configureBlocking(false);

      selector = Selector.open( );

      serverChannel.register(selector, SelectionKey.OP_ACCEPT);

    }

    catch (IOException ex) {

      ex.printStackTrace( );

      return;   

    }

    

    while (true) {

      

      try {

        selector.select( );

      }

      catch (IOException ex) {

        ex.printStackTrace( );

        break;

      }

        

      Set readyKeys = selector.selectedKeys( );

      Iterator iterator = readyKeys.iterator( );

      while (iterator.hasNext( )) {

        

        SelectionKey key = (SelectionKey) iterator.next( );

        iterator.remove( );

        try {

          if (key.isAcceptable( )) {

            ServerSocketChannel server = (ServerSocketChannel) key.channel( );

            SocketChannel client = server.accept( );

            System.out.println("Accepted connection from " + client);

            client.configureBlocking(false);

            SelectionKey key2 = client.register(selector, SelectionKey.

                                                                    OP_WRITE);

            ByteBuffer buffer = ByteBuffer.allocate(74);

            buffer.put(rotation, 0, 72);

            buffer.put((byte) '\r');

            buffer.put((byte) '\n');

            buffer.flip( );

            key2.attach(buffer);

          }

          else if (key.isWritable( )) {

            SocketChannel client = (SocketChannel) key.channel( );

            ByteBuffer buffer = (ByteBuffer) key.attachment( );

            if (!buffer.hasRemaining( )) {

              // Refill the buffer with the next line

              buffer.rewind( ); 

              // Get the old first character

              int first = buffer.get( );

              // Get ready to change the data in the buffer

              buffer.rewind( );

              // Find the new first characters position in rotation

              int position = first - ' ' + 1;

              // copy the data from rotation into the buffer

              buffer.put(rotation, position, 72);

              // Store a line break at the end of the buffer

              buffer.put((byte) '\r');

              buffer.put((byte) '\n');

              // Prepare the buffer for writing

              buffer.flip( );

            }

            client.write(buffer);

          }

        }

        catch (IOException ex) {

          key.cancel( );

          try {

            key.channel( ).close( );

          }

          catch (IOException cex) {}

        }

        

      }



    }

  

  }



}

#12


你看这个NIO,无论有多少个客户端都只要一个线程就够了。
如果不用NIO就要 一个客户端一个线程了 

#13


想的有些简单了吧.

#14


引用 12 楼 bill_hai 的回复:
你看这个NIO,无论有多少个客户端都只要一个线程就够了。
如果不用NIO就要 一个客户端一个线程了


现在越来越倾向与NIO了。可是怎么写业务呢?不是很明白。

#15


该回复于2010-09-17 14:09:02被版主删除

#16


别说"越来越倾向"这个词,其实从想写java网络程序,只要你的jdk是1.4以后的,那答案其实只有一个就是NIO.
怎么用的话,你去搜搜mina/netty这两个framework的关键字就知道了