Java 의 Socket 옵션 - xrath.com 에서 번역됨

## Java 의 Socket 옵션

### C 방법

C 로 프로그래밍 하는 경우는, 다음과 같은 방법으로 시스템 콜을 사용해 옵션을 설정합니다.

    	setsockopt(int fd, int level, int optval, void *optdata,
    		   int optdatalen);

    	fd = 벌써 열린 (아마 접속된) 소켓 fd;
    	level = 옵션이 적용되는 프로토콜 스택 (IP, UDP, TCP)
    	        의 레벨
    	optval = 옵션, CONSTANT
    	optdata = 옵션에 의존하는 파라미터의 구조체에의 포인터
    	         (특정의 옵션의 경우만)

### Java 방법

옵션을 설정할 때의 C 방법은, 객체 지향 프로그래밍의 형태의 안전성을 빠뜨리고 있습니다. 설정 및 취득하고 싶은 옵션은 int 로 지정해, 설정 및 취득하는 값은, 형태가 확실치 않은 void* 입니다. 잘못한 옵션 식별자를 지정하거나void* 파라미터에 잘못한 형태의 객체를 지정하거나 그 파라미터에 잘못한 것을 지정하거나 하는 것이, 간단하게 일어날 수 있습니다. 한층 더 나쁜 것에, 그러한 에러가 있는 코드도 일반적으로은 컴파일 되어 버려, 에러는 실행시가 되고 처음으로 표면화합니다.

Java 에서는 현재, 옵션을 설정하기 위한 , 형태의 안전성이 있을 방법이 제공되고 있습니다. 각 소켓 클래스는, 그 클래스가 지원하는 각 옵션용의 취득 및 설정 메소드를 가져, 적절한 형태의 데이터를 받거나 돌려주거나 합니다. 지원되고 있는 옵션, 적용되는 소켓 클래스, 및 그 의미를, 이후에 간단하게 설명합니다.

- TCP_NODELAY
  - Nagle 알고리즘을 무효로 한다
  - (클라이언트) Socket 에 대해서 유효
- SO_LINGER
  - linger-on-close 타임 아웃을 지정한다
  - (클라이언트) Socket 에 대해서 유효
- SO_TIMEOUT
  - 소켓 조작을 블록 하는 타임 아웃을 지정한다(영구히 블록 하지 않는 것)
  - 모든 소켓, 즉 Socket, ServerSocket, 및 DatagramSocket 에 대해서 유효
- SO_BINDADDR
  - 소켓의 로컬 주소 바인딩을 페치 한다
  - Socket, ServerSocket, 및 DatagramSocket 에 대해서 유효
- SO_REUSEADDR
  - 소켓의 주소의 재사용을 유효하게 한다
  - Socket, ServerSocket, 및 DatagramSocket 에 대해서 유효
- SO_BROADCAST
  - 브로드캐스트 메세지를 송신하는 소켓을 유효하게 한다
  - DatagramSocket 에 대해서 유효
- SO_SNDBUF
  - 송출 네트워크 입출력에 대해서, 기초가 되는 버퍼의 사이즈를 설정한다
  - 모든 소켓, 즉 Socket, ServerSocket, 및 DatagramSocket 에 대해서 유효
- SO_RCVBUF
  - 이 소켓으로 데이터를 수신할 때에 플랫폼에서 실제로 사용된 버퍼의 사이즈를 취득한다
  - 모든 소켓, 즉 Socket, ServerSocket, 및 DatagramSocket 에 대해서 유효
- SO_KEEPALIVE
  - 소켓의 킵얼라이브를 온으로 한다
  - Socket 에 대해서 유효
- SO_OOBINLINE
  - TCP 긴급 데이터의 인 라인 접수를 유효하게 한다
  - Socket 에 대해서 유효
- IP_MULTICAST_IF
  - 멀티 캐스트 패킷에 대해서, 송출 인터페이스를 지정한다 (multi-homed host상에서)
  - MulticastSocket 에 대해서 유효
- IP_MULTICAST_LOOP
  - 멀티 캐스트 데이터 그램의 로컬 루프백을 유효 또는 무효로 한다
  - MulticastSocket 에 대해서 유효
- IP_TOS
  - TCP 또는 UDP 소켓의 IP 헤더내의 서비스 타입 필드 또는 트래픽 클래스 필드를 설정한다
  - Socket, DatagramSocket 에 대해서 유효

### 추가

Java 에서는 지원되지않은, 사용 가능한 BSD 옵션은 다음과 같습니다.

- RAW/ICMP SOCKETS:
  이 옵션을 사용하는 이유로서 Java 로 ping 를 기술할 수 있다고 하는 점이 있지만, 거기에 따라 시큐리티상의 문제가 발생할 가능성이 있다. UNIX 컴퓨터상의 root 가 아니면 안된다

### 구현의 상세

SocketImpl/DatagramSocketImpl 를 서브 클래스화할 때 이외는, 이 정보는 필요 없습니다. 모든 *Socket 객체는, native code에의 인터페이스가 되는, 기초가 되는 SocketImpl/DatagramSocketImpl 를 가지고 있습니다. Impl 클래스는, 옵션을 지원하기 위한 2 개의 메소드를 구현하고 있습니다.

    	void setOption(int optID, Object val) throws SocketException;
    	Object getOption(int optID) throws SocketException;

이것은 C 에 자주(잘) 닮았습니다. 이러한 메소드는, 네이티브 메소드에 대해서 접착제와 같은 기능을 해, 네이티브 메소드를 기동하기 전에 형태의 안전성을 보증합니다.