Java NIO - Kênh Socket

Kênh ổ cắm Java NIO là một kênh loại có thể lựa chọn có nghĩa là nó có thể được ghép kênh bằng cách sử dụng bộ 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. Kênh ổ cắm có thể được tạo bằng cách gọi tĩnh của nó. open() phương thức, cung cấp bất kỳ ổ cắm có sẵn nào chưa có sẵn. Kênh ổ cắm được tạo bằng cách gọi phương thức mở nhưng chưa được kết nối. Để kết nối kênh ổ cắm connect() Một điểm cần được đề cập ở đây là nếu kênh không được kết nối và bất kỳ hoạt động I / O nào được cố gắng thực hiện thì NotYetConnectedException 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 kết nối trước khi thực hiện bất kỳ IO nào Hoạt động. Khi kênh được kết nối, nó vẫn được kết nối cho đến khi nó bị đóng. Trạng thái của kênh ổ cắm có thể được xác định bằng cách gọi nó isConnected phương pháp.

Kết nối của kênh ổ cắm có thể được hoàn thành bằng cách gọi finishConnect() Có thể xác định hoạt động kết nối đang diễn ra hay không bằng cách gọi phương thức isConnectionPending. Bởi vì kênh socket mặc định hỗ trợ kết nối không chặn, đồng thời hỗ trợ tắt không đồng bộ, tương tự như hoạt động đóng không đồng bộ được chỉ định trong lớp Kênh.

Các kênh ổ cắm an toàn để sử dụng bởi nhiều luồng đồng thời. Chúng hỗ trợ đọc và ghi đồng thời, mặc dù nhiều nhất một luồng có thể đang đọc và nhiều nhất một luồng có thể đang viết bất kỳ lúc nào. Các phương thức connect và finishConnect được đồng bộ hóa lẫn nhau với nhau và nỗ lực bắt đầu thao tác đọc hoặc ghi khi đang thực hiện lệnh gọi một trong các phương thức này sẽ chặn cho đến khi lệnh gọi đó hoàn tất.

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.

  • 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() and open((SocketAddress remote) - Phương thức mở được sử dụng để mở một kênh ổ cắm cho không có địa chỉ xác định trong khi phương thức mở được tham số hóa mở kênh cho địa chỉ từ xa được chỉ định và cũng kết nối với nó. 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 dựa trên kết quả kênh ổ cắm, chuyển nó từ xa, và sau đó trả lại 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.

  • isConnectionPending() - Phương thức này cho biết hoạt động kết nối đang diễn ra trên kênh này hay không.

Thí dụ

Ví dụ sau đây cho thấy cách gửi dữ liệu từ Java NIO SocketChannel.

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