TCP, UDP 헤더 형식과 게임서버 특징
TCP 헤더 형식
•
총 32bit로 구성되어 있다.
•
Source Port, Destination Port
◦
각각 16bit로 구성
◦
16bit는 0~65535까지의 범위
▪
하지만, 0과 65535는 존재하지 않는 port이기 때문에 -2를 뺀 65533개의 port를 사용할 수 있는 것
•
Sequence number
◦
TCP 연결을 할 때 통신을 하는 번호이다.
◦
데이터를 보낼 때(데이터도 bytes 단위로 존재) 데이터의 크기만큼 Sequence number에 더해지는 것이다.
◦
즉, 데이터의 길이가 100bytes라고 한다면 Sequence number + 100 이 된다.
•
Acknowledgement number
◦
받은 Sequence number + data + 1 의 크기로 보낸다.
•
Data Offset
◦
TCP Payload 위치를 계산할 때 사용한다.
Payload란? (복습)
•
Flag 값
◦
TCP의 상태를 결정
◦
FIN - 연결 종료를 의미하는 Finish
◦
ACK - 응답을 의미하는 Acknowledgement
◦
SYN - 연결 시작을 의미하는 Synchronize
◦
RST - 무언가 꼬였을 때 다시 시작하는 Reset
◦
PSH - TCP 통신할 때 buffering 없이 즉시 보내자는 뜻의 Push
◦
나머지는 혼잡 제어 부분이다.
▪
혼잡 제어란?
•
Loss, Re-Transmission + Duplicated - Acknowledgement, Out of order, zero window와 같은 네트워크에 장애가 발생하였을 때, 회선이 너무 복잡하니 천천히 가야하던지 해야한다. 이를 통제하기 위한 제어를 의미한다.
•
Window Size
◦
TCP 수준에서 Buffer의 여유 공간.
◦
여유 공간이 0이 되었을 때의 문제. 네트워크 속도가 처리 속도보다 빠를 때 발생할 수 있다.
◦
이는 네트워크 문제보다는 프로그램 수준에서 문제를 해결해야 한다.
•
CheckSum
◦
손상된 데이터는 없는지 계산할 때 사용한다.
UDP 헤더 형식
•
Source Port, Destination Port 번호, 길이, CheckSum 값만 존재.
•
UDP는 TCP처럼 혼잡 제어 등을 전혀 수행하지 않으며, 수신하는 측의 데이터 수신 여부, 버퍼의 상태 등을 전혀 고려하지 않은 채 데이터를 일방적으로 보낸다.
•
클라이언트를 배려하지 않는 프로토콜.
•
그렇기 때문에 TCP 헤더 형식에 비해 단순하다.
•
그렇다면 UDP는 언제 사용할까?
◦
IPTV를 사용하여 영상을 보는 경우를 생각해보자.
▪
IPTV에는 영상을 송출해주는 서버가 있을 것이고, 서버에 연결되어 있는 수 많은 사용자가 있을텐데, 각 사용자마다의 네트워크 속도는 모두 다를 것이다.
▪
그렇다면 이 중 느린 사용자의 네트워크 속도에 맞춰서 영상을 송출한다면 빠른 네트워크를 가진 사용자는 상대적으로 손해를 볼 수 밖에 없다.
▪
따라서 모두를 고려하지 않은 채 일단 데이터를 송신하는 것이다. 이럴 때 UDP를 사용한다.
◦
또 하나의 예로는 게임 서버가 있다.
▪
온라인 게임 서버같은 경우에는 모두가 같은 화면을 보아야하기 때문에 동기화 문제가 중요하다.
▪
이 때, TCP를 사용한다면 거의 대부분 하향 평준화를 해버린다. 이용자 중 한 사람의 네트워크가 느리다면 그 이용자에 맞춰 모두 느리게 구성할 수 밖에 없게 된다. 병목현상의 제약 조건과 유사하게 생각하면 된다.
•
이러한 동기문제로 인해서 UDP를 기반으로 하여 TCP의 혼잡 제어 로직을 직접 구현(커스터마이징)하여 개발하게 된다.
•
HTTP3에서도 UDP가 활용이 됨.
TCP '연결'이라는 착각
Q : TCP/IP로 1~2GB 정도 크기의 파일을 다운로드 받는 중 LAN 케이블을 분리했다가 다시 연결하면 TCP 연결은 어떻게 될까?
•
결론은 LAN 케이블을 얼마나 오랫동안 뽑고 있느냐에 따라서 달라지기는 하지만 TCP 일정 시간동안 연결은 유지된다.
•
파일을 다운로드 받는다는 것 == TCP가 연결되었다는 의미 == L4 계층 수준의 연결을 의미
•
LAN 케이블을 뽑았다는 것 == L1의 하드웨어 수준의 행위.
•
보통 소켓 수준의 프로그래밍에서는 3 way handshaking이 정상적으로 완료되어 연결이 되었음에도 불구하고 이러한 현상때문에 지속적으로 연결상태를 재확인한다.
◦
이를 Hearbeat라고 한다.
•
예시
◦
만약 새벽에 친구와 통화를 하고 있다고 하자. 내가 계속 말을 하고 있는데, 상대방은 어떠한 대답도 하지 않는다. 이럴 때 나는 친구가 자고 있는지 재확인하기 위해서 말을 건다. "야 자냐?"
◦
이 상황을 생각해보자. 나와 친구와의 통화 연결 자체는 유지되고 있다. 그러나 친구와의 대화(소통)이 원활하게 이루어 진 것은 아니다.
•
위의 예시가 바로 TCP 연결이라는 착각.
◦
L1 수준의 단락(케이블 분리)이 있어도, L4의 논리적 연결은 일정 시간동안 지속된다.
▪
위의 LAN 케이블을 분리하는 행위 = 네트워크 연결 내에서는 충격.
▪
이 충격에 대비하기 위해서 Buffer에 어느정도의 데이터를 미리 담아놓아서 충격에 방지하는 것이다.
◦
이는 유선에서는 LAN 케이블을 뽑는 행위 외에는 잘 일어나지 않지만 무선에서는 아주 흔하게 발생하는 현상이다.
▪
예를 들어 지하철의 경우 내 이동에 따라 중계기가 바뀌게 되는데 중계기가 바뀐다고 하여 바로 모든 인터넷 연결이 끊어지지 않는다. Buffer가 중간에서 충격을 완화해주는 역할을 해주고 있기 때문이다.
•
재전송 타이머의 기본 근사값은 대략 3초이지만 대부분의 운영체제들은 1초 미만이다.
◦
해당 시간은 SRTT 타임, 두 호스트 간의 거리를 측정
•
재전송 타이머 만료 후에도 확인 응답을 받지 못한 경우, Segment를 재전송하고 RTO(Retransmission Time-Out) 값은 두 배로 증가한다.
◦
예를 들어 1초 > 2초 > 4초 > 8초 > 16초 간격으로 재전송한다.
•
보통 최대 5회 재전송을 시도하고 5회 이상 모두 실패할 경우 전송 오류가 발생한다.
TCP 연결과 게임 버그
•
어떤 MMORPG 게임에서 아이템 복제 버그가 발생
•
이는 논리적 TCP 연결과 물리적 링크 간 차이를 이용한 시간차 공격이라 볼 수 있으며 연결은 사실은 End-point의 주관적 판단에 불과하다는 것을 보여줌
•
또 다른 예시 (연결은 착각이다 + TCP는 보안성이 없다)
앞선 예시에서 친구와 통화를 하는 상황을 가정했다.
그런데 상대방이 정말 내 친구라는 것은 어떻게 확신할 수 있을까?
사실 목소리와 말투 정도일 것이다.
만약 내 친구와 목소리와 말투를 똑같이 따라할 수 있는 누군가가 대신 전화를 받는다고 하면 나는 그 사람을 친구로 착각할 확률이 높다.
•
3-way handshake : Client 입장에서는 SYN ~ SYN + ACK 과정을 통해 ESTABLISHED 된 것은 사실 연결이 되었다고 믿는 것과 다름 없다.
연결은 착각이기 때문에 연결을 너무 신뢰해서는 안된다.