¿Cuál es la mejor manera de implementar un zócalo sin bloqueo en Java? ¿O hay tal cosa? Tengo un programa que se comunica con un servidor a través del socket, pero no quiero que la llamada del socket bloquee/cause demora si hay un problema con los datos/conexión.zócalo Java sin bloqueo
Respuesta
paquete java.nio ofrece Selector de trabajo muy similar a como en C.
Aparte de usar IO no bloqueo, podría encontrar que es mucho más fácil de tener un hilo de escritura para su conexión.
Varias de estas respuestas son incorrectas. SocketChannel.configureBlocking(false) lo pone en modo sin bloqueo. No necesitas un Selector para hacer eso. Solo necesita un Selector para implementar tiempos de espera o multiplexado E/S con sockets no bloqueantes.
Acabo de escribir este código. Funciona bien . Este es un ejemplo de Java NIO como se menciona en las respuestas anteriores, pero aquí publico el código.
ServerSocketChannel ssc = null;
try {
ssc = ServerSocketChannel.open();
ssc.socket().bind(new InetSocketAddress(port));
ssc.configureBlocking(false);
while (true) {
SocketChannel sc = ssc.accept();
if (sc == null) {
// No connections came .
} else {
// You got a connection. Do something
}
}
} catch (IOException e) {
e.printStackTrace();
}
inutilizable. Este código girará en bucle mientras no haya conexiones. Una versión sensata de esto usaría modo de bloqueo o un 'Selector'. – EJP
Creo que esta solución es muy similar al enfoque de bloqueo, la idea de usar un enfoque no bloqueante es crear un controlador para manejar el aceptar cada vez que ocurra ese evento . Cuando usa esto mientras (verdadero) para obtener el socket es como si estuviera bloqueando el hilo hasta que ocurra una conexión con el cliente. – Teocci
Java no bloqueando toma, introducido en Java 2 Standard Edition 1.4, permitir la comunicación entre aplicaciones neta sin el bloqueo de los procesos mediante los zócalos. Pero, ¿qué es un socket sin bloqueo, en qué contextos puede ser útil y cómo funciona?
¿Qué es una toma sin bloqueo?
Un zócalo sin bloqueo permite la operación de entrada/salida en un canal sin bloquear los procesos que lo utilizan. Esto significa un "asíncrono de alto rendimiento" operaciones de lectura/escritura (algunas personas no pueden convenidas con él)
Ok, en qué contextos puede ser útil?
Supongamos que desea implementar un servidor que acepte conexiones de clientes diversas. Supongamos, también, que le gustaría que el servidor pueda procesar múltiples solicitudes simultáneamente. Utilizando la forma tradicional, tiene dos opciones para desarrollar dicho servidor:
- Implemente un servidor multihilo que maneje manualmente un hilo para cada conexión.
- Uso de un módulo externo de terceros.
Ambas soluciones funcionan, pero si se adopta la primera, debe desarrollar toda la solución de administración de subprocesos, con concurrencia relacionada y problemas de conflicto. La segunda solución hace que la aplicación dependa de un módulo externo que no sea JDK y probablemente deba adaptar la biblioteca a sus necesidades. Mediante el socket sin bloqueo, puede implementar un servidor sin bloqueo sin gestionar directamente los hilos o recurrir a módulos externos.
Cómo funciona?
Por ejemplo, puede utilizar la clase AsynchronousServerSocketChannel
, que proporciona un canal asincrónico sin bloqueo para sockets de escucha orientados a la transmisión.
Para usarlo, primero ejecutar su método estático open()
y luego bind()
a un puerto específico . A continuación, ejecutará su método accept()
, transfiriéndole una clase que implementa la interfaz CompletionHandler
. Muy a menudo, encontrará ese controlador creado como clase interna anónima.
Desde este objeto AsynchronousServerSocketChannel
, invoca accept()
para que comience a escuchar conexiones, pasando a una instancia personalizada CompletionHandler
. Cuando invocamos accept()
, regresa inmediatamente. Tenga en cuenta que esto es diferente del enfoque de bloqueo tradicional; mientras que el método accept()
bloqueado hasta que un cliente conectado al mismo, el método AsynchronousServerSocketChannel
accept()
lo maneje por usted.
Aquí tienes un ejemplo:
public class NioSocketServer
{
public NioSocketServer()
{
try {
// Create an AsynchronousServerSocketChannel that will listen on port 5000
final AsynchronousServerSocketChannel listener = AsynchronousServerSocketChannel
.open()
.bind(new InetSocketAddress(5000));
// Listen for a new request
listener.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>()
{
@Override
public void completed(AsynchronousSocketChannel ch, Void att)
{
// Accept the next connection
listener.accept(null, this);
// Greet the client
ch.write(ByteBuffer.wrap("Hello, I am Echo Server 2020, let's have an engaging conversation!\n".getBytes()));
// Allocate a byte buffer (4K) to read from the client
ByteBuffer byteBuffer = ByteBuffer.allocate(4096);
try {
// Read the first line
int bytesRead = ch.read(byteBuffer).get(20, TimeUnit.SECONDS);
boolean running = true;
while (bytesRead != -1 && running) {
System.out.println("bytes read: " + bytesRead);
// Make sure that we have data to read
if (byteBuffer.position() > 2) {
// Make the buffer ready to read
byteBuffer.flip();
// Convert the buffer into a line
byte[] lineBytes = new byte[bytesRead];
byteBuffer.get(lineBytes, 0, bytesRead);
String line = new String(lineBytes);
// Debug
System.out.println("Message: " + line);
// Echo back to the caller
ch.write(ByteBuffer.wrap(line.getBytes()));
// Make the buffer ready to write
byteBuffer.clear();
// Read the next line
bytesRead = ch.read(byteBuffer).get(20, TimeUnit.SECONDS);
} else {
// An empty line signifies the end of the conversation in our protocol
running = false;
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
// The user exceeded the 20 second timeout, so close the connection
ch.write(ByteBuffer.wrap("Good Bye\n".getBytes()));
System.out.println("Connection timed out, closing connection");
}
System.out.println("End of conversation");
try {
// Close the connection if we need to
if (ch.isOpen()) {
ch.close();
}
} catch (I/OException e1)
{
e1.printStackTrace();
}
}
@Override
public void failed(Throwable exc, Void att)
{
///...
}
});
} catch (I/OException e) {
e.printStackTrace();
}
}
public static void main(String[] args)
{
NioSocketServer server = new NioSocketServer();
try {
Thread.sleep(60000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
puede encontrar the full code here
- 1. zócalo Java TLS-PSK
- 2. Java - Extraño zócalo colgante?
- 3. zócalo java writeUTF() y readUTF()
- 4. Bloqueo sin bloqueo
- 5. Java zócalo y ServerSocket Edición
- 6. Registro remoto asíncrono sin bloqueo en Java?
- 7. Java Serializable, ObjectInputstream, E/S sin bloqueo
- 8. Asignación de memoria sin bloqueo de Java
- 9. Archivo sin bloqueo lee
- 10. Construcciones sin bloqueo en .net
- 11. ¿Cómo puedo obtener socket connect() sin bloqueo?
- 12. getch sin bloqueo(), ncurses
- 13. ¿Colección concurrente sin bloqueo?
- 14. Javascript sin bloqueo
- 15. Sin bloqueo pthread_join
- 16. Bloqueo parcial en java
- 17. select(), recv() y EWOULDBLOCK en sockets sin bloqueo
- 18. Bloqueo de archivos Java
- 19. bloqueo de subproceso Java
- 20. bloqueo gama en java
- 21. Java doble bloqueo bloqueado
- 22. ¿Cómo se implementa IO sin bloqueo?
- 23. Descarga de javascript sin bloqueo
- 24. Programación multiprocesador: pilas sin bloqueo
- 25. Tubos con nombre sin bloqueo
- 26. Rieles: ¿solicitudes HTTP sin bloqueo?
- 27. ¿Probar un bloqueo sin adquirirlo?
- 28. Diálogo modal de bloqueo sin bloqueo Swing progress
- 29. Cerraduras de bloqueo frente a cerraduras sin bloqueo
- 30. Llamada recv() en el mismo zócalo de bloqueo de dos hilos
Hola, creo que su pregunta hace poco, pero creo que es un poco tarde. De todos modos, creo que es una buena pregunta, así que aquí está mi respuesta. – Teocci