Java NIO - kanał gniazda
Kanał gniazda Java NIO jest kanałem typu wybieralnego, co oznacza, że można go multipleksować za pomocą selektora, używanego do podłączania gniazd strumieniowego przepływu danych. Kanał gniazda można utworzyć, wywołując jego statyczny open() metoda, pod warunkiem, że żadne istniejące gniazdo nie jest jeszcze obecne. Kanał gniazda jest tworzony przez wywołanie metody otwartej, ale nie jest jeszcze połączony. connect() Jednym z punktów, o którym należy tutaj wspomnieć, jest to, że jeśli kanał nie jest podłączony i próbowano wykonać jakąkolwiek operację we / wy, wówczas ten kanał generuje wyjątek NotYetConnectedException. Po podłączeniu kanał pozostaje podłączony aż do jego zamknięcia. Stan kanału gniazda można określić poprzez wywołanie jego isConnected metoda.
Połączenie kanału gniazda można zakończyć, wywołując jego finishConnect() To, czy operacja połączenia jest w toku, może zostać ustalone przez wywołanie metody isConnectionPending. Domyślnie kanał gniazda obsługuje połączenia nieblokujące. Obsługuje również zamykanie asynchroniczne, które jest podobne do asynchronicznej operacji zamykania określonej w klasie Channel.
Kanały gniazd są bezpieczne do użytku przez wiele współbieżnych wątków. Obsługują równoczesne czytanie i pisanie, chociaż co najwyżej jeden wątek może być czytany i co najwyżej jeden wątek może pisać w danym momencie. Metody connect i finishConnect są wzajemnie synchronizowane, a próba zainicjowania operacji odczytu lub zapisu w trakcie wywoływania jednej z tych metod będzie blokowana do momentu zakończenia tego wywołania.
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.
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() and open((SocketAddress remote) - Metoda Open służy do otwierania kanału gniazda dla żadnego określonego adresu, podczas gdy sparametryzowana metoda otwarta otwiera kanał dla określonego adresu zdalnego, a także łączy się z nim Ta wygodna metoda działa tak, jakby wywoływała metodę open (), wywołując metodę connect na wynikowym gniazda kanału, przekazując go zdalnie, a następnie zwracając ten kanał.
read(ByteBuffer dst) - Ta metoda służy do odczytu danych z danego bufora przez kanał gniazda.
isConnectionPending() - Ta metoda określa, czy operacja połączenia jest w toku na tym kanale.
Przykład
Poniższy przykład pokazuje, jak wysyłać dane z Java NIO SocketChannel.
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