Tcp의 내용 설명
codedatasotrage.tistory.com/18
TCP 상태 전이도
서버측과 클라이언트 측 관점으로 나눈 TCP 상태 전이도이다. TCP의 신뢰성 보장을 위한 기능중 하나이다. 소켓의 종료는 누가 먼저 종료 요청을 보내느냐의 따라 달라지며 먼저 자신이 닫았을 경우 ACK 패킷을 송신함을 끝으로 TIME_OUT 상태에서 대기하다 소켓이 종료된다. 이 종료 시간은 커널에서 설정이 가능하다.
소켓 동작 원리
연결 과정
1. SYN 패킷 전송 단계
TCP 헤더의 SYN 비트를 1로 설정하여 패킷을 송신한다. 처음 SYN 패킷은 ISN(Init Seq Num)를 SYN 필드에 기록하여 전송한다. 보안상의 이유로 ISN을 임의의 숫자를 사용하나 0도 자주 사용한다.
2. SYN, ACK 패킷 전송 단계
SYN 비트와 ACK 비트를 1로 설정하여 클라이언트에게 전송한다. 이것 역시 ISN을 SYN 필드에 넣는다.
3. ACK 패킷 전송
클라이언트는 2단계의 SYN_ACK 패킷을 받은 후 ACK 비트를 1로 설정한다. 그후 ACK 패킷을 보낸다.
위 과정은 3-Way HandShaking 과정이다. TCP는 신뢰성있는 연결 확립을 위해 위 과정을 거친다. 다음은 이 과정 속에서 TCP 상태를 나타내는 설명이다. 서버는 LISTEN 상태에 놓여 있고 클라이언트 측이 SYN 패킷을 보내면서 SYN_SENT 상태가 된다. 서버측은 SYN을 받게 되면 SYN_RCVD 상태가 되고 SYN_ACK 패킷을 보낸다. 클라이언트는 SYN_ACK을 받고 ACK을 보낸뒤 ESTABLISHED 상태가 되고 서버도 ACK 패킷을 받으면 ESTABLISHED 상태가 된다. 이때 응용 프로그램은 accept 함수를 반환한다.
자료의 송수신
자료의 송수신은 송수신측 모두 ESTABLISHED 상태일 때 가능하다. TCP에서 최대 Segment 크기를 지정할 수 있어 (MSS) 이를 이용하여 자료의 크기를 지정할 수 있다.
자료 송수신 도중 SYN필드를 통해 데이터를 얼마나 보냈는지 알 수 있다. 패킷간에 SYN의 수 차이로 알 수 있다.
자료를 전송 할 때 응용 프로그램의 버퍼가 커널의 TCP 소켓 버퍼로 복사된다. 복사되는 동안은 응용프로그램은 커널에 의해 차단되며 송수신 과정을 거친다. TCP의 송신 버퍼 크기는 SO_SNDBUF로 지정할 수 있다.
연결 종료
연결 종료는 어느 쪽에서 먼저 진행하는가에 따라 다르다. 4-Way HandShake라고도 한다. 한쪽만 먼저 닫히기 때문에 반쪽종료라고도 한다. 예시는 클라이언트 측이 먼저 Close를 한 경우로 예시를 들었다.
1. FIN 패킷 전송
TCP 제어비트의 FIN 비트를 1로 설정하고 서버로 전송한다.
2. ACK 패킷 전송
서버는 FIN 패킷을 받고 ACK 패킷을 클라이언트로 전송한다.
3. FIN 패킷 전송
서버는 소켓 닫을 준비를 마무리하고 연결 종료를 위해 FIN 비트를 1로 설정하고 클라이언트에 FIN 패킷을 전송한뒤 송신 소켓을 닫는다.
4. ACK 패킷 전송
클라이언트는 서버의 FIN 패킷을 수신 받고 ACK 패킷을 서버로 전송한다.
위 과정의 내부 동작을 보면 클라이언트는 close를 진행한뒤 커널은 FIN패킷을 서버로 전송한다. 전송한 뒤 클라이언트는 FIN_WAIT_1 상태가 된다. 서버는 FIN 패킷을 받고 ACK 패킷을 보낸 뒤 CLOSE_WAIT 상태가 된다. 클라이언트는 ACK을 수신하고 FIN_WAIT_2 상태가 된다. 여기서 서버는 송신을 닫은 상태고 클라이언트가 ACK을 보내면서 서버는 소켓을 종료하여 CLOSED상태가 된다. 클라이언트는 ACK 패킷을 보낸뒤 TIME_OUT 상태가 되며 일정 시간뒤 소켓을 종료하여 CLOSED상태가 된다 TIME_OUT의 경우 커널로 설정이 가능하다.
'Programming > Socket' 카테고리의 다른 글
[C Socket Programing] servent 구조체(servent structure) (2) | 2021.06.07 |
---|---|
Socket을 닫은 뒤 바로 쓸 수 없는 이유 (0) | 2021.05.04 |
[C/C++/소켓프로그래밍] Socket이란? (0) | 2021.03.13 |
[C/C++/소켓프로그래밍] Hostent란? (0) | 2021.03.12 |
[C/C++/소켓 프로그래밍] IP 주소 형식 변환 aton() ntoa() 이진형식으로의 변환 (0) | 2021.03.10 |
댓글