Вы находитесь на странице: 1из 29

Buffers no bloqueantes

Un buffer tiene mejor desempeño que un flujo (stream),


ya que tiene un tamaño finito (capacidad), así
Como un estado (interno) que permite llevar el registro
y control de cuantos datos se han puesto
o leído de él.
Estructura de un buffer
Posición

Capacidad
Límite
Posición: 0
Marcado: sin definir
Límite: 9
Capacidad: 10
Clase Buffer (java.nio.Buffer) //abstracta

• Métodos: • Métodos:
• int capacity( ) • int position( )
• Buffer clear( ) • Buffer position(int p)
• Buffer flip( ) • int remaining( )
• abstract boolean hasArray( ) • Buffer reset( )
• Boolean hasRemaining( ) • Buffer rewind( )
• abstract boolean isDirect( )
• int limit( )
• Buffer limit(int l)
• Buffer mark( )
Clase ByteBuffer (java.nio.ByteBuffer)

• Métodos: • Métodos:
• static ByteBuffer allocate(int c) • abstract byte get( )
• static ByteBuffer allocateDirect(int c) • ByteBuffer get(byte[ ] dst )
• byte[ ] array( ) • abstract char getChar( )
• abstract CharBuffer asCharBuffer( ) • abstract double getDouble( )
• abstract IntBuffer asIntBuffer( ) • abstract int getInt( )
• abstract DoubleBuffer asDoubleBuffer( ) • abstract ByteBuffer put(byte b)
• abstract ShortBuffer asShortBuffer( ) • ByteBuffer put(byte[ ] b)
• abstract ByteBuffer duplicate( ) • abstract ByteBuffer putFloat(float f)
• boolean equals(Object o) • static ByteBuffer wrap(byte[ ] b)
Socket bloqueante (1/2)
•Las entradas y salidas son por naturaleza bloqueantes (no permiten
realizar nada mas hasta que terminen)
•En el caso de los sockets si no hay nada que procesar la instrucción se
queda dormida hasta que ocurra un evento que permita terminar la
operación
Socket bloqueante (2/2)
•Si realizamos operaciones de entrada (read, recv, recvfrom, etc.) sobre
el socket y no hay datos disponibles es proceso entrara al estado de
dormido hasta que haya datos para leer
•Si realizamos operaciones de salida (write, send, sendto, etc.) sobre el
socket, el kerner copia los datos del buffer de la aplicación en el buffer
de envio de datos, si no hay espacio en este último el proceso se
bloqueara hasta tener suficiente espacio
Socket no bloqueante
•En algunas ocasiones es preferible que no exista el bloqueo
mencionado
•Permite realizar otras tareas si no hay datos que manejar
•Hay dos maneras básicas de manejo:
•Polling
•Asíncrono
Polling
•Consiste en una operación de consulta constante
•Eso lo vuelve síncrono, ya que solo se procesa en un momento
determinado
Polling
Asíncrono
•En este caso, hay que esperar a que ocurra un evento de entrada o
salida y actuar en consecuencia
Clase ServerSocketChannel (abstract
java.nio.channels.ServerSocketChannel)
• Opciones de socket modificables:
• SO_RCVBUF
• SO_REUSEADDR

• Constructor:
• protected ServerSocketChannel(SelectorProvider sel)
Clase ServerSocketChannel (abstract
java.nio.channels.ServerSocketChannel)
• Métodos:
• static ServerSocketChannel open( )
• abstract SocketChannel accept( )
• ServerSocketChannel bind(SocketAddress d)
• abstract ServerSocketChannel bind(SocketAddress d, int backlog)
• abstract SocketAddress getLocalAddress( )
• abstract <T> ServerSocketChannel setOption(SocketOption <t>o, T val)
• abstract ServerSocket socket( )
• int validOps( )
*public final SelectableChannel configureBlocking(boolean block)
*public final SelectionKey register(Selector sel, int ops, Object att)
Clase SocketChannel (abstract
java.nio.channels.SocketChannel)
• Opciones de socket modificables:
• SO_SNDBUF
• SO_RCVBUF //Ej. s.setOption(StandardSocketOptions.SO_REUSEADDR,
• SO_REUSEADDR true);
• SO_KEEPALIVE
• SO_LINGER
• TCP_NODELAY

• Constructor:
• protected SocketChannel(SelectorProvider sel)
Clase SocketChannel (abstract
java.nio.channels.ServerSocketChannel)
• Métodos:
• static SocketChannel open( )
• abstract SocketChannel bind(SocketAddress l )
• abstract boolean connect(SocketAddress dst)
• abstract boolean finishConnect( )
• abstract SocketAddress getLocalAddress( )
• abstract SocketAddress getRemoteAddress( )
• abstract <T> SocketChannel setOption(SocketOption <t>o, T val)
• abstract Socket socket( )
• int validOps( )
Clase SocketChannel (abstract
java.nio.channels.ServerSocketChannel)
• Métodos:
• abstract int read(ByteBuffer b)
• abstract SocketChannel ShutdownInput( )
• abstract SocketChannel ShutdownOutput( )
• abstract int write(ByteBuffer b)
*public final SelectableChannel configureBlocking(boolean block)
*public final SelectionKey register(Selector sel, int ops, Object att)
Clase Selector (abstract java.nio.channels.Selector)

