레이블이 Socket인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Socket인 게시물을 표시합니다. 모든 게시물 표시

2013년 10월 3일 목요일

자바7 NIO.2 - 내용정리 8장 (소켓 API)

chapter 8. 소켓 API
Java7의 NIO.2에서 추가된 Socket 관련 기능
  • NetworkChannel 인터페이스 도입
  • ServerSocketChannel , SocketChannel, DatagramChannel 도입
  • SocketOption<T> 인터페이스와 StandardSocketOption을 사용하여 Socket 옵션 설정 및 가져오기
  • MulticastChannel 인터페이스 도입

8.1 NetworkChannel 소개

주요 공통 메서드 : bind() , getLocalAddress() ,
주요 메소드
  • bind() : 채널의 소켓을 로컬 주소에 바인딩한다. 정확하게 소켓과 로컬 주소 사이에 연관 관계를 설정 한다. null을 전달하면 로컬 주소를 자동으로 할당한다.NetworkChannel bind(SocketAddress local) throws IOException
  • getLocalAddress() : 바인딩된 주소를 추출함. 바인딩 되지 않으면 null을 반환 한다.NetworkChannel getLocalAddress() throws IOException

8.1.1 소켓 옵션
소켓과 연관된 옵션은 SocketOption<T> 인터페이스로 표현됨.
StandardSocketOption 클래스에 표준 옵션
  • IP_MULTICAST_IF : UDP 멀티캐스트 다이어그램에서 사용되는 NIC를 지정하기 위해서 사용한다. null 값을 지정하면 OS가 자동으로 선택.
  • IP_MULTICAST_LOOP : 멀티캐스트 다이어그램의 루프백을 제어하는 하는 boolean 값(기본값 true)
  • IP_MULTICAST_TTL : UDP 소켓에서 전송된 멀티캐스트 TTL(time-to-live)값 (범위 0 ~ 255, 기본값 1)
    1으로 설정되면 외부 네트워크로 전달되는 것을 방지 한다.
  • IP_TOS : IP 패킷 안에 정의되는 ToS(Type of Service) 옥텟 값을 나타낸다. IPv4 전용, (기본값 0)
  • SO_BROADCAST : 브로드캐스트 데이터그램의 전송 여부를 결정하는 boolean 값(기본값 false)
  • SO_KEEPALIVE : 연결 유지 여부를 결정하는 boolean 값 (기본값 false)
  • SO_LINGER : 타임아웃 값을 설정(기본값 음수, 즉 비활성화), 블로킹 모드에서 close() 사용해서 중단할 때 전송할 Data가 남아 있으면 주어진 linger interval 만큼 대기 한다.
  • SO_RCVBUF : 소켓 수신 버퍼의 크기 (단위 byte) , 기본값을 OS가 지정함. 음수 불가
  • SO_SNDBUF : 소켓 송신 버퍼의 크기 (단위 byte) , 기본값을 OS가 지정함. 음수 불가
  • SO_REUSEADDR : 주소 재 사용 여부를 나타내는 정수 값. UDP 멀티캐스팅에서 유용, TCP의 경우 TIME_WAIT 상태일 때 주소를 바인딩할 수 있다. 기본값은 OS 마다 틀림.
  • TCP_NODELAY : Nagle 알고리즘의 사용 여부를 정하는 정수(기본값을 false)
관련메소드-옵션 가져오기/변경하기
<T> T getOption(SocketOption<T> name) throws IOException
<T> NetworkChannel setOption(SocketOption<T> name,T value) throws IOException
특정 채널에서 지원하는 옵션을 가져오는 메소드
Set<SocketOptions<?>> supportedOptions()

8.2 TCP 서버/클라이언트 애플리케이션 작성하기

8.2.1 블로킹과 논블로킹 메커니즘의 비교
블로킹 혹은 논블로킹 선택 해야 함.
-> 개발자 입장에서 이 두가지 개념을 반드시 이해(복잡도) , 일반적은 논블로킹 성능과 확장성이 블로킹 보다 좋다.
** 그러나 복잡도는 증가한다.

8.2.2 블로킹 TCP 서버 작성하기
블로킹 메커니즘 설정하기 : ServerSocketChannel.configureBlocking(true)
서버 채널 옵션 설정 (아래 두가지를 지원한다.)
serverSocketChannel.setOption(StandardSocketOptions.SO_RCVBUF, 4 * 1024);
serverSocketChannel.setOption(StandardSocketOptions.SO_REUSEADDR, true);

- IP 주소를 와이들카드(*) 주소를 사용할때 NIC가 여러 개 인 경우 발생할수 충돌을 피해야 하므로 일반적으로 지정된 NIC 주소를 사용하는 것이 좋다.
- 바인딩되지 않은 서버 소켓 채널에 대해 accept() 메소드를 호출하면 NotYetBoundException예외가 발생한다.
- SocketChannel.getRemoteAddress() 이용해서 원격지 주소를 알수 있음(Java7, NIO.2에 추가됨)

