Java NIO - ServerSocket Channel

Kanał gniazda serwera Java NIO jest ponownie wybranym kanałem używanym do strumieniowego przepływu danych łączących gniazda. Kanał gniazda serwera można utworzyć, wywołując jego statyczny open() metoda, pod warunkiem, że żadne wcześniej istniejące gniazdo nie jest jeszcze obecne.Serwer Kanał gniazda jest tworzony przez wywołanie metody otwartej, ale nie jest jeszcze powiązany. bind() należy wywołać metodę.

Należy tu wspomnieć o tym, że jeśli kanał nie jest powiązany i próbowano wykonać jakąkolwiek operację we / wy, wówczas ten kanał generuje wyjątek NotYetBoundException, dlatego przed wykonaniem jakiejkolwiek operacji we / wy należy się upewnić, że kanał jest ograniczony.

Połączenia przychodzące dla kanału gniazda serwera są nasłuchiwane przez wywołanie metody ServerSocketChannel.accept (). Gdy metoda accept () powróci, zwraca SocketChannel z połączeniem przychodzącym. W ten sposób metoda accept () blokuje się do momentu nadejścia połączenia przychodzącego, a jeśli kanał jest w trybie nieblokującym, metoda accept natychmiast zwróci wartość null, jeśli nie ma połączeń oczekujących. W przeciwnym razie będzie blokować się na czas nieokreślony, aż dostępne będzie nowe połączenie lub wystąpi błąd we / wy.

Gniazdo nowego kanału jest początkowo niezwiązane; musi być powiązany z określonym adresem za pomocą jednej z metod wiązania jego gniazda, zanim połączenia będą mogły zostać zaakceptowane. Nowy kanał jest również tworzony przez wywołanie metody openServerSocketChannel domyślnego obiektu SelectorProvider dla całego systemu.

Podobnie jak serwer gniazda, kanał gniazda może odczytywać dane za pomocą read()Najpierw przydzielany jest bufor. Dane odczytane z ServerSocketChannel są przechowywane w buforze, po drugie wywołujemy metodę ServerSocketChannel.read () i odczytuje ona dane z ServerSocketChannel do bufora. Wartość całkowita metody read () zwraca liczbę bajtów zapisanych w buforze

Podobnie dane można zapisać w kanale gniazda serwera przy użyciu write() Powszechnie używa metody write w pętli while w celu powtórzenia metody write () do momentu, gdy Buffer nie będzie miał więcej bajtów do zapisu.

Ważne metody kanału Socket

  • bind(SocketAddress local) - Ta metoda służy do powiązania kanału gniazda z adresem lokalnym, który jest dostarczany jako parametr tej metody.

  • accept() - Ta metoda jest używana do akceptowania połączenia z gniazdem tego kanału.

  • connect(SocketAddress remote) - Ta metoda służy do podłączenia gniazda do zdalnego adresu.

  • finishConnect() - Ta metoda służy do zakończenia procesu podłączania kanału gniazda.

  • getRemoteAddress() - Ta metoda zwraca adres zdalnej lokalizacji, do której jest podłączone gniazdo kanału.

  • isConnected() - Jak już wspomniano, metoda ta zwraca stan połączenia kanału gniazda, tj. Czy jest on podłączony czy nie.

  • open() - Metoda Open służy do otwierania kanału gniazda dla żadnego określonego adresu. Ta wygodna metoda działa tak, jakby wywoływała metodę open (), wywoływała metodę connect na wynikowym kanale gniazda serwera, przekazywała go zdalnie, a następnie zwracała ten kanał.

  • read(ByteBuffer dst) - Ta metoda służy do odczytu danych z danego bufora przez kanał gniazda.

  • setOption(SocketOption<T> name, T value) - Ta metoda ustawia wartość opcji gniazda.

  • socket() - Ta metoda pobiera gniazdo serwera skojarzone z tym kanałem.

  • validOps() - Ta metoda zwraca zestaw operacji identyfikujący obsługiwane operacje tego kanału. Kanały z gniazdem serwera obsługują tylko akceptowanie nowych połączeń, więc ta metoda zwraca SelectionKey.OP_ACCEPT.

Przykład

Poniższy przykład pokazuje, jak wysyłać dane z Java NIO ServerSocketChannel.

C: /Test/temp.txt

Hello World!

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

Wynik

Uruchomienie klienta nie spowoduje wydrukowania niczego do czasu uruchomienia serwera.

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

Wynik

Uruchomienie serwera spowoduje wydrukowanie następujących informacji.

Connection Set:  /127.0.0.1:49558
File Received