Java NIO - ServerSocket Channel

Le canal de socket du serveur Java NIO est à nouveau un canal de type sélectionnable utilisé pour les sockets de connexion de flux de données orientés flux.Le canal de socket serveur peut être créé en appelant son canal statique. open() , à condition qu'aucune socket préexistante ne soit déjà présente.Le canal de socket serveur est créé en invoquant une méthode ouverte mais pas encore lié.Afin de lier le canal de socket bind() la méthode doit être appelée.

Un point à mentionner ici est que si le canal n'est pas lié et qu'une opération d'E / S est tentée, alors NotYetBoundException est levée par ce canal.Il faut donc s'assurer que le canal est borné avant d'effectuer toute opération d'E / S.

Les connexions entrantes pour le canal de socket du serveur sont écoutées en appelant la méthode ServerSocketChannel.accept (). Lorsque la méthode accept () retourne, elle renvoie un SocketChannel avec une connexion entrante. Ainsi, la méthode accept () se bloque jusqu'à ce qu'une connexion entrante arrive. Si le canal est en mode non bloquant, la méthode accept retournera immédiatement null s'il n'y a pas de connexions en attente. Sinon, il se bloquera indéfiniment jusqu'à ce qu'une nouvelle connexion soit disponible ou qu'une erreur d'E / S se produise.

Le socket du nouveau canal est initialement non lié; il doit être lié à une adresse spécifique via l'une des méthodes de liaison de son socket avant que les connexions puissent être acceptées. De plus, le nouveau canal est créé en appelant la méthode openServerSocketChannel de l'objet SelectorProvider par défaut à l'échelle du système.

Comme le canal de socket, le canal de socket du serveur peut lire des données en utilisant read()Le tampon est d'abord alloué. Les données lues à partir d'un ServerSocketChannel sont stockées dans le tampon. Deuxièmement, nous appelons la méthode ServerSocketChannel.read () et il lit les données d'un ServerSocketChannel dans un tampon. La valeur entière de la méthode read () renvoie le nombre d'octets écrits dans le tampon

De même, les données peuvent être écrites sur le canal de socket du serveur en utilisant write() utilisant buffer comme paramètre. Utilise couramment la méthode write dans une boucle while pour répéter la méthode write () jusqu'à ce que Buffer n'ait plus d'octets disponibles pour écrire.

Méthodes importantes de canal de socket

  • bind(SocketAddress local) - Cette méthode est utilisée pour lier le canal de socket à l'adresse locale qui est fournie comme paramètre de cette méthode.

  • accept() - Cette méthode est utilisée pour accepter une connexion établie à la prise de ce canal.

  • connect(SocketAddress remote) - Cette méthode est utilisée pour connecter la prise à l'adresse distante.

  • finishConnect() - Cette méthode est utilisée pour terminer le processus de connexion d'un canal de socket.

  • getRemoteAddress() - Cette méthode renvoie l'adresse de l'emplacement distant auquel la prise du canal est connectée.

  • isConnected() - Comme déjà mentionné cette méthode retourne l'état de connexion du canal de socket c'est à dire s'il est connecté ou non.

  • open() - La méthode Open est utilisée pour ouvrir un canal de socket pour aucune adresse spécifiée. Cette méthode pratique fonctionne comme en invoquant la méthode open (), en invoquant la méthode de connexion sur le canal de socket du serveur résultant, en le passant à distance, puis en renvoyant ce canal.

  • read(ByteBuffer dst) - Cette méthode est utilisée pour lire les données du tampon donné via le canal socket.

  • setOption(SocketOption<T> name, T value) - Cette méthode définit la valeur d'une option de socket.

  • socket() - Cette méthode récupère un socket serveur associé à ce canal.

  • validOps() - Cette méthode renvoie un ensemble d'opérations identifiant les opérations prises en charge par ce canal. Les canaux de socket serveur ne prennent en charge que l'acceptation de nouvelles connexions, donc cette méthode retourne SelectionKey.OP_ACCEPT.

Exemple

L'exemple suivant montre comment envoyer des données à partir de Java NIO ServerSocketChannel.

C: /Test/temp.txt

Hello World!

Client: 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();
   }
}

Production

L'exécution du client n'imprimera rien avant le démarrage du serveur.

Serveur: 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();
   }
}

Production

L'exécution du serveur imprimera ce qui suit.

Connection Set:  /127.0.0.1:49558
File Received