Java NIO-소켓 채널

Java NIO 소켓 채널은 소켓을 연결하는 스트림 지향 데이터 흐름에 사용되는 선택기를 사용하여 다중화 할 수 있음을 의미하는 선택 가능한 유형 채널입니다. 소켓 채널은 정적을 호출하여 생성 할 수 있습니다. open() 기존 소켓이 존재하지 않는 경우 소켓 채널은 open 메서드를 호출하여 생성되지만 아직 연결되지 않은 소켓 채널을 연결하려면 connect() 여기서 언급해야 할 점은 채널이 연결되지 않은 상태에서 I / O 동작을 시도한 경우이 채널에서 NotYetConnectedException이 발생하므로 IO를 수행하기 전에 채널이 연결되어 있는지 확인해야합니다. 채널이 연결되면 닫힐 때까지 연결된 상태로 유지됩니다. 소켓 채널의 상태는 해당 채널을 호출하여 확인할 수 있습니다. isConnected 방법.

소켓 채널의 연결은 finishConnect() 연결 작업이 진행 중인지 여부는 isConnectionPending 메서드를 호출하여 확인할 수 있습니다. 기본적으로 소켓 채널은 비 차단 연결을 지원합니다. 또한 Channel 클래스에 지정된 비동기 닫기 작업과 유사한 비동기 종료를 지원합니다.

소켓 채널은 여러 동시 스레드에서 사용하기에 안전합니다. 동시 읽기 및 쓰기를 지원하지만 최대 하나의 스레드가 읽고있을 수 있고 최대 하나의 스레드가 주어진 시간에 쓸 수 있습니다. connect 및 finishConnect 메소드는 서로에 대해 상호 동기화되며 이러한 메소드 중 하나의 호출이 진행중인 동안 읽기 또는 쓰기 작업을 시작하려는 시도는 해당 호출이 완료 될 때까지 차단됩니다.

소켓 채널의 중요한 방법

  • bind(SocketAddress local) −이 메서드는이 메서드에 매개 변수로 제공되는 로컬 주소에 소켓 채널을 바인딩하는 데 사용됩니다.

  • connect(SocketAddress remote) −이 방법은 소켓을 원격 주소에 연결하는 데 사용됩니다.

  • finishConnect() −이 방법은 소켓 채널 연결 과정을 완료하는 데 사용됩니다.

  • getRemoteAddress() −이 메서드는 채널의 소켓이 연결된 원격 위치의 주소를 반환합니다.

  • isConnected() − 이미 언급했듯이이 메서드는 소켓 채널의 연결 상태, 즉 연결 여부를 반환합니다.

  • open() and open((SocketAddress remote) − Open 메서드는 지정된 주소가없는 소켓 채널을 열고, 지정된 원격 주소에 대해 매개 변수화 된 open 메서드 오픈 채널을 사용하여 연결합니다.이 편리한 메서드는 open () 메서드를 호출하여 결과에 대해 connect 메서드를 호출하는 것처럼 작동합니다. 소켓 채널을 원격으로 전달한 다음 해당 채널을 반환합니다.

  • read(ByteBuffer dst) −이 방법은 소켓 채널을 통해 주어진 버퍼에서 데이터를 읽는 데 사용됩니다.

  • isConnectionPending() −이 방법은이 채널에서 연결 작업이 진행 중인지 여부를 알려줍니다.

다음 예제는 Java NIO SocketChannel에서 데이터를 보내는 방법을 보여줍니다.

C : /Test/temp.txt

Hello World!

클라이언트 : 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();
   }
}

산출

클라이언트를 실행하면 서버가 시작될 때까지 아무것도 인쇄되지 않습니다.

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

산출

서버를 실행하면 다음이 인쇄됩니다.

Connection Set:  /127.0.0.1:49558
File Received