Java NIO - Kênh ServerSocket
Kênh ổ cắm máy chủ Java NIO một lần nữa là một kênh loại có thể lựa chọn được sử dụng cho các ổ cắm kết nối luồng dữ liệu định hướng luồng. Có thể tạo kênh Ổ cắm máy chủ bằng cách gọi tĩnh của nó. open() phương thức, cung cấp bất kỳ ổ cắm nào tồn tại từ trước đều không có sẵn. Kênh Ổ cắm máy chủ được tạo bằng cách gọi phương thức mở nhưng chưa bị ràng buộc. Để liên kết kênh ổ cắm. bind() phương thức được gọi.
Một điểm cần được đề cập ở đây là nếu kênh không bị ràng buộc và bất kỳ hoạt động I / O nào được cố gắng thực hiện thì NotYetBoundException sẽ được đưa ra bởi kênh này. Vì vậy, người ta phải đảm bảo rằng kênh đó được giới hạn trước khi thực hiện bất kỳ hoạt động IO nào.
Các kết nối đến cho kênh ổ cắm máy chủ được lắng nghe bằng cách gọi phương thức ServerSocketChannel.accept (). Khi phương thức accept () trả về, nó sẽ trả về một SocketChannel có kết nối đến. Do đó, phương thức accept () chặn cho đến khi có kết nối đến. Nếu kênh ở chế độ không chặn thì phương thức accept sẽ ngay lập tức trả về giá trị rỗng nếu không có kết nối nào đang chờ xử lý. Nếu không, nó sẽ chặn vô thời hạn cho đến khi có kết nối mới hoặc xảy ra lỗi I / O.
Ổ cắm của kênh mới ban đầu không bị ràng buộc; nó phải được liên kết với một địa chỉ cụ thể thông qua một trong các phương thức liên kết của socket của nó trước khi các kết nối có thể được chấp nhận. Ngoài ra, kênh mới được tạo bằng cách gọi phương thức openServerSocketChannel của đối tượng SelectorProvider mặc định trên toàn hệ thống.
Giống như kênh socket máy chủ, kênh socket có thể đọc dữ liệu bằng cách sử dụng read()Đầu tiên bộ đệm được cấp phát. Dữ liệu đọc từ ServerSocketChannel được lưu trữ vào bộ đệm, thứ hai chúng ta gọi phương thức ServerSocketChannel.read () và nó đọc dữ liệu từ ServerSocketChannel vào bộ đệm. Giá trị số nguyên của phương thức read () trả về số byte đã được ghi vào bộ đệm
Tương tự, dữ liệu có thể được ghi vào kênh ổ cắm máy chủ bằng cách sử dụng write() Phương thức sử dụng bộ đệm làm tham số Thường sử dụng phương thức ghi trong vòng lặp while khi cần lặp lại phương thức write () cho đến khi Bộ đệm không còn byte nào để ghi.
Các phương pháp quan trọng của kênh Socket
bind(SocketAddress local) - Phương thức này được sử dụng để liên kết kênh ổ cắm với địa chỉ cục bộ được cung cấp làm tham số cho phương thức này.
accept() - Phương thức này được sử dụng để chấp nhận kết nối được thực hiện với ổ cắm của kênh này.
connect(SocketAddress remote) - Phương pháp này được sử dụng để kết nối ổ cắm với địa chỉ từ xa.
finishConnect() - Phương pháp này được sử dụng để kết thúc quá trình kết nối kênh ổ cắm.
getRemoteAddress() - Phương thức này trả về địa chỉ của vị trí từ xa mà ổ cắm của kênh được kết nối.
isConnected() - Như đã đề cập, phương pháp này trả về trạng thái kết nối của kênh socket, tức là nó đã được kết nối hay chưa.
open() - Phương thức mở được sử dụng để mở một kênh ổ cắm không có địa chỉ cụ thể. Phương thức tiện lợi này hoạt động như thể bằng cách gọi phương thức open (), gọi phương thức kết nối trên kênh ổ cắm máy chủ kết quả, chuyển nó từ xa, rồi trả về kênh đó.
read(ByteBuffer dst) - Phương pháp này được sử dụng để đọc dữ liệu từ bộ đệm đã cho thông qua kênh socket.
setOption(SocketOption<T> name, T value) - Phương thức này đặt giá trị của một tùy chọn socket.
socket() - Phương pháp này truy xuất một ổ cắm máy chủ được liên kết với kênh này.
validOps() - Phương thức này trả về một tập hợp hoạt động xác định các hoạt động được hỗ trợ của kênh này. Các kênh ổ cắm máy chủ chỉ hỗ trợ việc chấp nhận các kết nối mới, vì vậy phương thức này trả về SelectionKey.OP_ACCEPT.
Thí dụ
Ví dụ sau đây cho thấy cách gửi dữ liệu từ Java NIO ServerSocketChannel.
C: /Test/temp.txt
Hello World!
Máy khách: 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();
}
}
Đầu ra
Chạy máy khách sẽ không in bất cứ thứ gì cho đến khi máy chủ khởi động.
Máy chủ: 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();
}
}
Đầu ra
Chạy máy chủ sẽ in như sau.
Connection Set: /127.0.0.1:49558
File Received