• Métodos:
• static Selector open( )
• abstract void close( )
• abstract int select( )
• abstract int select(long t)
• abstract Set<SelectionKey> selectedKeys( )
Estructura de un servidor (1/4)
try{
ServerSocketChannel s = ServerSocketChannel.open( );
s.configureBlocking(false);
s.setOption(StandardSocketOptions,SO_REUSEADDR,true);
InetSocketAddress l = new InetSocketAddress(1234);
s.socket().bind(l);
Selector sel = Selector.open();
s.register(sel,SelectionKey.OP_ACCEPT);
for(;;){
sel.select();
Estructura de un servidor (2/4)

Iterator<SelectionKey>it = sel.selectedKeys( ).iterator( );


while(it.hasNext( )){
SelectionKey k = (SelectionKey)it.next( );
it.remove( );
if(k.isAcceptable( )){
SocketChannel cl = s.accept( );
System.out.println(“Cliente conectado desde ”+cl.socket(
).getInetAddress( )+”:”+cl.socket( ).getPort( ));
cl.configureBlocking(false);
Estructura de un servidor (3/4)

cl.register(sel,SelectionKey.OP_READ|SelectionKey.OP_WRITE);
continue;
}//if
if(k.isReadable()){
SocketChannel ch = (SocketChannel)k.channel( );
ByteBuffer b= ByteBuffer.allocate(100);
b.clear();
ch.read(b);
continue;
Estructura de un servidor (4/4)

}else if(k.isWritable()){
SocketChannel ch = (SocketChannel)k.channel( );
String msj=“un mensaje”;
byte[ ] b = msj.getBytes();
ByteBuffer buf = ByteBuffer.wrap(b);
ch.write(buf);
continue;
}//if
}//while
}//for
}catch(Exception e){ … }
Estructura de un cliente (1/4)
try{
InetAddress dir = InetAddress.getByName(“127.0.0.1”);
SocketChannel cl = SocketChannel.open( );
cl.configureBlocking(false);
InetSocketAddress dst = new InetSocketAddress(dir,1234);
Selector sel = Selector.open();
cl.connect(dst);
cl.register(sel,SelectionKey.OP_CONNECT);
while(true){
sel.select();
Estructura de un cliente (2/4)

Iterator<SelectionKey>it = sel.selectedKeys( ).iterator( );


while(it.hasNext( )){
SelectionKey k = (SelectionKey)it.next( );
it.remove( );
if(k.isConnectable( )){
SocketChannel ch = (SocketChannel)k.channel( );
if(ch.isConnectionPending()){
try{
ch.finishConnect();
Estructura de un cliente (3/4)
System.out.println(“Conexión establecida”);
}catch(Exception e){ . . .}
}//if
ch.register(sel,SelectionKey.OP_READ|SelectionKey.OP_WRITE);
continue;
}//if
if(k.isReadable()){
SocketChannel ch2 = (SocketChannel)k.channel( );
ByteBuffer b= ByteBuffer.allocate(100);
b.clear();
ch2.read(b);
continue;
Estructura de un cliente (4/4)

}else if(k.isWritable()){
SocketChannel ch2 = (SocketChannel)k.channel( );
String msj=“un mensaje”;
byte[ ] b = msj.getBytes();
ByteBuffer buf = ByteBuffer.wrap(b);
ch2.write(buf);
continue;
}//if
}//while
}//for
}catch(Exception e){ … }
Ej. EcoS.java, EcoC.java, Sender.java, Receiver.java, SNB.java, CNB.java
Clase java.nio.channels.DatagramChannel

• Opciones modificables:
• SO_SNDBUF
• SO_RCVBUF
• SO_REUSEADDR
• SO_BROADCAST
• IP_TOS
• IP_MULTICAST_IF
• IP_MULTICAST_TTL
• IP_MULTICAST_LOOP
Clase DatagramChannel
Métodos
• abstract DatagramChannel bind(SocketAddress l)
• abstract DatagramChannel connect(SocketAddress dst)
• abstract DatagramChannel disconnect( )
• abstract SocketAddress getLocalAddress( )
• abstract SocketAddress getRemoteAddress( )
• abstract boolean isConnected( )
• static DatagramChannel open( )
• static DatagramChannel open(ProtocolFamily f)
Clase DatagramChannel
Métodos
• abstract int read(ByteBuffer b)
• long read(ByteBuffer [ ] dst)
• abstract SocketAddress receive(ByteBuffer b)
• abstract int send(ByteBuffer b, SocketAddress dst)
• abstract <T> DatagramChannel setOption(SocketOption<T> op, T v)
• abstract DatagramSocket socket( )
• abstract int write(ByteBuffer b)

Ej. UDPC.java, UDPS.java, USNB.java, UCNB.java, USNBC.java, UCNBC.java


Sockets multicast no bloqueantes
• Opciones de socket a ser modificadas:
• SO_REUSEADDR
• IP_MULTICAST_IF
• IP_MULTICAST_TTL
Ej.
System.out.print("\nElige la interfaz multicast:");
int interfaz = Integer.parseInt(br.readLine());
//NetworkInterface ni = NetworkInterface.getByName("eth2");
NetworkInterface ni = NetworkInterface.getByIndex(interfaz);
br.close();
System.out.println("\nElegiste "+ni.getDisplayName());
DatagramChannel channel = DatagramChannel.open(StandardProtocolFamily.INET);
channel.configureBlocking(false);
channel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
channel.setOption(StandardSocketOptions.IP_MULTICAST_IF, ni);
channel.setOption(StandardSocketOptions.IP_MULTICAST_TTL, 128);
InetAddress group = InetAddress.getByName("230.0.0.1");
channel.join(group, ni);
Selector selector = Selector.open();
channel.register(selector,SelectionKey.OP_WRITE);

Вам также может понравиться