TCP-IP 소켓 프로그래밍

TCP의 내부 동작 원리를 이해해보자

코딩봇치 2023. 8. 28. 17:28

들어가며


이번 글에선 TCP에서 어떤 식으로 통신을 하길래 그렇게 신뢰 있게 통신되는지, 내부의 동작 원리를 공부해 본다.

 

TCP의 동작원리


입/출력 버퍼

알다시피 TCP엔 데이터의 바운더리가 없다. Host1이 Host2에게 40바이트를 송신했는데 Host2가 10바이트씩 받는다면, 남은 30바이트는 어디에 있는 것일까? 네트워크상에 떠돌고 있는 걸까?

바로 입력버퍼로 들어가게 된다. TCP소켓엔 각각 입력, 출력 버퍼가 존재한다. send를 하면 출력버퍼에 있다가, 상대방의 입력버퍼에 들어가게 된다. 또한 recv를 할 시 자신의 입력 버퍼에 있는 데이터를 받아오게 된다.

 

Q. 그럼 소켓을 닫았을 때 입/출력 버퍼에 남아있는 데이터는 어떻게 되나요?
A. 출력버퍼에 있는 데이터는 계속해서 전송되지만, 입력버퍼에 남아있는 데이터는 소멸합니다!

그럼 입력버퍼에 남은 크기보다 큰 데이터를 전송하면 어떻게 될까???

답은 "입력버퍼를 초과하는 데이터는 전송은 발생하지 않는다"이다. TCP에선 데이터의 흐름을 관리한다. 

입력버퍼의 크기 또한 슬라이딩 윈도우(Sliding Window)라는 프로토콜을 통해 입력버퍼 크기에 대한 송/수신을 관리한다.

이프로토콜을 이용해 수행하는 역할을 대화로 표현하면 다음과 같다.

소켓 A: 나한테 50바이트까진 보내도된다!
소켓 B: ㅇㅋㅇㅋ

소켓 A: 나 20바이트 처리해서 70바이트까지 가능~
소켓 B: ㅇㅋㅇㅋ

TCP의 상대 소켓과의 연결

TCP소켓은 연결할 때 상대 소켓과 3마디의 대화를 나눈다.

[Shake 1] 소켓 A: 안녕 소켓 B야, 나 데이터 전달할게 있어서.. 우리 연결 좀 하자.
[Shake 2] 소켓 B: 오케이, 나도 준비 됐으니까 언제든 연결해!
[Shake 3] 소켓 A: 땡큐, 요청 들어줘서 고마워~

이 3마디의 대화를 Three-way handshaking이라고한다. 즉, 세 번 악수 했다는 뜻이다. 

그럼 Three-way handshaking의 형태를 대화가 아닌 실제 과정으로 살펴보자.

 

  첫 번째 패킷

첫 번째 패킷은SYN(Synchronization)이다. 데이터 송수신에 앞서 전송되는 '동기화 메세지'를 의미한다. 이 메세지는

SEQ: 1000, ACK는 비어있다. 여기서 SEQ는 이것을 의미한다.

Host A: "내가 지금 보내고 있는 패킷은 id: 1000이야, 잘 받으면 다음 패킷은 1001번으로 전달해달라고 말해줘!"

두 번째 패킷

이 패킷은 SEQ: 2000, ACK: 1001로 응답메세지(ACK)와 동기화 메세지(SEQ)를 함께 보내고 있어 SYN+ACK 라고한다.

SEQ는 첫 번째에서 설명했던 것과 같은 의미를 가지고 있고, ACK의 경우 이것을 의미한다.

Host B: "좀 전에 전송하 SEQ 1000 패킷은 무사히 받았다! 다음엔 1001인 패킷을 전송해줘!

세 번째 패킷

세 번째 패킷은 SEQ: 1001에  ACK: 2001이 추가된 형태를 지녀, ACK라고 한다. 이것들이 의미하는 것은 앞에서 알아봤듯이 SEQ 2001를 무사히 받았고, 이번 id는1001이라는 뜻이다.

 

이 세 과정을 거치며 두 소켓은 모두 연결해 서로 송수신을 위한 준비가 되었다는 것을 인식할 수 있었다.

 

TCP의 상대 소켓과 송/수신

 

첫 번째 전송

Host A가 100byte의 data를 SEQ와 함께 Host B에게 전송했다. 그러자 Host B가 ACK로 1301를 전송했다.

왜 1201이 아닌 1301이 ACK로 돌아왔을까?

ACK는 다음 공식으로 결정된다. 

SEQ 번호 + 전송된 바이트 크기 + 1

이 공식을 통해 Host B가 100바이트를 모두 잘 받았는 지, 중간에 손실됐는 지 여부를 알 수 있다!

두 번째 전송

두 번째 전송에선 Host B가 데이터를 수신하는데 실패했다! 하지만 TCP 소켓은 전송과 동시에 타이머를 동작시켜서 타이머가 끝나기 전 응답이 오지 않으면, 패킷을 재전송한다.

TCP 소켓의 상대 소켓과 연결종료

TCP 소켓은 연결종료도 매우 안전하게 진행한다. 연결과 다르게 연결종료는 4마디의 대화를 나눈다.

소켓 A: 연결 끊고 싶어.
소켓 B: 아? 나 아직 준비가 안됐어. 좀만 기다려줘!

소켓 B: 준비 끝났어! 이제 연결 끊자.
소켓 A: 오케이 수고했어!

이걸 실제 과정으로 살펴보면 이런 느낌이 나온다.

 

연결종료는 FIN메세지를 한 번씩 주고받으며 연결이 끝나는데, 이 과정이 4단계에 걸쳐 진행되어 Four-way handshaking이라고 부른다!(FIN은 종료를 알리는 메세지를 뜻한다.)

SEQ와 ACK는 연결과 같은 뜻을 가지는 것을 알면 이해하기 쉬울 것이다!

 

마무리

 


TCP의 흐름제어(FLow Control)에 대해 알아보았다. 우리가 그냥 함수 하나도 처리하던 걸 컴퓨터는 굉장히 많은 동작으로 진행하고 있다는 것을 알게 되었다.

참고