자바 nio Selector 사용 - 클 라 이언 트

한 편 을 연결 하면 클 라 이언 트 의 프로그램 은 간단 합 니 다. 연결 을 책임 지고 다운로드 파일 이름 을 보 내 고 데 이 터 를 읽 으 면 됩 니 다.주요 절 차 는 등록 -> 서버 연결 -> 다운로드 요청 보 내기 -> 데이터 읽 기 -> 연결 끊 기 입 니 다.
STEP 1: 등록, connect 이벤트 등록.
if(selector == null)
	selector = Selector.open();
SocketChannel channel = SocketChannel.open();
channel.configureBlocking(false);
channel.connect(new InetSocketAddress("localhost", 1234));
channel.register(selector, SelectionKey.OP_CONNECT);

 
상기 절 차 는 실제 적 으로 configure 와 connet 이 위 치 를 임의로 교환 할 수 없다 는 것 을 발견 했다. 즉, connect 를 configureBlocking 앞 에 놓 을 수 없고 open 에 InetSocketdress 인 자 를 직접 추가 할 수 없다.공식 doc 에서 open (InetAddress) 은 "이러한 편리 한 방법 은 다음 과 같은 과정 과 같다. open () 방법 을 호출 하고 받 은 소켓 채널 에서 connect 방법 을 호출 하여 reote 를 전달 한 다음 에 이 채널 로 돌아 가 는 것"이 라 고 설명 했다. 그러나 왜 connect 이후 에 block 을 설정 하지 못 해 데이터 다운로드 와 통신 을 할 수 없 게 되 었 는 지 모르겠다.
 
두 번 째 단계: connect 이벤트 처리
//    
if(key.isConnectable()) {
	SocketChannel socketChannel = (SocketChannel) key.channel();
	if(socketChannel.isConnectionPending())
		socketChannel.finishConnect();
	socketChannel.write(ByteBuffer.wrap(serverFileName.getBytes()));//       ,            
	socketChannel.register(selector, SelectionKey.OP_READ);
}

 
이 단계 에서 연결 이 완료 되면 서버 측 에 다운로드 한 파일 이름 의 데이터 정 보 를 보 내 고 read 이 벤트 를 등록 합 니 다.서버 쪽 에서 해당 파일 이름 을 받 은 후에 write 이 벤트 를 열 어 클 라 이언 트 에 게 데 이 터 를 보 냅 니 다. 클 라 이언 트 는 이때 데 이 터 를 읽 을 수 있 습 니 다.
 
STEP 3: read 이벤트 처리
if(key.isReadable()) {
	SocketChannel socketChannel = (SocketChannel) key.channel();
	byteBuffer.clear();
	if(!socketChannel.isConnected())
		return null;
//           channel
	if(fileChannel == null)
		fileChannel = new RandomAccessFile(localFileName, "rw").getChannel();
	int r = socketChannel.read(byteBuffer);
//        ,   channel,    socketChannel
	if(r <= 0) {
		if(fileChannel != null)
			fileChannel.close();
		channel.close();
		key.cancel();
		return null;
	}
	byteBuffer.flip();
//       
	fileChannel.write(byteBuffer);
}

 
읽 기 정 보 를 처리 하 는 것 입 니 다. 데이터 가 읽 혔 다 면 파일 을 저장 하 는 파일 흐름 을 다운로드 하고 프로그램 을 종료 하 는 것 입 니 다.
 
이렇게 해서 전체 클 라 이언 트 가 완성 되 었 습 니 다. 실행 할 때 저 는 10 개의 스 레 드 를 사용 하여 서버 에 같은 파일 을 읽 고 서로 다른 파일 백업 으로 저장 하여 아 날로 그 데이터 전송 기능 을 수행 합 니 다.다음 과 같다.
ExecutorService executorService = Executors.newSingleThreadExecutor();
for(int i = 0; i < 10; i++) {
	executorService.submit(new DownloadClient<Object>("d:/log4j.log", "d:/down" + i + ".log"));
}
executorService.shutdown();

 
전체 selector 는 연습 용 작은 예 일 뿐 실제 코드 에 사용 하려 면 서로 다른 이상 과 해당 하 는 논리 등 을 처리 해 야 합 니 다.공부 에 도 어느 정도 도움 이 된다.도움 이 됐 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기