소켓에는 다양한 특성들이 있다.
소켓 옵션 확인 (레발 안에 옵션이 있다!)
int getsockopt(int sock,int level,int optname, void* optval, socklen_t* optlen);
소켓 옵션 변경
int setsockopt(int sock,int level,int optname, const void* optval, socklen_t optlen);
SO_TYPE
SO_RCVBUF & SO_SNDBUF
SO_REUSEADDR
TCP_MAXSEG
TCP_NODELAY
소켓이 생성되면 기본적으로 입력, 출력 버퍼가 생성된다.
이 둘을 이용해 버퍼의 크기를 참조, 변경이 가능
단 버퍼의 크기를 조정할때 원하는 크기대로 설정이 되지 않을 수도 있다.
이는 커널이 오버헤드를 막기위해 setsockopt를 할때 버퍼의 크기를 값의 두배로 설정하기 때문이다.
시그널로 서버를 종료하고 다시 그 포트번호로 서버를 실행시키면 bind error가 발생한다. 그리고 3분후 다시 그 포트 번호로 서버를 실행하면 정상 동작한다.
Time wait 때문이다.
reliable 통신이 종료될때는 4-way handshaking을 거친다.
여기서 소켓은 바로 소멸되지 않고 Time-wait 상태를 일정시간 유지 후 소켓이 소멸이 된다.
(Time wait은 연결의 종료를 요청한(먼저 FIN메시지를 보낸) 호스트만 거침)
그래서 서버가 먼저 종료 요청을 보내면 해당 소켓이 Time-wait 후 소멸되기 때문에 해당 PORT 번호가 사용중인 것으로 나타나 bind error가 발생한다!!
서버나 클라이언트 모두 Time wait은 존재
그러나 클라이언트 소켓의 포트번호는 임의로 할당되기때문에(accpet) 때문에 time-wait에 대해 신경 쓰지 않아도 된다
왜 존재하나??
하지만!! time wait가 있따면!! 호스트 A가 다시 B로 ACK를 재전송을 하여 호스트 B는 정상 종료 할 수 있다.
그렇다면 갑작스럽게 서버가 종료가 되어서 Time-wait 때문에 포트 번호를 쓰지 못하는 상황에는 ?? 얼른 서비스를 구동해야하는데 몇 분을 기다린다면 매우 큰 문제가 될 수도 있다.
해결법
SO_REUSEADDR의 상태를 변경하면 된다!
적절한 변경을 통해 time wait 상태의 소켓에 할당되어 있는 port 번호를 새 소켓에 할당할 수 있다
앞서 전송한 데이터에 대한 ACK 메시지를 받아야만 다음 데이터를 전송하는 알고리즘
on
off
네트워크의 효율을 위해서는 NAGLE을 사용해야한다.
하지만 NAGLE이 항상 좋은것은 아님
NAGLE을 적용하지 않아도 트래픽 차이가 크지 않고 데이터의 전송이 빠른 경우도 있음
=> 용량이 큰 파일 데이터의 전송
필요하다면 NAGLE을 중지시켜야함
알고리즘은 적용하지 않아도 트래픽의 차이가 크지 않음 + NAGLE 적용보다 속도가 빠름
setsockopt(sock,IPROTO_TCP,TCP_NODELAY,(void*)&opt_val,sizeof(opt_val));