개요

이 포스팅에 나오는 내용은 TCP/IP 소켓 프로그래밍에 나오는 TCP/UDP 관련 부분을 요약한 것이다.

TCP/IP 프로토콜 스택

이전의 포스팅에서 이야기했듯이, TCP/IP는 OSI 프로토콜과 싸워서 이긴, 현재 네트워크 세계에서 가장 범용적으로 사용되는 프로토콜 중 하나이다. 포스팅을 시작하기 전에 간단하게 프로토콜 스택을 확인해 보면

Application 계층
TCP/UDP
IP
Link

이렇게 표현할 수 있다. 즉, TCP/IP 프로토콜의 스택은 총 네 개의 계층을 나뉨을 알 수 있다. 만약 TCP를 사용하게 된다면

  • Application > TCP > IP > Link

이런 흐름으로 데이터를 전송하게 되고, UDP 를 사용하게 된다면

  • Application > UDP > IP > Link

이런 흐름으로 데이터가 전송되게 된다.

TCP

네트워크 레이어에서 IP 를 활용하여 목적지까지 데이터를 전달하는 과정을 결정한다면, 트렌스포트 레이어에서는 데이터를 어떻게 전송할지에 대한 규약을 정한다.

네트워크 세상은 결코 안전한 곳이 아니라서, 전송하는 도중에 패킷이 손실될 수도 있고 중간 라우터에서 데이터가 흘러 넘칠 수도 있다. 목적지까지 가는게 안전함을 누구도 보장할 수 없는 것이다.

그렇기 때문에 TCP 프로토콜 전송자/수신자끼리 규약을 만들어서, 맨 처음 데이터를 전송할때는 이렇게 하고, 요청을 종료할때는 이렇게 한다는 규약을 만들었다.

크게 나누면 다음 세 가지로 나눌 수 있다.

  • 상대 소켓과의 연결
  • 상대 소켓과의 데이터 송수신
  • 상대 소켓과의 연결 종료

상대 소켓과의 연결

맨 처음 요청을 보낼 때, TCP 프로토콜로 상대 소켓과 연결을 한다. 이를 Three-way handshaking 이라 한다. 먼저, 연결요청을 하는 호스트 A가 호스트 B에게 다음 메시지를 보낸다.

[SYN] SEQ : 1000, ACK: -

위 메시지의 의미는 다음과 같다 : 패킷 넘버 1000번 패킷을 보내고, 잘 받았다면 1001번 패킷을 보내줘

이는 처음 연결요청에 사용되는 메시지이기 때문에 이 메시지를 가르켜 SYN이라 한다. SYN은 Synchronization 의 줄임말로써, 데이터 송수신에 앞서 전송되는 동기화 메시지라는 의미를 담고 있다.

이어서 호스트 B는 A에게 다음과 같은 메시지를 전달한다

[SYN+ACK] SEQ : 2000, ACK : 1001

이는 다음과 같은 의미이다 : 지금 보내는 패킷에 2000을 부여하니, 잘 받았다면 2001을 보내라. 그리고 1000은 잘 받았으니 다음에는 1001을 보내라.

그러면 A는 다음과 같은 패킷을 보낸다.

[ACK] SEQ : 1001, ACK : 2001

이는 다음과 같은 의미이다 : 조금 전에 전송한 SEQ 가 2000인 패킷은 잘 받았으니, 다음 번에는 2001을 전송하렴

SEQ는 패킷에 붙이는 시퀀스로, 1씩 증가하여 보내게 된다. 이렇게 세 번의 통신이 마치면 Three-way handshake 가 완료된다.

상대 소켓과의 데이터 송수신

최초에 연결이 완료되었다면, 데이터를 송수신한다. 데이터를 송수신하는 규칙은 다음과 같다.

SEQ : 1200 100 byte data
ACK 1301
SEQ : 1301 100 byte data
ACK 1402

확인한 바와 같이, 데이터를 전송받으면 잘 받았다고 ACK를 보내게 되는데, 이 때는 SEQ + 전송받은 데이터 byte + 1 의 값을 보내게 된다.

만약에 요청이 전달되지 않는다면? 일정 시간 동안 자신이 보낸 요청에 ACK를 받지 못하면, 아까 날렸던 요청을 다시 날리게 된다.

연결 종료

연결 종료는 Four-way handshaking이라고 부르는데, SEQ와 ACK는 상대 소켓과 연결을 맺을 때와 흡사한데, 총 네 번 요청을 하게 된다.

A -> B	[FIN] SEQ 5000 ACK -
B -> A	[ACK] SEQ 7500 ACK 5001
B -> A	[FIN] SEQ 7501 ACK 5001
A -> B	[ACK] SEQ 5001 ACK 7502

요청의 의미는 Three-way handshaking과 동일하다.

UDP

UDP 방식 또한 트랜스포트 레이어에서 일어나는 데이터 전송 방식으로, TCP와의 차이점은 위의 흐름 제어 방식이 없다.

즉, TCP는 위의 흐름을 따라 데이터를 전달하기 때문에, 데이터가 손실되면(timeout)이 발생하면 다시 데이터를 전송한다. 그렇기 때문에 데이터가 유실될 가능성이 거의 없지만, UDP는 이런 요소가 없이 그냥 데이터를 전송하고 마무리한다. 수신측에서 ACK를 보내지도 않고, SEQ와 같이 패킷에 번호를 부여하는 일도 없다.

그러면 더 안 좋은 전송방식인가? 그렇지는 않다. 위의 과정이 없기 때문에 상황에 따라서 TCP보다 훨씬 좋은 성능을 발휘한다. 또한 생각만큼 데이터 손실이 많지 않기 때문에, 신뢰성보다 성능이 중요시되는 상황에서는 UDP가 좋은 선택이 될 수 있다.

내부 동작원리

UDP 서버, 클라이언트는 연결된 상태로 데이터를 송수신하지 않는다. 서버든 클라이언트든 한 개의 소캣만 가지고 있다. 하나의 소켓으로 데이터를 전송하고, 데이터를 받는다.

TCP는 데이터의 경계가 없이 한 번의 읽는 함수 출력으로 모든 데이터를 읽어올 수 있지만, UDP는 데이터의 경계가 있기 떄문에 세 번 write 함수를 출력하여 데이터를 전송했다면, 세 번 read 함수를 출력해야 한다.

TCP vs UDP

압축 파일 같은 경우에는 한 개만 틀어져도 압축이 풀리지 않기 때문에, TCP를 사용하여 전송하는 편이 안전하다. 그러나 멀티미디어 전송 같은 경우를 고려해 보자. 멀티미디어 전송 시에는 데이터가 조금 유실되어도 상관 없다. 손실 되어봐야 잡음이 약간 섞이는 정도일 것이다. 그리고 딜레이가 있으면 안 되는 부분이다.

이런 상황에는 UDP를 사용하는 것이 좋다.