Java NIO - ServerSocket Kanalı
Java NIO sunucu soket kanalı yine akış yönelimli veri akışı bağlantı soketleri için kullanılan seçilebilir tip bir kanaldır.Sunucu Soket kanalı statikini çağırarak oluşturulabilir. open() yöntemi, önceden var olan herhangi bir soket sağlamak için zaten mevcut değildir.Sunucu Soket kanalı, açık yöntemi çağırarak oluşturulur, ancak henüz bağlı değildir. soket kanalına bağlanmak için bind() yöntem çağrılacak.
Burada belirtilmesi gereken bir nokta, eğer kanal bağlı değilse ve herhangi bir G / Ç işlemi denenmeye çalışılırsa, bu kanal tarafından NotYetBoundException atılır.Bu nedenle, herhangi bir IO işlemi gerçekleştirmeden önce kanalın sınırlı olduğundan emin olunmalıdır.
Sunucu soket kanalı için gelen bağlantılar, ServerSocketChannel.accept () yöntemi çağrılarak dinlenir. Accept () yöntemi döndüğünde, gelen bağlantıyla bir SocketChannel döndürür. Bu nedenle, kabul () yöntemi gelen bir bağlantı gelene kadar bloke eder. Kanal, engellemesiz moddaysa, bekleyen bağlantı yoksa, kabul yöntemi hemen boş döndürür. Aksi takdirde, yeni bir bağlantı sağlanana veya bir G / Ç hatası oluşana kadar süresiz olarak bloke olacaktır.
Yeni kanalın soketi başlangıçta bağlantısızdır; bağlantılar kabul edilmeden önce soketinin bağlama yöntemlerinden biri aracılığıyla belirli bir adrese bağlanması gerekir.Ayrıca yeni kanal, sistem genelinde varsayılan SelectorProvider nesnesinin openServerSocketChannel yöntemi çağrılarak oluşturulur.
Soket kanalı gibi sunucu soket kanalı da verileri okuyabilir read()İlk olarak tampon tahsis edilir. ServerSocketChannel'dan okunan veriler arabellekte depolanır. İkincisi, ServerSocketChannel.read () yöntemini çağırırız ve bir ServerSocketChannel'dan verileri bir arabelleğe okur. Read () yönteminin tamsayı değeri, arabelleğe kaç bayt yazıldığını döndürür
Benzer şekilde veriler sunucu soket kanalına kullanılarak yazılabilir. write() Bir parametre olarak arabelleği kullanan yöntem. Genellikle, Arabellek'te yazmak için başka bayt kalmayıncaya kadar write () yöntemini tekrarlamak gerektiğinden, bir while döngüsünde yazma yöntemini kullanır.
Soket kanalının önemli yöntemleri
bind(SocketAddress local) - Bu yöntem, soket kanalını bu yönteme parametre olarak sağlanan yerel adrese bağlamak için kullanılır.
accept() - Bu yöntem, bu kanalın soketine yapılan bir bağlantıyı kabul etmek için kullanılır.
connect(SocketAddress remote) - Bu yöntem soketi uzak adrese bağlamak için kullanılır.
finishConnect() - Bu yöntem, bir soket kanalı bağlama işlemini bitirmek için kullanılır.
getRemoteAddress() - Bu yöntem, kanal soketinin bağlı olduğu uzak konumun adresini döndürür.
isConnected() - Daha önce de belirtildiği gibi, bu yöntem soket kanalının bağlantı durumunu, yani bağlı olup olmadığını döndürür.
open() - Açık yöntemi, belirtilmemiş bir adres için bir soket kanalını açmak için kullanılır.Bu kolaylık yöntemi, open () yöntemini çağırarak, ortaya çıkan sunucu soket kanalı üzerinde bağlantı yöntemini çağırarak, onu uzaktan geçirerek ve sonra o kanalı döndürerek çalışır.
read(ByteBuffer dst) - Bu yöntem, verilen arabellekteki verileri soket kanalı üzerinden okumak için kullanılır.
setOption(SocketOption<T> name, T value) - Bu yöntem, bir soket seçeneğinin değerini belirler.
socket() - Bu yöntem, bu kanalla ilişkilendirilmiş bir sunucu soketini alır.
validOps() - Bu yöntem, bu kanalın desteklenen işlemlerini tanımlayan bir işlem kümesi döndürür.Sunucu soket kanalları yalnızca yeni bağlantıların kabul edilmesini destekler, bu nedenle bu yöntem SelectionKey.OP_ACCEPT döndürür.
Misal
Aşağıdaki örnek, Java NIO ServerSocketChannel'dan nasıl veri gönderileceğini gösterir.
C: /Test/temp.txt
Hello World!
İstemci: 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();
}
}
Çıktı
İstemciyi çalıştırmak, sunucu başlayana kadar hiçbir şey yazdırmaz.
Sunucu: 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();
}
}
Çıktı
Sunucuyu çalıştırmak aşağıdakileri yazdıracaktır.
Connection Set: /127.0.0.1:49558
File Received