728x90
반응형

서버는 socket 함수를 호출해서 소켓을 생성하고, bind 함수로 포트에 연결한 후 listen함수로 클라이언트로부터 연결 요청을 받는다.

이때 소켓의 상태는 CLOSED에서 LISTEN이 된다. 클라이언트가 connect 함수를 호출하면 서버는 LISTEN 상태에서 SYN_RCVD 상태가 된 다음 ESTABLISHED 상태가 된다. 자료의 전송은 서버와 클라이언트 모두 ESTABLISHED 상태일 때 가능하다.

연결의 종료는 누가 먼저 종료를 시작하는가에 따라 상태가 달라지는데, 서버의 경우 클라이언트에서 먼저 종료를 시작하면 CLOSE_WAIT, LAST_ACK 상태를 거쳐 CLOSED 상태가 된다. 반대로 서버에서 먼저 종료를 시작하면 FIN_WAIT_1, FIN_WAIT_2, TIME_OUT 상태를 거쳐 CLOSED 상태가 된다.

클라이언트는 우선 socket 함수를 호출해서 소켓을 생성하고, connect 함수를 호출해서 서버와 연결하는데, SYN_SENT 상태를 거쳐 ESTABLISHED 상태가 된다. 그러면 자료의 송수신이 가능하게 된다.

 

연결준비단계

TCP는 연결형 서비스이다. 따라서 TCP로 통신하려는 두개의 호스트는 별도의 제어정보를 주고받음으로써 호스트간의 연결을 이루어낸다.

클라이언트의 응용프로그램에서 서버와 연결하기 위해 connect 함수를 호출하면 특정 제어비트를 1로 설정한 TCP 패킷을 서로 교환함으로써 이루어지는데 패킷 3개를 서로 교환하기 때문에 3-way handshaking이라고 부른다.

 

* 1단계(SYN 패킷 전송)

우선 클라이언트는 제어비트(control bit)중 SYN 비트를 1로 설정한 TCP 제어 패킷(SYN 패킷)을 서버로 전송해 연결을 시도한다.

TCP는 송수신되는 자료의 바이트 순서를 관리하는데, SYN 패킷에 기록된 일련번호와 확인번호 필드의 값으로 순서를 추척한다.

처음 SYN 패킷에는 클라이언트가 사용할 일련번호의 시작값을 일련번호 필드에 기록해서 전송한다.

즉, SYN 패킷의 일련번호 필드에는 연결후 자료를 송수신할 때 사용할 ISN이 있다.

 

* 2단계(SYN_ACK 패킷 전송)

서버는 제어비트중 SYN비트와 ACK비트를 1로 설정한 SYN_ACK 패킷을 클라이언트로 전송함으로써 클라이언트에게 SYN 패킷을 잘 받았음을 알린다. 역시 서버가 사용할 ISN을 SYN_ACK 패킷의 일련번호 필드에 기록해서 전송한다.

 

* 3단계(ACK 패킷전송)

클라이언트는 2단계의 SYN_ACK 패킷을 서버로부터 받은후 두 호스트간에 연결이 되었다는 것을 확인하고, 제어비트의 ACK 비트를 1로 설정한 TCP 제어패킷을 서버로 보낸다.

 

자료 송수신 단계

원격지로 자료를 전송할 때 응용 프로그램의 버퍼의 내용은 커널의 TCP 송신버퍼로 복사된다.

응용프로그램의 버퍼의 내용 모두가 커널의 TCP 송신버퍼에 복사될 때가지 응용프로그램은 차단된다.

TCP 송신버퍼의 크기는 옵션 SO_SNDBUF으로 지정한다.

응용프로그램의 버퍼의 크기가 크거나 송신버퍼에 비어있지 않아서 모두 복사하지 못하면 응용프로그램이 차단된다.

 

TCP 소켓옵션

#include <sys/types.h>

#include <sys/socket.h>

int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen);

 

s: 옵션을 읽거나 수정하려는 소켓 기술자

level: 옵션을 해석하는 커널 내 시스템 코드의 구분

optname: 소켓의 옵션을 수정할 옵션 이름

optval: 수정할 옵션의 값

optlen: 인자 optval의 메모리 크기

 

SO_KEEPALIVE 옵션

SO_KEEPALIVE 옵션은 TCP 소켓에 적용된다. 이 옵션을 1로 설정하면 일정시간(통상 2시간)동안 해당 소켓을 통해 어떤 자료도 송수신되지 않을때, 커널에서 상대방의 상태를 확인하는 패킷을 전송한다.

소켓이름 처리구분 적용 프로토콜
SO_KEEPALIVE SOL_SOCKET TCP

 

ACK 패킷으로 정상이라고 응답하는 경우 응용프로그램에는 어떠한 통보도 하지 않고 커널간의 확인만으로 상대방이 살아있음을 확인하고 마무리 한다. 상대방으로부터 아무런 응답이 없거나 RST 응답을 받으면 소켓을 자동으로 종료한다.

기본적으로 SO_KEEPALIVE 옵션은 서버측 소켓에 설정되어 상대방 시스템의 고장이나 정전, 네트워크 연결이 끊기는 등 통신이 불가능한 상황을 탐지해준다. 상대방 시스템이 고장난 경우 ETIMEOUT 오류를, 상대방 시스템까지 네트워크 연결이 불가능한 경우 EHOSTUNREACH 오류를 반환한다. 응용프로그램에서는 해당 오류에 따라 처리하면 된다. 시스템이나 네트워크 문제가 아닌 응용프로그램 문제라면 으용프로그램이 종료될 때 상대방 커널에서 FIN 패킷을 보내 연결 종료를 시작하기 때문에 응용 프로그램에서는 EOF에 대한 처리를 하면 된다.

728x90
반응형

+ Recent posts