Java NIO 학습 8 (Selector 보충 판 SocketChannel)
public abstract class SocketChannel extends AbstractSelectableChannel implements ByteChannel, ScatteringByteChannel, GatheringByteChannel {
// This is a partial API listing
public static SocketChannel open() throws IOException;
public static SocketChannel open(InetSocketAddress remote) throws IOException;
public abstract Socket socket();
public abstract boolean connect(SocketAddress remote) throws IOException;
public abstract boolean isConnectionPending();
public abstract boolean finishConnect() throws IOException;
public abstract boolean isConnected();
public final int validOps();
}
Socket 과 SocketChannel 류 패 키 징 점 대 점, 질서 있 는 네트워크 연결 은 우리 가 잘 알 고 좋아 하 는 TCP / IP 네트워크 연결 과 유사 합 니 다.SocketChannel 은 클 라 이언 트 가 같은 감청 서버 에 연결 하 는 역할 을 합 니 다.연결 이 성공 할 때 까지 데 이 터 를 받 을 수 있 고 연 결 된 주소 에서 만 받 을 수 있 습 니 다.
모든 SocketChannel 대상 이 생 성 될 때 같은 대등한 java. net. Socket 대상 이 연 결 됩 니 다.정적 open () 방법 은 새로운 SocketChannel 대상 을 만 들 수 있 으 며, 새로 만 든 SocketChannel 에서 socket () 방법 을 호출 하면 대등한 Socket 대상 을 되 돌 릴 수 있 습 니 다.이 Socket 에서 getChannel () 방법 을 호출 하면 최초의 Socket Channel 로 돌아 갈 수 있 습 니 다.
새로 만 든 SocketChannel 은 열 렸 지만 연결 되 지 않 았 습 니 다.연결 되 지 않 은 SocketChannel 대상 에서 I / O 작업 을 시도 하면 NotYet Connected Exception 이 이상 합 니 다.
우 리 는 채널 에서 connect () 방법 을 직접 호출 하거나 채널 과 연 결 된 Socket 대상 에서 connect () 를 호출 하여 이 socket 채널 을 연결 할 수 있 습 니 다.
socket 채널 이 연결 되면 닫 힐 때 까지 연결 상 태 를 유지 합 니 다.
불 모양 의 isConnected () 방법 을 호출 하여 SocketChannel 이 현재 연결 되 어 있 는 지 확인 할 수 있 습 니 다.
InetSocketAddress open( ) 。 :
SocketChannel socketChannel = SocketChannel.open (new InetSocketAddress ("somehost", somePort));
:
SocketChannel socketChannel = SocketChannel.open( );
socketChannel.connect (new InetSocketAddress ("somehost", somePort));
1. 전통 적 인 방식 으로 연결 하 는 것 을 선택 하면 대등한 Socket 대상 에서 connect () 방법 을 호출 하면 전통 적 인 연결 의 미 는 여기에 적 용 됩 니 다.스 레 드 는 연결 이 잘 되 거나 시간 이 지나 기 전에 차단 을 유지 합 니 다.
2 채널 에서 connect () 방법 을 직접 호출 하여 연결 을 만 들 고 채널 이 차단 모드 (기본 모드) 에 있다 면 연결 과정 은 사실상 같 습 니 다.SocketChannel 에 서 는 시간 초과 (timeout) 값 을 지정 할 수 있 는 connect () 방법 이 없습니다. connect () 방법 이 비 차단 모드 에서 호출 될 때 SocketChannel 은 동시 연결 을 제공 합 니 다. 요청 주소 에 대한 연결 을 시작 하고 즉시 값 을 되 돌려 줍 니 다.
반환 값 이 true 라면 연결 이 즉시 만 들 어 졌 음 을 설명 합 니 다 (이것 은 로 컬 링 연결 일 수 있 습 니 다).
연결 이 즉시 만들어 지지 않 으 면 connect () 방법 은 false 로 돌아 가 고 연결 구축 과정 을 병행 합 니 다.
스 트림 을 위 한 socket 연결 상 태 를 만 드 는 데 는 시간 이 필요 합 니 다. 연결 시스템 간 에 스 트림 socket 을 유지 하 는 데 필요 한 상태 정 보 를 만 들 기 위해 서 는 패키지 대 화 를 해 야 하기 때 문 입 니 다.
열 린 인터넷 을 넘 어 원 격 시스템 에 연결 하 는 데 는 시간 이 많이 걸린다.만약 어떤 SocketChannel 에서 현재 병렬 로 연결 되 어 있다 면, isConnectPending () 방법 은 true 값 을 되 돌려 줍 니 다.finish Connect () 방법 을 사용 하여 연결 과정 을 완성 합 니 다. 이 방법 은 언제든지 안전하게 호출 할 수 있 습 니 다.차단 되 지 않 은 SocketChannel 대상 에서 finish Connect () 방법 을 호출 하면 다음 과 같은 상황 이 발생 할 수 있 습 니 다.
연결 () 방법 이 아직 호출 되 지 않 았 습 니 다.그러면 NoConnection PendingException 이상 이 발생 합 니 다.연결 생 성 과정 이 진행 중 이 며 완료 되 지 않 았 습 니 다.그러면 아무 일 도 일어나 지 않 습 니 다. finish Connect () 방법 은 false 값 을 즉시 되 돌려 줍 니 다.비 차단 모드 에서 connect () 방법 을 호출 한 후 SocketChannel 은 다시 차단 모드 로 전환 되 었 습 니 다.필요 하 다 면 연결 이 완 료 될 때 까지 호출 스 레 드 가 막 히 고 finish Connect () 방법 은 트 루 값 으로 돌아 갑 니 다.처음 connect () 를 호출 하거나 finishConnect () 를 마지막 으로 호출 한 후 연결 생 성 과정 이 완료 되 었 습 니 다.그러면 SocketChannel 대상 의 내부 상 태 는 연 결 된 상태 로 업 데 이 트 됩 니 다. finishConnect () 방법 은 true 값 을 되 돌려 주 고 SocketChannel 대상 은 데 이 터 를 전송 할 수 있 습 니 다.연결 이 완료 되 었 습 니 다.그러면 아무 일 도 일어나 지 않 습 니 다. finish Connect () 방법 은 true 값 을 되 돌려 줍 니 다.채널 이 중간 연결 대기 (connection - pending) 상태 에 있 을 때 finish Connect (), isConnectPending () 또는 isConnected () 방법 만 호출 할 수 있 습 니 다.
연결 생 성 과정 이 성공 하면 isConnected () 는 true 값 을 되 돌려 줍 니 다.
InetSocketAddress addr = new InetSocketAddress (host, port);
SocketChannel sc = SocketChannel.open( );
sc.configureBlocking (false);
sc.connect (addr);
while ( ! sc.finishConnect( )) {
doSomethingElse( );
}
doSomethingWithChannel (sc);
sc.close( );
비동기 연결 을 관리 하 는 데 사용 할 수 있 는 코드
public class SocketChannelApp {
public static void main(String[] args) throws Exception {
InetSocketAddress addr = new InetSocketAddress("127.0.0.1", 8989);
SocketChannel sc = SocketChannel.open();
sc.connect(addr);
sc.configureBlocking(false);
while (!sc.finishConnect()) {
doSomethings();
}
//Do something with the connected socket
ByteBuffer buffer = ByteBuffer.wrap(new String("Hello server!").getBytes());
sc.write(buffer);
sc.close();
}
private static void doSomethings() {
System.out.println("do something useless!");
}
}
server 는 여전히 전편 을 채택 하 였 으 며, 나 는 그것 을 간단하게 고 쳤 다.
public class ServerSocketChannelApp {
private static final String MSG = "hello, I must be going
";
public static void main(String[] args) throws Exception {
int port = 8989;
ServerSocketChannel ssc = ServerSocketChannel.open();
ServerSocket ss = ssc.socket();
ss.bind(new InetSocketAddress(port));
// set no blocking
ssc.configureBlocking(false);
ByteBuffer buffer = ByteBuffer.wrap(MSG.getBytes());
while (true) {
// System.out.println("wait for connection ……");
SocketChannel sc = ssc.accept();
if (sc == null) {
// no connections, snooze a while ...
Thread.sleep(1000);
} else {
System.out.println("Incoming connection from " + sc.socket().getRemoteSocketAddress());
ByteBuffer readerBuffer = ByteBuffer.allocate(1024);
sc.read(readerBuffer);
readerBuffer.flip();
//output get
out(readerBuffer);
buffer.rewind();
sc.write(buffer);
sc.close();
}
}
}
private static void out(ByteBuffer readerBuffer) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < readerBuffer.limit(); i++) {
char c = (char) readerBuffer.get();
sb.append(new String(new char[]{c}));
}
System.out.println(sb.toString());
}
}
ps:
비동기 연결 을 시도 하 는 데 실패 하면 다음 에 finish Connect () 방법 을 사용 하면 적당 한 검사 이상 이 발생 하여 문 제 를 지적 할 수 있 습 니 다.채널 이 닫 히 고 연결 되 거나 다시 사용 할 수 없습니다.연결 과 관련 된 방법 으로 우 리 는 하나의 채널 에 대해 문의 하고 연결 진행 과정 에서 채널 이 처 한 상 태 를 판단 할 수 있다.제4 장 에서 우 리 는 폴 더 를 피하 고 비동기 연결 이 만들어 진 후에 통 지 를 받 는 선택 기 를 어떻게 사용 하 는 지 알 게 될 것 이다.Socket 채널 은 라인 이 안전 합 니 다.동시 방문 시 방문 하 는 여러 스 레 드 를 보호 하기 위해 특별한 조 치 를 취하 지 않 아 도 됩 니 다. 그러나 언제든지 읽 기 동작 과 쓰기 동작 만 진행 되 고 있 습 니 다.sockets 는 가방 이 아 닌 흐름 을 향 한 것 임 을 기억 하 세 요.보 낸 바이트 가 순서대로 도착 할 것 이 라 고 보장 할 수 있 지만 바이트 그룹 을 유지 하 겠 다 고 약속 할 수 는 없다.어떤 송신기 가 socket 에 20 개의 바이트 만 썼 을 수도 있 고 수신 기 가 read () 방법 을 호출 했 을 때 3 개의 바이트 만 받 았 다.나머지 17 개의 바이트 가 전송 중 입 니 다.이 때문에 여러 개의 어 울 리 지 않 는 스 레 드 가 특정한 스 트림 socket 의 같은 쪽 을 공유 하 는 것 은 결코 좋 은 디자인 선택 이 아 닙 니 다.
connect () 와 finish Connect () 방법 은 서로 동기 화 되 며, 그 중 하나의 조작 이 진행 되 고 있 으 면 읽 거나 쓰 는 방법 호출 이 막 힐 수 있 습 니 다. 비 차단 모드 에서 도.만약 이 상황 에서 의문 이 있 거나 읽 기 또는 쓰기 동작 이 특정한 채널 에서 막 히 는 것 을 감당 할 수 없다 면, isConnected () 방법 으로 연결 상 태 를 테스트 하 십시오.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.