I/O를 위한 연결 종료하기
NIO.2의 새 메서드 SocketChannel.shutdownInput(),SocketChannel.shutdownOutput()을 호출해서 채널을 닫지 않아도 I/O를 위한 연결을 종료할 수 있다.

8.2.3 블로킹 TCP 클라이언트 작성하기
소켓 채널 옵션 설정하기
지원하는 옵션들
  • SO_RCVBUF
  • SO_LINGER
  • IP_TOS
  • SO_OOBINLINE
  • SO_REUSEADDR
  • TCP_NODELAY
  • SO_KEEPALIVE
  • SO_SNDBUF

8.2.4 블로킹 에코 애플리케이션 테스트 하기
8.2.5 논블로킹 TCP 클라이언트/서버 애플리케이션 작성하기
논블로킹 I/O - 채널을 사용하는 프로세스를 블로킹하지 않고 작업함.
java.nio.channels.Selector의 특징
  • 엔티티일때 복잡해짐.(즉 java.nio.channels.Selector 클래스 사용할 때)
  • Selector는 open() 메소드로 생성한다.
  • Selector는 데이터 전송을 위해 하나 이상의 채널을 이용할 수 있고 각각의 기록된 소켓 채널을 모니터링 함.
  • 다중 소켓의 IO 읽기/쓰기 작업을 하나의 쓰레드에서 처리할 수있다.(멀티프렉싱 개념 덕분)
  • java.nio.channels.SelectableChannels를 위한 멀티플렉서
  • ServerSocketChannel와 SocketChannel의 register()를 통해 등록할 수 있음.
  • 셀렉터에 의해 채널에 할당된 리소스를 해제해서 등록을 해지 할 수 있음.

SelectionKey 클래스 : 채널이 Selector로 등록할 때 마다 생성되는 구분 클래스, 클라이언트와 요청 유형(연결,읽기,쓰기)을 식별하는 정보가 들어 있다.

동작 정보 유형
  • SelectionKey.OP_ACCEPT(수락기능) : 클라이언트가 연결 요청(보통 서버측에서 생성)
  • SelectionKey.OP_CONNECT(연결기능) : 서버가 연결을 수락(보통 클라이언트 측에서 생성)
  • SelectionKey.OP_READ(읽기기능) : 읽기 동작
  • SelectionKey.OP_WRITE(쓰기기능) : 쓰기 동작

Selector 관리하는 세가지 키 집합
  • key-set : 등록된 키 집합
  • selected-key : 선택된 키 집합. 하나 이상의 연산을 탐지할 준비가 된 각 키 집합.
  • cancelled-key : 취소된 키 집합, 키를 취소했지만 아직 등록이 해지되지 않는 키 집합.
** 논블로킹 모드에서 I/O 연산은 요청한 것보다 적은 바이트(분활 읽기/쓰기)를 전송하거나 바이트를 전혀 전송하지 않을수 있다.
셀렉터 기반의 논블로킹의 흐름도

Selector 메소드
  • open() : 새 셀렉터를 생성한다.
  • select() : 블로킹 선택 작업을 수행해서 키의 집합을 선택한다.
  • select(t) : select()와 동일 지저된 시간동안만 블로킹 한다.
  • selectNow() : select()와 동일 논블로킹 선택 작업을 수행
  • selectedKeys() : 셀렉터가 선택한 키 집합을 Set<SelectionKey>로 반환한다.
  • keys() : 셀렉터의 키 집합을 반환한댜.
  • wakeup() : 아직 반환되지 않는 첫 번째 선택 작업이 즉시 반환하게 한다.
SelectionKey 메소드
  • isValid() : 키가 유효한지 확인 한다. 키가 취소되거나 키의 채널이 닫혔거나 키의 셀렉터가 닫혔다면 키는 유효하지 않다.
  • isReadable(): 키의 채널을 읽을 수 있는지 검사
  • isWritable() : 키의 채널을 쓸수 있는지 검사
  • isAcceptable() : 키의 채널이 새 소켓 연결을 수락할 수 있는지 검사
  • isConnectable() : 채널의 소켓 연결 작업을 종료하기 위해 키의 채널이 끝났거나 실패했는지 검사
  • cancel() : 셀렉터의 등록 취소를 요청
  • interestOps() : 키의 interest set를 가져 온다.
  • interestOps(t) : 키의 interest set을 주어진 값으로 설정한다.
  • readyOps() : 키의 준비된 작업 집합을 가져온다.
그외 메소드
register() : ServerSocketChannel 혹은 SocketChannel 있는 메소드, 주어진 셀렉터를 현재 채널에 등록하고 셀렉션 키를 반환하는 용도로 쓰임.
public final SelectionKey register(Selector s,int p,Object a) throws ClosedChannelException

