Java NIO - Socket Channel

Il canale socket Java NIO è un canale di tipo selezionabile, il che significa che può essere multiplexato utilizzando il selettore, utilizzato per il flusso di dati orientato al flusso di connessione dei socket.Il canale socket può essere creato invocando il suo statico open() , a condizione che non sia già presente un socket preesistente.Il canale socket viene creato invocando il metodo aperto ma non ancora connesso.Per connettere il canale socket connect() Un punto da menzionare qui è che se il canale non è connesso e viene tentata qualsiasi operazione di I / O, allora NotYetConnectedException viene lanciata da questo canale.Quindi bisogna assicurarsi che il canale sia connesso prima di eseguire qualsiasi IO Una volta connesso, il canale rimane connesso fino a quando non viene chiuso. Lo stato del canale socket può essere determinato invocando il suo isConnected metodo.

La connessione del canale socket potrebbe essere completata invocando il suo finishConnect() È possibile determinare se un'operazione di connessione è in corso o meno richiamando il metodo isConnectionPending. Per impostazione predefinita, il canale socket supporta la connessione non bloccante. Supporta inoltre l'arresto asincrono, che è simile all'operazione di chiusura asincrona specificata nella classe Channel.

I canali socket possono essere utilizzati da più thread simultanei. Supportano la lettura e la scrittura simultanee, sebbene al massimo un thread possa leggere e al massimo un thread possa scrivere in un dato momento. I metodi connect e finishConnect sono sincronizzati reciprocamente e un tentativo di avviare un'operazione di lettura o scrittura mentre è in corso una chiamata di uno di questi metodi si bloccherà fino al completamento di tale chiamata.

Metodi importanti del canale Socket

  • bind(SocketAddress local) - Questo metodo viene utilizzato per associare il canale socket all'indirizzo locale fornito come parametro a questo metodo.

  • connect(SocketAddress remote) - Questo metodo viene utilizzato per connettere la presa all'indirizzo remoto.

  • finishConnect() - Questo metodo viene utilizzato per completare il processo di connessione di un canale socket.

  • getRemoteAddress() - Questo metodo restituisce l'indirizzo della posizione remota a cui è connesso il socket del canale.

  • isConnected() - Come già accennato questo metodo restituisce lo stato di connessione del canale socket cioè se è connesso o meno.

  • open() and open((SocketAddress remote) - Il metodo Open viene utilizzato per aprire un canale socket per nessun indirizzo specificato mentre il metodo open parametrizzato apre il canale per l'indirizzo remoto specificato e si connette anche ad esso.Questo metodo pratico funziona come se invocasse il metodo open (), invocando il metodo di connessione al risultato canale socket, passandolo remoto e quindi restituendo quel canale.

  • read(ByteBuffer dst) - Questo metodo viene utilizzato per leggere i dati dal buffer specificato attraverso il canale socket.

  • isConnectionPending() - Questo metodo indica se è in corso un'operazione di connessione su questo canale.

Esempio

L'esempio seguente mostra come inviare dati da Java NIO SocketChannel.

C: /Test/temp.txt

Hello World!

Cliente: SocketChannelClient.java

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.EnumSet;

public class SocketChannelClient {
   public static void main(String[] args) throws IOException {
      ServerSocketChannel serverSocket = null;
      SocketChannel client = null;
      serverSocket = ServerSocketChannel.open();
      serverSocket.socket().bind(new InetSocketAddress(9000));
      client = serverSocket.accept();
      System.out.println("Connection Set:  " + client.getRemoteAddress());
      Path path = Paths.get("C:/Test/temp1.txt");
      FileChannel fileChannel = FileChannel.open(path, 
         EnumSet.of(StandardOpenOption.CREATE, 
            StandardOpenOption.TRUNCATE_EXISTING,
            StandardOpenOption.WRITE)
         );      
      ByteBuffer buffer = ByteBuffer.allocate(1024);
      while(client.read(buffer) > 0) {
         buffer.flip();
         fileChannel.write(buffer);
         buffer.clear();
      }
      fileChannel.close();
      System.out.println("File Received");
      client.close();
   }
}

Produzione

L'esecuzione del client non stamperà nulla fino all'avvio del server.

Server: SocketChannelServer.java

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Path;
import java.nio.file.Paths;

public class SocketChannelServer {
   public static void main(String[] args) throws IOException {
      SocketChannel server = SocketChannel.open();
      SocketAddress socketAddr = new InetSocketAddress("localhost", 9000);
      server.connect(socketAddr);

      Path path = Paths.get("C:/Test/temp.txt");
      FileChannel fileChannel = FileChannel.open(path);
      ByteBuffer buffer = ByteBuffer.allocate(1024);
      while(fileChannel.read(buffer) > 0) {
         buffer.flip();
         server.write(buffer);
         buffer.clear();
      }
      fileChannel.close();
      System.out.println("File Sent");
      server.close();
   }
}

Produzione

L'esecuzione del server stamperà quanto segue.

Connection Set:  /127.0.0.1:49558
File Received