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