8. Client Socket
인터넷을 통해 전달되는 데이터는 데이터그램(datagram)이라 불리는 일정 크기의 패킷으로 전송됨.
(인터넷(Internet)에서는 IP 데이타그램을 패킷이라고 말함)
데이터 그램은 header, payload를 포함함.
수신 & 송신한 곳의 주소와 포트, 데이터 손상을 체크하기 위한 체크섬 등 전송을 위해 필요한 정보들이
포함되어 있다.
하지만 데이터그램은 길이제한으로 패킷을 분할하여 목적지에서 재조립하는 특징이 있음. 또한 패킷 손실 및
재전송시 패킷이 보낸 순서와 다르게 도착하여 재정렬이 필요한 경우도 있음.
소켓이 네트워크 연결을 바이트 단위로 읽고 쓰는 다른 스트림처럼 다룰 수 있도록 함. 소켓은 에러탐지,
패킷의 크기, 패킷 분할, 패킷 재전송, 네트워크 주소 등과 같은 네트워크 내부의 자세한 내용을
감싸 프로그래머가 신경 쓰지 않도록 해줌.
Socket 사용하기
소켓이란 두 호스트 사이의 연결을 말함
1. 원격 장비에 연결(connect)
2. 데이터 보내기(send)
3. 데이터 받기(recv)
4. 연결 닫기(close)
5. 포트 지정하기(bind)
6. 수신 대기하기(listen)
7. 지정된 포트에 대해 원격 장비의 연결 받아들이기(accept)
socket으로 서버에서 읽기 (
InputStream
)// socket time-out 설정 : 소켓에 대한 읽고 쓰기가 느린 경우에도 지정된 밀리초 이상을 // 소요하지 않을 것임을 나타냄. socket.setSoTimeout(15000)
socket으로 서버에 쓰기(
OutputStream
)
소켓 생성과 연결
java.net.Socket 클래스는 클라이언트 측 TCP기능을 수행하기 위한 자바의 기본 클래스.
java.net.Socket 클래스 자체는 호스트 운영체제의 로컬 TCP 스택과 통신을 위해 네이티브 코드를 사용함
*네이티브 코드 : 프로그래머가 직접 메모리를 할당 및 해제해야 하는 native한 환경을 갖는 코드
기본 생성자
각각의 소켓 생성자는 연결할 호스트와 포트를 인자로 전달받음.
public Socket(String host, int port) public Socket(InetAddress address, int port)
연결에 사용할 로컬 인터페이스 지정하기
public Socket(String host, int port, InetAddress localAddr, int localPort) throws IOException public Socket(InetAddress address, int port, InetAddress localAddr, int localPort) throws IOException
연결되지 않은 소켓 생성하기
아무런 인자 없이 호출하면, 생성자는 연결되지 않은 소켓을 반환함.
public Socket() { setImpl(); } Socket socket = new Socket(); SocketAddress address = new InetSocketAddress("time.nist.gov", 13); socket.connect(address); // 연결된 소켓으로 작업함....
소켓 주소
SocketAddress 클래스는 연결 끝점(endpoint)를 나타냄. SocketAddress 클래스는 적어도 TCP와 비TCP 소켓 둘 모두에 사용될 수 있음. socket으로 부터 얻은 SocketAddress로 새로운 소켓에 같은 주소로 다시 연결할 수 있음.
Socket socket = new Socket("www.yahoo.com", 80); //소켓 연결 SocketAddress yahoo = socket.getRemoteSocketAddress(); //주소 설정 socket.close();
프록시 서버
Socket 클래스의 마지막 생성자는 인자로 전달된 프록시 서버를 통해 연결하는 연결되지 않은 소켓을 생성함
public Socket(Proxy proxy)
소켓 정보 얻기
set메서드는 존재하지 않음. 소켓은 연결과 동시에 설정되며 고정됨.
public InetAddress getInetAddress() public int getPort() public InetAddress getLocalAddress() public int getLocalPort()
종료된 소켓과 연결된 소켓
isClosed() 메서드 사용 : 닫혀 있으면 true, 그렇지 않으면 false
소켓 옵션 설정하기
TCP_NODELAY
true로 설정시 버퍼링 구조를 사용하지 않고 모든 패킷이 준비되는 즉시 전송됨.
→ true : 가능한 한 빨리 패킷을 전송함
SO_LINGER
소켓이 닫힐 때, 전송되지 않은 데이터그램을 어떻게 처리할지 결정함
SO_TIMEOUT
설정시 read() 메서드 호출이 지정된 밀리초 이상 블록되지 않음. 즉 설정한 밀리초만큼만 블록됨.
타임아웃이 발생하면
InterruptedIOException
타임아웃은 밀리초로 생성
기본값은 0, 무한대기를 의미
SO_RCVBUF 그리고 SO_SNDBUF
TCP는 네트워크 성능을 향상시키기 위해 버퍼를 사용함.
속도가 빠르면 큰 버퍼, 속도가 느리면 작은 버퍼가 유리함.
SO_RCVBUF 옵션은 수신 버퍼의 크기를 제어
성능향상 : 많은 데이터를 처리
네트워크 지연 감소 : 수신 버퍼 크기를 늘리면 소켓이 데이터를 기다리는 시간이 줄어들어 네트워크 지연이 감소함. 고대역폭 네트워크에 유리
버퍼 크기를 적절히 설정 : 오버플로우 방지, 대량의 데이터 도착시 유리
SO_KEEPALIVE
유후 연결을 통해 데이터 패킷을 보내어 서버와의 연결을 유지함.
OOBINLINE
TCP는 단일 바이트를 긴급하게 전송하는 기능을 제공함
SO_REUSEADDR
소켓이 종료될 때, 로컬 포트를 즉시 해제하지 않는 경우가 있음. 소켓을 종료하려는데 전송 패킷이 남아있을 경우를 대비해 즉시 해제되지 않는 경우가 대부분, 이 때 같은 포트에 바운드되는 새 프로세스에게 늦게 도착하는 패킷이 전달되지 않도록 시스템은 설계되어있음.
SO_REUSEADDR (default false) 이 켜져있으면 이전 소켓으로 전송된 데이터가 남아있는 경우에도 다른 소켓이 해당 포트를 바인드(bind)할 수 있음. 즉, 이전 주소와 소켓을 재사용 하려면 SO_REUSEADDR 옵션을 true로 설정해야함.
Last updated