Tamaño máximo de datos que se pueden obtener de un socket de cliente utilizando socketChannel del paquete nio en java

Utilizando SocketChannel sc =(SocketChannel)key.channel();, podemos obtener datos del puerto en el búfer.
Para recibir los datos continuamente desde el puerto sin la pérdida de datos, ¿cómo debe ser el código?

Aqui esta mi codigo

import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.util.*;

public class MultiPortEcho
{
  private int ports[];
  private ByteBuffer echoBuffer = ByteBuffer.allocate(32000);

  public MultiPortEcho( int ports[] ) throws IOException
  {
    this.ports = ports;
    go();
  }

  private void go() throws IOException
  {
    // Create a new selector
    Selector selector = Selector.open();

    // Open a listener on each port, and register each one
    // with the selector
    for (int i=0; i<ports.length; ++i)
    {
      ServerSocketChannel ssc = ServerSocketChannel.open();
      ssc.configureBlocking( false );
      ServerSocket ss = ssc.socket();
      InetSocketAddress address = new InetSocketAddress( ports[i] );
      ss.bind( address );

      SelectionKey key = ssc.register( selector, SelectionKey.OP_ACCEPT );

      System.out.println( "Going to listen on "+ports[i] );
    }

    while (true)
    {
      int num = selector.select();
      System.out.println("num::::"+num);
      Set selectedKeys = selector.selectedKeys();
      Iterator it = selectedKeys.iterator();

      while (it.hasNext())
      {
        SelectionKey key = (SelectionKey)it.next();

        if ((key.readyOps() & SelectionKey.OP_ACCEPT)== SelectionKey.OP_ACCEPT)
          {
              // Accept the new connection
              ServerSocketChannel ssc = (ServerSocketChannel)key.channel();
              SocketChannel sc = ssc.accept();
              sc.configureBlocking( false );

              // Add the new connection to the selector
              SelectionKey newKey = sc.register(selector,SelectionKey.OP_READ);
              it.remove();

              System.out.println( "Got connection from "+sc );
        }
          else if ((key.readyOps() & SelectionKey.OP_READ)== SelectionKey.OP_READ)
          {
              // Read the data
              SocketChannel sc =(SocketChannel)key.channel();
              System.out.println("sc::::"+sc);
              // data to fetched from channel and dump into the datatbase
              int bytesEchoed = 0;
              //while(true)
              {
                    echoBuffer.clear();
                    int r = sc.read(echoBuffer);
                    System.out.println("r:::" + r);
                    /*int pos=echoBuffer.position();
                    System.out.println("pos:::" +pos);*/
                    if (r == -1)
                    {
                        //echoBuffer.flip();
                        echoBuffer.rewind();
                        byte[] array = new byte[100000];
                        while (echoBuffer.hasRemaining())
                        {
                            int n = echoBuffer.remaining();
                            System.out.println("size:" + n);
                            echoBuffer.get(array,0,n );
                            System.out.println(new String(array,0,n));
                            key.cancel();
                            it.remove();

                        }

                    }

                    /*int pos=echoBuffer.position();
                    System.out.println("pos:::" + pos);
                    if(r<=0)
                    {
                        echoBuffer.flip();
                        for (int j = 0; j < pos; j++ )
                        {
                            String ss =Integer.toHexString(echoBuffer.get());
                            if (ss.length() == 1)
                                System.out.print("0" + ss + " ");
                            else if (ss.length() > 2)
                                System.out.print(ss.substring(6) + " ");
                            else System.out.print(ss + " ");
                        }
                      break;
                    }

                    echoBuffer.flip();

                    sc.write( echoBuffer );
                    bytesEchoed += r;*/
              }

             //System.out.println( "Echoed "+bytesEchoed+" from "+sc );
             //it.remove();
        }

      }

//System.out.println( "going to clear" );
//      selectedKeys.clear();
//System.out.println( "cleared" );
    }
  }

  static public void main( String args[] ) throws Exception
  {
    FileOutputStream fileoutputstream = new FileOutputStream("MultiPort.txt", false);
    PrintStream printstream = new PrintStream(fileoutputstream);
    System.setOut(printstream);
    if (args.length<=0) {
      System.err.println( "Usage: java MultiPortEcho port [port port ...]" );
      System.exit( 1 );
    }

    int ports[] = new int[args.length];

    for (int i=0; i<args.length; ++i) {
      ports[i] = Integer.parseInt( args[i] );
    }

    new MultiPortEcho( ports );
  }
}
Respuesta 1

El tamaño máximo que puede leer está efectivamente limitado por la cantidad de memoria que tiene.

Sin embargo, no necesita leer bloques súper grandes para mayor eficiencia. Debería encontrar que 1 MB es más que suficiente. De hecho, es posible que los bloques de 4KB sean lo suficientemente grandes como para obtener el ancho de banda máximo para una conexión de 1 Gb.

Respuesta: 2

Un comentario sobre el diseño general:

Hay dos formas básicas de escribir servidores de red. Bloqueo y no bloqueo. En 2008, tuvimos la tarea de implementar un servidor de red de alto rendimiento en Python. Después de probar un par de formas diferentes con no bloqueo, descubrimos que era mucho más fácil y más claro de usar:

  • tomas de bloqueo
  • un hilo por conexión
  • un par de hilos de administrador

De esa manera, cada subproceso podría sentarse y esperar datos hasta el día de su muerte, y cuando recibiera un paquete completo, actuaría sobre eso.

Solo por consideración.

Respuesta: 3

Puede encontrar algunos clientes potenciales en este SocketChannelHandler , donde estas readFromChannel()funciones pueden ser de su interés.

        public void readFromChannel() {
        try {
                   [...]
                   if (readBuffer != null) {
                readBuffer.flip();
                receivingBroker.broker(readBuffer, false);
                if (readBuffer != null) {
                    readBuffer.clear();
                    readBuffer = null;
                }
            }
            if (readBuffer == null || !readBuffer.hasRemaining()) {
                getThread().removeInterestOp(this, SelectionKey.OP_READ);
                getThread().addInterestOp(this, SelectionKey.OP_WRITE);
            }
            if (receivingBroker.isClosed()) {
                if (getChannelListener() != null) {
                    getChannelListener().readFinished(this);
                }
            }
         } catch (Exception e) {
              e.printStackTrace();
         }
         }
Respuesta: 4

Como primera solución, debe eliminar la línea con key.cancel (). Mantenerlo cancelará la clave y asegurará que la clave no se considere después de la primera lectura, lo que efectivamente le impedirá leer cualquier cosa después.

Respuesta: 5

Quiero hacer algo como Set <String []> strSet = new HashSet <String []> (); ¿Hay una manera fácil de hacer un Conjunto de matrices en Java, o tengo que codificar mi propia implementación? Agregando un ...

Tengo un ViewPager dentro de un ScrollView. Necesito poder desplazarme tanto horizontal como verticalmente. Para lograr esto, tuve que desactivar el desplazamiento vertical cada vez que se toca mi ViewPager (...

Tengo una tabla que contiene registros con el tipo de datos DateTime en MySQL (por ejemplo, 2013-01-17 21:16:06), mientras que en mi entidad elijo el tipo de datos LocalDateTime para el campo de fecha. Durante mis consultas me gustaría ...

curl -XPOST 'localhost: 9200 / test / _open' curl -XPOST 'localhost: 9200 / test / _close' ¿Cómo lograr esto con la API de Java? Busqué en Google mucho pero no encontré ninguna solución.