이번 포스팅에서는 IP 프로토콜, 패킷, TCP/UDP 프토토콜, 그리고 포트에 대해 알아보겠습니다.
IP 프토토콜이란 지정한 IP 주소에 데이터를 전달하기 위한 프로코콜입니다. 이때 그냥 데이터를 전달하는게 아니라, 패킷(Packet) 이라는 통신 단위로 데이터를 전달합니다.
아라채럼 패킷에다 출발지 IP, 도착지 IP, 그리고 처리할 메시지를 담아서 인터넷 망에다 던집니다. 그러면 인터넷 망에 있는 각 노드들이 도착지 IP, 즉 200.200.200.2 를 받을 수 있는 서버 주소를 계속 어딘지를 찾아가면서 패킷을 건너건너 계속 전달해줍니다.
반대로 도착지 IP에서 다시 잘 받았다는 OK 메시지와 함꼐 반환을 시킬 수도 있습니다.
위와 같은 IP 프로토콜방식은 한계점을 보입니다.
패킷을 던졌는데 인터넷망의 중간 어딘가에서 패킷이 사라질 수도 있고,
패킷을 여러개를 던졌는지 순서대로 도착하지 않을수도 있습니다.
같은 IP 에서 사용하는 서버에서 통신하는 애플리케이션이 여러개이면 어떻게 해결할까요? 예를들어 한 컴퓨터에서 노래 프로그램을 틀고, 게임을 동시에 할수도 있습니다.
직전에 살펴봤듯이 IP 프로토콜의 비연결성의 특징으로 인해, 패킷이 손실될 수도 있습니다. 목적지를 잃게되어, 인터넷망의 노드 중간에서 패킷이 머무르게 될수 있습니다.
또한 패킷에 담아서 전송하는 메시지의 용량이 꽤 클수도 있어서, 보통 조금씩 끊어서 다른 패킷에 메시지를 담아서 전송합니다. 그러면 문제점이, 패킷 전송이 다른 노드를 타고 다른 경로를 통해 목적지에 전송될 수도 있습니다. 그렇게 된다면 메시지가 원하는 순서대로 전송이 되지 않을 수 있습니다.
예를들어 위와 같이 Hello world 를 보낼때, 용량이 너무 커서 메시지를 Hello 와 world 따로 다른 패킷에 담아서 전송하는 경우를 생각해봅시다. Hello 를 패킷에 담아서 전송하고, 그 다음으로 world 를 두번째 패킷에 담아서 전송할 수 있으나, 2번째 패킷이 더 빠른 노드 경로를 타고 이동해서 world 가 Hello 보다 먼저 도착지에 전송될 수도 있습니다.
IP 프로토콜 외에도 아래와 같은 다양한 프로토콜 방식과 여러 계층으로 구분됩니다.
예를들어 채팅 프로그램으로 미국에 있는 친구에게 Hello world 라는 메시지를 전송하는 경우를 가정해봅시다. 그러면 아래와 같은 과정이 발생합니다.
Socket 라이브러리를 통해 OS 계층에다 Hello 라는 메시지를 넘깁니다.
그러면 OS 계층에 있는 TCP 가 Hello 라는 메시지에다 TCP 정보를 씌웁니다 (그림에서 녹색 테두리)
그러고나서 TCP 밖에다 IP 관련 정보를 씌웁니다. (그림에서 주황색 테두리)
그러면 IP 패킷이 생성이 된 것입니다.
=> 결국 IP 패킷은 IP와 관련한 정보, 그 안에 TCP와 관련한 정보, 또 그 안에 내가 만들었떤 실제 메시지(Hello world) 를 보유하고 있게 됩니다.
그렇다면 IP 패킷에 IP, TCP, 실제 메시지와 관련한 정보를 담게된다고 했는데, 이들이 뭔지 더 자세히 알아봅시다. IP 패킷의 구성성분을 더 뜯어보자는거죠!
아래 그림은 패킷의 세부구조입니다.
우선 IP 패킷은 출발지 IP, 목적지 IP 를 가지고 있게 됩니다. (기타 등등 조금더 있긴하지만요)
그런데 이 정보만으로는 IP 프로토콜의 한계점을 보인다고 했었죠? 이를 해결하는것이 TCP 이겠고요.
TCP 세그먼트는 전송제어와 관련된 정보, 순서와 관련된 정보, 검증 정보와 관련된 정보를 지니고 있습니다. 따라서 IP 만으로 해결하지 못했던 순서 문제와 같은 것들을 해결할 수 있게 됩니다.
이 외에도 출발지 와 도착지 포트(PORT) 정보를 가지고 있게됩니다. 포트는 추후에 설명드겠습니다.
TCP 에 대해 조금 더 살펴보죠. TCP 는 전송 제어 프토토콜(Transmission Control Protocol) 로, 이름 그대로 어떻게 할지를 제어한다 라는 특징을 지니고 있습니다.
TCP 의 특징을 세분화해서 크게 3가지로 나눌 수 있습니다.
제랑 나랑 연결이 되었는지 여부를 먼저 확인후 연결후에 메세지를 전송합니다.
이로 인해 도탁지 컴퓨터의 서버가 꺼져있다면 전송이 잘 되지않는 방식이 되는 것입니다.
데이터를 전달한 것을 보증해줍니다. 예를들어 내가 메시지를 보냈고 중간에 어디선가에서 누락이 된다면 도착지 쪽에서 메시지를 못받는다는 것을 알수가 있습니다.
순서를 보장해줍니다. 순서에 관한 내용은 앞서 설명드렸습니다. Hello 와 world 메세지가 world 가 먼저 보내지는 등의 이상한 도착 순서가 발생되지 않는 것을 보장해주는 것입니다.
=> 이런 장점으로 인해, TCP 는 신뢰할 수 있는 프로토콜이자 현재는 대부분의 애플리케이션에서 TCP 를 사용하고 있는 중입니다.
직전에 설명드린 TCP 3 way handshake 에 대해 더 알아보겠습니다.
과정을 알아보기전에 먼저 아셔야할 용여는 다음과 같습니다.
SYN 메세지 : 접속 요청
ACK 메시지 : 요청 수락
과정은 아래와 같습니다. TCP IP 프로토콜로 연결을하면,
클라이언트에서 서버로 SYN 이라는 메시지를 보냅니다. 즉, 연결을 해달라는 요청을 보내는것입니다.
그러면 서버에서는 ACK 메세지를 클라이언트에게 보내면서, 동시에 "나도 연결해줘!" 라는 말을 전달하기 위해 ACK 라는 메시지를 전달합니다.
즉, 클라이언트에서 나에게 보낸 연결 요청을 수락해주면서 (ACK 메시지 보내기) 동시에 나도 클라이언트에게 연결하고 싶다는 요청을 보내는 것입니다. ( SYN 메시지 보내기 )
그러면 클라이언트도 서버에게 연결 요청을 수락해주는 ACK 메시지를 보내줍니다.
=> 즉, 클라이언트와 서버 양측모두 SYN 및 ACK 메시지를 보내고 연결 여부를 수락하면서
서버와 클라이언트 양측모두 연결 여부를 확실하게 신뢰할 수 있게 됩니다.
서버가 껴져있다면 원할한 데이터 전송이 이루어지지 않을겁니다.
클라이언트가 SYN 을 보낸다면 서버에서 SYN 과 ACK 메세지를 회신해 주는 것이 정상인데, 회신을 하지 않고 무응답인 상태가 됩니다.
그러면 클라이언트 입장에서는 어? 서버가 껴져있고 연결이 잘 안되어있네? 라고 인식읋 할 수 있게 되는 것입니다. 그래서 Hello world 과 같은 메시지를 안보내게 되는 것입니다.
그런데 TCP 의 3 way 방식을 통해 연결되었다는 말을 하지만, 이건 진짜로 연결된 것이 아니다.
즉, 이론상으로는 연결되었다고 표현할 수 있으나 실제로 물리적으로는 연결된 것이 아니다.
3 way 방식은 클라이언트와 서버 양측에게 서로 SYN 과 ACK 을 보냈고 논리적으로 연결되었구나의 간단한 확인여부 방식입니다.
그러나, 클라이언트와 서버의 중간 사이에는 수많은 서버(노드)가 존재할겁니다. 그 중간의 노드들끼리도 제대로 연결되었는지 여부를 모릅니다.
클라이언트가 서버에게 데이터를 전송했을 떄 그에 대한 응답으로 데이터를 잘 받았다는 것을 회신해주는 것읋 확인해주는 방식입니다. 이로써 데이터가 잘 전달되었다는 것을 확인하는 방식이라 볼 수 있습니다.
만일 패킷1, 2, 3 순으로 서버에 전달해줘야 하는데 패킷이 1, 3, 2 순서로 도착했다고 합시다.
그러면 TCP 는 다시 패킷1은 그대로 놔두고 나머지 패킷을 모두 버립니다.
그리고 패킷2부터 정상적인 순서대로 다시 보내나고 클라이언트에게 요청을 하고, 클라이언트는 다시 패킷 2,3 을 정상적인 순서에 따라 재전송하도록 하는 방식입니다.
이로써 패킷 전송의 순서를 보장해주는 것이되겠죠?
UDP 는 TCP 와 같은 OS 계층에 있는 프로토콜입니다.
그런데 UDP 는 딱히 TCP 와 달리 특별한 기능이 없습니다.
3 way handshake 방식도 없고, 데이터 전달도 보증해주지않고, 패킷 전달 순서도 보증해주지 않습니다. 그러면 왜 쓰지? 라는 의문이 들 수 있는데, UDP 는 IP 패킷 위에 포트(Port) 라는 정보가 추가가 됩니다. (주의! TCP 에도 포트가 존재합니다!)
이로써 데이터 전달 및 순서가 보장되지 않지만, TCP 에 비해 단순하고 빠른 방식입니다.
UDP : IP 패킷에 포트(port) 와 체크섬 정도만 간단하게 추가한 프로토콜
예를들어 내 컴퓨터에서 게임도 하고, 화상통화도 하고, 웹 브라우저도 요청을 동시에 할수 있다.
즉, 클라이언트가 한번에 여러개의 서버와 통신해야 하는 상황이 발생했습니다.
그렇다면 여러 서버로부터 나에게 패킷들이 날아올텐데, 전달받은 패킷이 게임을 위한 패킷인지, 화상통화를 위한 패킷인지를 알 수가 없습니다. 반대로 보낼때도 마찬가지입니다.
그래서 TCP 와 UDP 와 같은 패킷에는 포트(PORT) 라는 정보를 담아서 전송합니다.
출발지 포트와, 도착지 포트를 패킷에 담아서 전송하는 방식인것이죠.
즉, IP 에다 추가적으로 포트라는 정보를 더한것이죠!
IP는 목적지 서버를 찾기위한 주소이고, 그 목적지 서버안에서 돌아가는 애플리케이션들을 구분하는 것이 포트라고 생각하면 됩니다.
앞으로 TCP 와 IP 를 합쳐서 TCP/IP 라는 패킷이라는 말로 부르겠습니다. 그리고 그 안에는 출발지 IP와 PORT, 그리고 목적지 IP와 PORT 가 들어있다고 보면 됩니다.
정리를 해보자면, 포트란 IP내에서 프로세스를 구분하기 위한 용도입니다.
게임 포트는 8090번, 화상통화는 21000번 이렇게 포트를 열어서 게임서버, 화상통화 서버, .. 등과 연결하는 것이죠.
예들들어 클라이언트에서 게임서버와 연결하고 싶은 상황을 가정해봅시다.
그러면 200.200.200.2 에 있는 서버 IP 와 연결하고 통신하기 위해 11220 번 포트로 연결할거야! 라면서 클라이언트인 내가 패킷을 쏘는 것입니다.
또 예를들어 웹 브라우저와 연결하고 통신하고 싶은 상황을 가정해봅시다.
내가(클라이언트가) 웹 브라우저(서버) 에게 요청을 할떄는 200.200.200.3 IP 의 80 포트에다 요청 메시지를 보내는 것이고,
반대로 웹 브라우저에서 응답이 올떄는 (HTML 파일을 만들어서 클라이언트인 나에게 보내줄떄) 그 결과물을 100.100.100.1 번 IP 의 포트 10010 번에 보내주는 것입니다.
좋은 글 감사합니다 근데 "그러면 서버에서는 ACK 메세지를 클라이언트에게 보내면서, 동시에 "나도 연결해줘!" 라는 말을 전달하기 위해 ACK 라는 메시지를 전달합니다." 에서 두번째 ACK 가 ACK 아니라 syn인가요?