Qual è il modo migliore per implementare un socket non bloccante in Java? O c'è una cosa del genere? Ho un programma che comunica con un server tramite socket ma non voglio che la chiamata socket blocchi/causi ritardo se c'è un problema con i dati/connessione.Presa Java non bloccante
risposta
pacchetto java.nio fornisce Selettore di lavoro molto simile a come in C.
Oltre ad utilizzare non IO blocco, si potrebbe trovare è molto più semplice di avere un filo di scrittura per la connessione.
Molte di queste risposte non sono corrette. SocketChannel.configureBlocking(false) lo mette in modalità non bloccante. Non hai bisogno di un selettore per farlo. È necessario solo un selettore per implementare timeout o multiplexed I/O con socket non bloccanti.
Ho appena scritto questo codice. Funziona bene . Questo è un esempio di NIO Java come menzionato nelle risposte precedenti ma qui inserisco il codice.
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();
}
Inusabile. Questo codice girerà in loop mentre non ci sono connessioni. Una versione sana di questo userebbe la modalità di blocco o un 'Selector'. – EJP
Penso che questa soluzione sia molto simile all'approccio di blocco, l'idea di usare un approccio non bloccante è creare un gestore per gestire l'accettazione ogni volta che si verifica quell'evento . Quando si utilizza questo mentre (true) per ottenere il socket è come si sta bloccando il thread fino a quando si verifica una connessione client. – Teocci
Java socket non bloccante, introdotto in Java 2 Standard Edition 1.4, consentire la comunicazione tra le applicazioni netto senza ostruire i processi utilizzando le prese. Ma cos'è un socket non bloccante, in quali contesti può essere utile e come funziona?
Che socket non bloccante è?
Un socket non bloccante consente l'operazione di input/output su un canale senza bloccare i processi che lo utilizzano. Ciò significa che un "asincrona ad alte prestazioni" operazioni lettura/scrittura (alcune persone potrebbero non concordate con quella)
Ok, In quali contesti può essere utile?
Supponiamo che si desideri implementare un server che accetta connessioni client diverse. Supponiamo, inoltre, che il server sia in grado di elaborare più richieste contemporaneamente. Usando il modo tradizionale hai due opzioni per sviluppare un server del genere:
- Implementare un server multi-thread che gestisce manualmente un thread per ciascuna connessione.
- Utilizzo di un modulo esterno di terze parti.
Entrambe le soluzioni funzionano, ma adottando la prima è necessario sviluppare l'intera soluzione di gestione dei thread, con relativi problemi di concorrenza e conflitto. La seconda soluzione rende l'applicazione dipendente da un modulo esterno non JDK e probabilmente devi adattare la libreria alle tue necessità. Tramite il socket non bloccante, è possibile implementare un server non bloccante senza gestire direttamente i thread o ricorrere a moduli esterni.
Come funziona?
Ad esempio, è possibile utilizzare la classe AsynchronousServerSocketChannel
, che fornisce un canale asincrono non bloccante per socket di ascolto orientati al flusso.
di usarlo, prima di eseguire il metodo statico open()
e poi bind()
ad una specifica porto. Successivamente, eseguirai il suo metodo accept()
, passando ad esso una classe che implementa l'interfaccia CompletionHandler
. Molto spesso, troverai questo gestore creato come classe interna anonima .
Da questo oggetto AsynchronousServerSocketChannel
, si invoca accept()
per indicare che inizia l'ascolto delle connessioni, passando ad esso un'istanza personalizzata CompletionHandler
. Quando invochiamo accept()
, restituisce immediatamente. Si noti che questo è diverso dal tradizionale approccio di blocco; mentre il metodo bloccato fino a quando un client si è connesso a esso, il metodo AsynchronousServerSocketChannel
accept()
lo gestisce per te.
Ecco un esempio:
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();
}
}
}
Potete trovare the full code here
- 1. non bloccante presa, l'errore è sempre
- 2. Allocazione memoria Java non bloccante
- 3. Risoluzione DNS non bloccante (asincrona) in Java
- 4. Java serializzabile, ObjectInputstream, I/O non bloccante
- 5. Registrazione remota non bloccante asincrona in Java?
- 6. Java - Strana presa sospesa?
- 7. Presa Java/serializzazione, l'oggetto non verrà aggiornato
- 8. Presa raw in java
- 9. Perché FileChannel in Java non è non bloccante?
- 10. PHP Inotify Modo non bloccante
- 11. getch non bloccante(), ncurses
- 12. Raccolta simultanea non bloccante?
- 13. Sottoprocesso non bloccante
- 14. Scrapy: pausa non bloccante
- 15. Connessione non bloccante
- 16. non bloccante getch()
- 17. Esiste una raccolta limitata non bloccante in Java?
- 18. Il socket Java non genera eccezioni su una presa morta?
- 19. Come viene implementato l'I/O non bloccante?
- 20. Linux, socket, connessione non bloccante
- 21. perché concurrent_queue non è bloccante?
- 22. Kombu in modalità non bloccante
- 23. Ingresso console non bloccante Python
- 24. ruby linea non bloccante read
- 25. Accesso in esecuzione non bloccante?
- 26. jQuery Dialogo modale dell'interfaccia utente non bloccante
- 27. Accesso file non bloccante con Twisted
- 28. Come posso eseguire un System.Beep() non bloccante?
- 29. sostituire il sistema() con funzione non bloccante
- 30. Connessione socket non bloccante su SSL?
Ciao, ho trovato la tua domanda da poco ma penso che è un po 'in ritardo. Comunque penso sia una buona domanda, quindi ecco la mia risposta .. – Teocci