시작
Protocol은 우리말로 하면 약속, 규약 이라는 의미이고, Network Protocol은 통신 규약입니다.
서로 간에 어떤 통신을 하기 위해서는 어떤 약속이 필요한데요.
프로토콜에는 여러가지가 있다. 여기서 전부 다 알아보진 않고, 게임에서 필요한 TCP, UDP만 다뤄보도록 하겠습니다.
여기에 베이스가 되는게 IP라는 프로토콜이 있어요. 이것이 하위 계층이고, TCP, UDP가 상위 계층입니다.
TCP, UDP위에 HTTP, SMTP, 등등이 있습니다.
여러 레이어들이 있는데 보내는 쪽에서 데이터를 만들어서 레이어들을 거칠 때마다 거기게 해당하는 데이터들이 하나씩 추가 되서 맨 마지막에 데이터가 인터넷을 통해 전송하게 됩니다.
받는 쪽에서도 여러 레이어들이 있어서 각 레이어들에 맞는 데이터들이 전송이 됩니다.
그래서 인터넷에서 패킷이 가는 것을 알아봅시다.
우선 ip가 있는데요. ip는 컴퓨터의 주소인데 이 ip를 가지고 10.10.25.3이 있다 가정하면 이 ip를 가지고 데이터가 전송이 됩니다.
데이터가 전송이 되면 데이터 집합소인 게이트웨이(GateWay)라는 곳이 있는데 이 게이트웨이(GateWay)가 10.10.0.0이라는 주소 일 때 10.10으로 시작되는 모든 패킷을 가져오게 됩니다.
그리고 나머지 25.3을 찾게 되는데 밑에 있는 게이트웨이 컴퓨터 중에 누가 25.3인지 찾아서 거기로 보냅니다.
그러면 ip는 필요가 없게 되고, 이 때부터는 ip패킷을 날려버리고 그 아래에 있는 TCP나 UDP를 사용하게 되고, 그 안에는 포트정보가 있습니다.
그래서 컴퓨터간에 통신을 할 때 ip와 port를 적어서 보내게 되는데요. port는 터미널 같은 것이라고 생각하면 쉽습니다.
이것을 어떻게 이해하면 좋냐면 만약에 물건을 찾는 곳이 여러 군데가 있다고 가정하고, 보내는 쪽과 받는 쪽에 약속을 하게 될 것입니다. "내가 3번 터미널에 보낼테니 3번 터미널에서 기다려"라고 하면 받는 쪽에서 3번 터미널에서 기다리겠지요.
이것을 Binding이라고 하는데 거기 묶여서 기다리고 있는 것입니다.
묶여서 기다리고있을 때 ip와 port가 10.10.25.3:3 이렇게 보낸다고 했을 때 문지기를 하고 있는 게이트웨이(GateWay)라는 곳에서 이 패킷이 우리에게 온 것이 맞는지를 체크해서 맞다면 그 컴퓨터를 찾아서 보내서 그 컴퓨터는 여러 터미널을 갖고 있는데 3번 터미널을 보냈으므로 3번 터미널에 물건을 놓고, Binding 되있던 수신 쪽에서 물건을 찾아가면 됩니다.
ip는 어떤 컴퓨터냐이고, port는 어떤 터미널이냐로 생각하면 됩니다.
앞에서 물건이라 말씀 드렸지만 컴퓨터에서 통신하는 것은 0101010101으로 이루어진 바이너리 데이터들입니다.
네트워크 카드에 버퍼(물건을 수용하는 공간)가 있는데 거기에 물건이 오면 차곡차곡 쌓이게 되고, 가져가는 수신자 쪽에서 그 때 그 때 빼가야 보내는 쪽에서 다시 보낼 수 있기 때문에 패킷을 보낼 때는 잘 보내주는 것도 중요하지만 잘 받아주는 것도 중요합니다.
그러면 게임쪽에서 많이 사용하는 TCP와 UDP에 대해 알아보도록 하겠습니다.
TCP를 쓰거나 UDP를 쓰거나 둘 중 하나로 선택하는 것인데, TCP에 대해 먼저 알아보자면
TCP는 하드웨어(기계)에서 기존에 알아봤던 3가지 문제들이 있으니까 몇가지를 보장해주자는 것입니다.
- 연결 유무를 확인.
- 패킷의 순서 보장.
- 송신 보장(패킷이 확실히 간다는 보장해주자.)
요 3가지를 해주도록 하자는 Protocol이 TCP입니다.
그러면 먼저 연결 유무를 확인 해준다는 부분부터 봅시다.
연결 되었다는 것은 무엇을 의미하는 것일까요? 가령 두 사람이 손을 잡았다 가정하면 그것은 물리적으로 연결되어 있는 것인데
컴퓨터에서 연결되어 있다는 것은 컴퓨터간에 다이렉트로 전선으로 연결되어 있으면 연결되어 있다고 할 수 겠지만 인터넷에서는 컴퓨터간에 연결되어있지 않습니다. 서로 거미줄 처럼 얽혀있는 네트워크에서 두 컴퓨터가 서로 연결되어 있다고 말할 수 가 없습니다.
그런데 연결되어 있다고 말하는 것은 추상적인 것인데 연결되어 있다고 생각하는 것입니다.
실제로 서울에서 미국까지 광케이블로 다이렉트로 깔아서 연결한다면 연결 되어 있다고 말할 수 있겠지만 실제로는 World Wide Web이라 거미줄처럼 얽혀있는 상황이라 두 컴퓨터가 연결 되어 있다고 말할 수는 없습니다.
그냥 이런 상태를 연결이라고 말하자고 추상적인 개념을 적용하는 것입니다.
그래서 TCP에서는 연결되어있다고 말할 수 있는 상태를 프로그래머가 TCP를 이용하는 프로그램이 알 수 있도록 해주자는 것인데
TCP에선 3Way handshake. 직역하면 3방향 악수인데요.
보통 연결을 맺는다 하면 보내는 쪽에서 connect Request를 보내고, 받는 쪽에서 OK를 보내면 보내는 쪽에서 그 다음 부터 연결을 할 수 있지만 수신쪽에서 생각해보면 OK를 보냈는데 이 OK를 보낸 패킷이 인터넷 상황에서 데이터는 언제든지 유실 될 수 있기 때문에 '잘 갈까?'라는 의문이 생길 수 있다.
다시 예를 들면 어떤 두 사람이 원거리 연애를 하고 있다 치면 한 사람은 한국, 한 사람은 미국에 있다 하면 한국에 있는 사람이 미국에 있는 사람에게 편지를 보낸다고 쳐봅시다.
보낸 쪽에서 그 편지가 잘 도착 했는지 알 수 있는 방법은 받은 쪽에서 답장을 해주면 잘 갔다는 걸 알 수 있습니다.
하지만 답장하는 입장에서 답장이 잘 갔는지 확인하려면 마찬가지로 답장을 받은 쪽에서 잘 받았다고 보내야 알 수 있을 것입니다.
그래서 이렇게 A가 B에게 Connect Request를 했을 때(1 way) B가 A에게 OK를 보내게 되고(2 way) B는 A가 OK를 잘 받았는지 못 받았는지 알 수 없기 때문에 A가 B에게 잘 받았다고 알려줘야한다. (3 way) 이렇게 해서 3Way handshake가 됩니다.
만약에 B가 A에게 OK를 보냈을 때 A가 B에게 잘 받았다고 다시 보내줘야 하는데 아무리 기다려도 안와서 또 B가 A에게 OK를 보냈는데도 안왔을 때 추상적으로 연결이 끊어졌다고 간주합니다.
또는 명시적으로 Disconnect통보를 하는경우 끊어졌다고 간주합니다.
TCP는 이런식으로 연결이 되고, 끊어지고를 프로그램에서 알 수 있게 알려줍니다.
그 다음 패킷의 순서를 보장해주는 부분을 봅시다!
네트워크 통신 자체가 원거리 연애라고 생각하면 된다. (보장되는 것이 아무것도 없기 때문에)
A라는 한국 사람이 미국에 있는 B에게 소포 4개를 각각 다른 배에 보냈다고 가정해봅시다.
그러면 받는 쪽에서 어떤 배는 빨리오고 어떤 배는 늦게와서 순서가 뒤 바뀌어서 어떤게 먼저 온 것인지 알 수가 없습니다.
그래서 이것을 해결하는 방법은 소포에 번호를 부여하는 것인데요.
그러면 받는 쪽에서 그 번호를 보고 순서대로 정렬을 할 수 있습니다.
컴퓨터로 얘기를 하자면 패킷 4개가 왔는데 받는 쪽에서 마지막 보낸 패킷이 2번이라고 가정하고, (데이터가 있으면 TCP/IP의 헤더가 앞에 붙습니다.) 그 다음 보내는게 4번이라고 보냈을 때 받는 쪽에선 2번이 오고 그 다음에 4번이 오게 되니까 3번이 안오는 것을 알게 되고, 받는 쪽에서 보내는 쪽에게 3번을 다시 보내라고 요청할 것입니다.
그 때 3번을 받을 수 있고, 또는 3번을 다시 보내라는 패킷이 유실되서 3번이 아니라 5번을 받게 되고, 5번을 받았을 때도 3번을 보내라고 요청을 했는데 이 패킷이 또 유실되서 6번을 받게되고,
이렇게 계속 7번이 오든 8번이 오든 기다리고 있다가 3번이 오는 순간 TCP를 이용하는 프로그램에 패킷이 다 왔다고 알려줍니다.
그래서 프로그램 입장에서는 순서를 뒤섞여서 받는 경우는 없습니다. 안받거나, 못받거나 연결이 끊어졌거나이지 순서가 뒤섞여서 받지 않기 때문에 순서를 보장해줍니다.
그 다음 TCP를 사용하면 송신 보장을 해주는데 2번 받고 3번이 유실되고, 4번을 받았을 때 3번을 다시 받을 때 까지 요청하고 기다리기 때문에 송신보장도 해줍니다.
TCP를 사용하면
- 연결 유무를 확인.
- 패킷의 순서 보장.
- 송신 보장(패킷이 확실히 간다는 보장해주자.)
인데
그에 반해 UDP는 그런게 없습니다.
- 연결 유무 X
- 순서보장 안됨.
- 송신보장 안됨.
TCP와 UDP가 있을 때 TCP 쓰면 되지 UDP를 왜 써? 할 수 있지만 TCP를 사용하면 보내고 받는데 3way로 왔다갔다 해야 3배 느립니다.
그런데 UDP는 보내놓고 '갔겠지.. 안 갔음 말고..' 이런 것이기 때문에 빠릅니다.
그리고 유실이라는 것이 실제 확률적으로 보면 7%인데 100개를 보내면 7개가 안가는 것이죠.
그래서 UDP입장에서 보면 '7개 정도야 안 갈 수도 있지...'라고 넘길 수 있게 됩니다.
그래서 이렇게 빠르기 때문에 게임쪽에서 쓰고 싶어합니다. (게임은 무조건 반응이 빨라야 하기 때문이죠.)
TCP는 지연시간이 UDP에 비해 깁니다. 그래서 지연시간 면에서 UDP가 빠르기 때문에 쓰고 싶어하는데 순서보장이 안되고, 연결보장이 안되고, 가다가 없어질 수 도 있습니다.
실 예로 LOL이라는 게임에서 스킬을 썼는데 사용 된 스킬의 데이터가 서버로 가야하는데 가다가 유실되면 그 때 사용된 스킬이 사용이 되지 않게 되는 것이 그 예이죠.
그래서 이런 문제들 때문에 UDP를 쓰고 싶지만 UDP를 쓰려니까 여러가지 문제가 생기는데요.
그래서 게임 개발자들이 이 것을 해결하기 위해 Relialde UDP를 코딩으로 만들어서 사용합니다.
Relialde UDP가 다른게 아니고 TCP가 하던 일을 소프트웨어로 처리 하는 것인데요.
TCP는 기계 자체(NIC 네트워크 카드 같은 것들)에서 그런 프로토콜을 제공하도록 내장되어 있고, Relialde UDP는 프로그래머들이 코딩을 통해 만들었습니다.
TCP에서 비효율적인 부분들을 제거를 해서 안정성을 낮추고, 성능을 올리고, 안정성이 필요한 쪽에서는 성능을 낮추는 식으로 해서 프로그래머들이 원하는 식으로 해서 만드는게 Relialde UDP입니다.
그런데 Relialde UDP는 만들기가 쉽지가 않습니다. 여러가지 변수가 존재하기 때문입니다.
그래서 대형 게임회사들(블리자드)이 자체적으로 만들어 썼습니다.
요즘에는 유니티나 언리얼에서 제공하고 있습니다. 옛날에 비해서는 누구나 쓸 수 있는 상황들이 열려있지만 막상 쓰려고 하면 복잡한 문제들은 있습니다. 그래서 UDP와 TCP가 있는데 우리가 아는 대부분의 게임들은 UDP를 씁니다. 보통 반응속도가 빠른 게임들인데 격투, 슈팅, AOS형태의 게임들입니다.
TCP를 사용하는 게임들은 안정성이 높아야 하는 게임들인데 MMORPG, 보드게임들입니다.
TCP | UDP | |
---|---|---|
장점 | 1. 연결 유무를 확인. 2. 패킷의 순서 보장. 3. 송신 보장 |
TCP에 비해 빠르다. |
단점 | UDP에 비해 3배 느림. | 1. 연결 유무 X 2. 순서보장 안됨. 3. 송신보장 안됨. |
특징 | 3Way handshake 사용. | 단점을 보완하고자 Relialde UDP를 코딩으로 만들어서 사용. |
용도 | MMORPG, 보드게임들, 등 빠른 반응속도를 요구하지 않는 게임들. | 격투, 슈팅, AOS, 등 빠른 반응속도를 요구하는 게임들. |
'Networking' 카테고리의 다른 글
[바미] P2P, Relay 서버 방식에 대해 알아보자! (2) | 2020.12.18 |
---|---|
[바미] 중계서버와 그 외 유용한 방식들에 대해 알아봅시다. (0) | 2020.12.18 |
[바미] Delay 와 Rollback에 대해 알아보자! (0) | 2020.12.18 |
[바미] Deterministic방식에 대해 알아보자! (0) | 2020.12.18 |
[바미] 게임 네트워킹에 대해 (0) | 2020.12.18 |