8.3 UDP 서버/클라이언트 애플리케이션 작성하기

UDP의 두 가지 중요한 특징
  • IP 패킷 하나에 담을 수 있는 양에 따라 패킷 크기가 제한 된다는 점.(최대 크기 65507 byte - 원래는 65535 여기서 IP 헤더 크기 20 byte 와 UDP 헤더 8 byte 뺀값)
  • 데이터의 특정 순서로 전송하는 것을 보장하지 않는다, 전송된 데이터가 도착한다는 보장도 하지 않는다.
    각 패킷은 IP 주소와 포트를 캡슐화 한다.(TCP 전화, UDP 편지)
8.3.1 UDP 서버 작성하기
java.nio.channels.DatagramChannel - 주요 관련 클래스
java.net.StandardProtocolFamily ( 프로토콜 패밀리 매개변수 , DatagramChannel.open() 매개변수)
  • StandardProtocolFamily.INET : IP 버전 4(IPv4)
  • StandardProtocolFamily.INET6 : IP 버전 6(IPv6)
DatagramChannel이 지원하는 소켓 옵션들
  • SO_REUSEADDR
  • SO_BROADCAST
  • IP_MULTICAST_LOOP
  • SO_SNDBUF
  • IP_MULTICAST_TTL
  • IP_MULTICAST_IF
  • SO_RCVBUF

DatagramChannel 주요 메소드
  • open() : 소켓 생성
  • isOpen() : 소켓 채널이 성공적으로 열렸는지
  • supportedOptions() : 지원하는 소켓 옵션 알아내기
  • bind() : 로컬 주소에 바인딩하고 소켓이 연결 요청에 대기하도록 함.
  • send() : 메시지 전송
  • receive() 메시지 받기
  • getRemoteAddress() : 원격지 주소 얻기
  • close() : 채널 닫기

8.3.2 비연결지향 UDP 클라이언트 작성하기
서버 작성와 비슷하다. send(),receive() 사용

8.3.4 연결지향 UDP 클라이언트 작성하기
read()와 write()를 사용함. 고정된 원격지 주소와 통신을 한다. 즉 만약 다른 쪽과 통신을 하고 싶다면 연결을 해지 않고 재 연결해야 한다.

  • DatagramChannel.connect() : 명시적으로 호출해야 함. - 연결할 주소지 정보를 전달해야 함.
  • DatagramChannel.isConnected() : 연결 상태를 확인 할 수 있다.

8.3.6 멀티캐스팅
테이터그램 수신자로 표현되는 그룹이라는 표기법을 사용함. 그룹은 클래스D IP 주소로 식별한다.
** 클래스D 영역(IPv4 기준 : 224.0.0.1 ~ 239.255.255.255 사이) 새 수신자(클라이언트)가 멀티캐스트 그룹에 가입하려면 그에 상응하는 IP 주소를 통해 그룹에 연결해야 하며, 들어오는 데이터그램을 리스닝해야 한다.
java.nio.channels.MulticastChannel
  • NIO.2에서 추가됨
  • IP 멀티 캐스팅을 지원하는 네트워크 채널을 매핑하는 새로운 인터페이스를 제공
  • NetworkChannel의 서브인터페이스 이고 DatagramChannel 클래스에서만 구현되어 있음.
  • 주요 메소드
    • join() : MemberShipKey를 리턴값으로 받고 아래 두 가지 형태 메소드가 있다.
      • join(InetAddress g, NetworkInterface i) : 정보를 받기 위해서 멀티캐스트 그룹에 가입하는 것
      • joni(InetAddress g, NetworkInterface i, InetAddress s) : 그룹에 가입한다. s - 메시지를 받을 수 있는 출발지 주소를 알려준다.  
    • close() : membership을 버리고 채널을 닫는데 사용된다.
  • ** 멀티캐스트 채널은 여러 그룹 가입 가능, 여러 인터페이스에 동일한 그룹 가입 가능
java.nio.channels.MemberShipKey
  • IP 멀티캐스 그룹의 회원 구분자(토근)
  • 자주 하는 동작
    • 차단/차단 해제 : block()/unblock() , 특정 주소 메시지 차단/해지
    • 그룹 가져오기 : group() ,리턴 유형은 InetAddress
    • 채널 가져오기 : channel(), 리턴 유형은 MulticastChannel
    • 출발지 주소 가져오기 : 출발지 주소가 정해져 있다면 , sourceAddress(), 리턴 유형은 InetAddress
    • 네트워크 인터페이스 가져오기 : networkInterface() , 리턴 유형은 NetworkInterface
    • 유효성 검사 : isValid()
    • 버리기 : drop()
NetworkInterface 소개
NIC에 할당된 IP 주소의 목록과 이름으로 구성된 정보를 표현 (즉 네트워크 카드 정보를 알아낼 수 있다)