안녕하세요 삽잡이입니다.
이번 시간에는 TCP/IP 4계층을 통해
데이터가 목적지의 PC에 어떻게 전달되는지 생각해보는 시간을 가져보겠습니다.
네트워크에는 전송을 위한 OSI 7계층이라는 개념이 있습니다. 이론 쪽인데...
소켓을 처음 고안해낸 버클리 대학쪽에서 TCP/IP라는 4계층을 만들어 냈습니다...
이를 통해 우리는 데이터가 어떻게 날라가는지 확인을 해보도록 하지요...
각 계층별로 핵심을 소개하겠습니다.
이해가 가지 않더라도 우선은 가볍게 보시길 바랍니다.
우선 링크 계층에서는
'일대일 전송'을 보장해주고, 데이터 통신을 위한 하드웨어에 관련된 정의를 담당합니다.
다음으로 인터넷 계층에서는
ID 번호를 보고 컴퓨터간에 통신을 할 수 있도록 해줍니다.
그리고 'IP'를 집어넣습니다... 따라서 데이터를 보낸 IP와 목적지의 IP를 둘다 집어 넣는 곳이
이 계층입니다...
다음으로 전송 계층에서는
tcp, udp와 같은 전송하는데 관련된 약속을 정하는 것입니다.
약속 즉, 프로토콜이지요...
왜 갑자기 프로토콜을 말했을까요?
각 계층별로 '사용되어야한다.', '정의 되어야한다.' 하는 정의가 되있고 약속을 만들어 낸 것이
프로토콜인데 각 계층별로 이러한 프로토콜을 가지고 있기 때문입니다...
인터넷 계층에서는 IP 프로토콜이 있지요....
아무튼...
응용 계층은, 말그대로 우리가 만들어 놓은 프로그램에 대한 내용을 가진 계층입니다.
전송 계층위에 동작하는 프로토콜인 http, ftp, telnet등이 해당되는데요...
이 모드가 응용 계층에 포함됩니다... (TCP 위에서 동작하니까 포함된다고 하는 것입니다...)
그럼, 응용 계층에서는 우리가 통신하는 규칙을 만들어야할터인데
이 규칙을 만들기 위해서는 약속을 정의해야되지 않겠습니까?
이 약속을 라이브러리로 만들면 '프로토콜 라이브러리'가 되는것이고,
다른 사람한테 주면 클라이언트가 만들어지는 것이지요...
어찌됬건, 어플리케이션이 자기 마음대로 만들어 정의할 수 있는 계층이 응용 계층입니다.
응용 계층은 우리가 만들어서 제공하는데, 그렇다면 일반적으로 전송계층까지는 누가 제공할까요?
바로 OS입니다. 네트워킹이 안되는 OS는 없다고 할 정도로
거의 모든 OS는 네트워킹이 가능합니다.
그러니까 프로토콜들이 OS 내부에 다 구현이 이미 되있다는 것입니다.
원래는 네트워크 라이브러리가 이 기능을 제공해줘야합니다.
그런데, 이 라이브러리들을 모든 OS가 장착하고 있다고 생각하시면 됩니다.
자... 그럼 여기서 문제!
아두이노와 같은 하드웨어를 사용할 때에 네트워크 기능을 사용하고 싶다면 어떻게 해야할까요?
참고로 아두이노는 OS가 없습니다....
두가지 방법이 있습니다.
첫 번째 방법! 모든 라이브러리들을 개발하는 것! 헐...
두 번째 방법! 하드웨어를 쓰는 것!
하드웨어를 쓴다? 즉, 네트워크 라이브러리가 심어져있는 하드웨어를
다른 말로 통신 가능한 라이브러리가 들어있는 하드웨어를 쓰는 것입니다....
이더넷 카드와 같은 라이브러리를 장착하고 있는 하드웨어를 사용해서
해당 하드웨어로 명령을 하면 그 하드웨어가 통신을 해주는 것이지요.. OS 대신에..
이 말을 왜 했느냐!
전송계층까지는 OS가 알아서 해주는데
정확하게는 OS가 아닌 네트워크 라이브러리가 처리를 해준다는 것을 말씀드리고 싶었습니다.
지금까지 제가 말한 네트워크 라이브러리는 다른 말로 '소켓 라이브러리'라고 부릅니다.
소켓은 뭘까요? 콘센트 같은 것을 말합니다.
다른 놈들과 호환되기 위한 접점을 말하는데,
이 놈한테 꽂아야 통신, 연결, 이야기할 수 있다는 소켓의 의미에서 착안되어 지었다네요...
이 소켓은 다음에 배울 통신하기 위한 커널 객체와 헷갈릴 수 있습니다.
왜냐, 통신하기 위한 커널 객체를 윈도우에서는 소켓이라 부르기 때문이지요...
커널은 라이브러리가 될 수도... 커널 오브젝트가 될수도 있겠군요...
아무튼... 정리해봅시다.
OS가 어떤 기능을 제공하는가?
바로, TCP 프로토콜, IP 프로토콜, 데이터 링크 관련된 프로토콜 과 같은 라이브러리를
이미 구현한 것을 내장해놓고 처리를 대신 해주는 것입니다.
'a' 라는 문자를 다른 놈에게 보내는 과정을 한번 살펴보겠습니다.
그렇다면 우선 전송 계층에서 TCP 헤더를 붙이고, 인터넷 계층으로 내려보내면 IP 헤더를 붙입니다.
그리고, 또 내리면 링크 계층에서 이더넷 헤더와 이더넷 트레일러를 붙입니다.
이처럼 이더넷 헤더 ~ 이더넷 트레일러까지 하나의 전송 단위로 '패킷'이라고 부릅니다.
그리고 데이터 링크 계층에서 일대일 통신을 담당하기 때문에,
패킷을 까보면 라우터와 통신하는 것을 확인할 수 있습니다.
즉, 라우터까지 날라가는 것을 링크 계층이 보장해준다는 것입니다.
다음으로 라우터에서는 IP 헤더까지 확인합니다.
시작 IP와 도착 IP가 들어있기 때문이지요...
라우터에 도착하면 시작점 IP와 도착점 IP를 확인하고 네트워크 ID를 확인하여
다시 쏴주게 됩니다.
그런데 제 PC에서 제 PC로 패킷을 날려도 라우터를 한번 거쳐와야되기 때문에
즉, 데이터를 날리면 라우터가 저한테 다시 날린다는 것이지요...
아무튼, 이 경우 네트워크 카드가 없든, 라우터가 꺼졌든 상황에서는
나에게 패킷을 날리는 경우가 불가능해지기 때문에
이런 불편함을 없애기 위해 루프백 주소를 제공해주기도 합니다...
굳이 라우터까지 안가고 TCP 스택을 거쳤다가 다시 올라오도록 하는 방식이지요...
주소는 공개되있습니다. 127.0.0.1 이지요...
자... 'a' 문자를 보내고 있었지요...
'a'라는 문자를 보내는데 헤더들이 붙고 이더넷 헤더와 트레일러가 붙습니다.
그리고 일대일로 연결되는 놈 즉, 라우터겠지요... 그 놈에게 데이터를 쏩니다...
그러면 라우터놈은 IP까지 열어보게 됩니다.
열어서 보고 일대일로 연결되어있는 인접 라우터에게 해당 데이터를 쏘는 것입니다.
정리하자면,
일대일 통신때는 링크 계층까지만, 그리고 라우터에 도착하면 IP 헤더까지 까보게 되는 것입니다.
보내고자 하는 PC의 최종 라우터가 있을 것입니다.
그 라우터에게 데이터가 도착하게 되면, 해당 라우터도 당연히 네트워크 ID를 확인하겠지요...
자기 네트워크 ID인 것을 IP헤더를 까보고 확인하면,
host ID를 보고 일대일로 데이터 링크 계층만 보고 데이터를 쏩니다.
정확히는 브로드 캐스팅을 하는데요,
대부분 한번에 브로드 케스팅을 합니다... 즉, 방송을 하는 것이지요...
그럼 로컬 내 End System에 방송이 도착할터인데, 해당 되는 PC만 손을 들겠지요...
지금까지의 과정을 생각해보면
라우터들끼리 '핑퐁'을 하며 데이터를 공유하고,
최종 라우터에서는 브로드 케스팅을 통해 데이터를 공유하는 것이었습니다.
그리고 해당 PC는 자기 것이라면 올라오겠지요...
자... 원하는 목적 PC에 데이터가 전달됬습니다.
그럼 끝? 아닙니다...
다음으로 전송 계층인 TCP 헤더를 벗깁니다... *-_-*
TCP의 핵심은 컴퓨터로 도착했지만, 컴퓨터 내부에 수 많은 프로세스들중
누구 것인지 프로세스를 구분해주는 것이지요...
프로세스를 구분하는 포트번호를 통해서 말이에요...
무사히 도착했다면 드디어 데이터를 받을 수 있게 된것입니다.
전송 계층까지는 OS가 하니깐요...
참고로, OS에게 우리가 law 소켓이라고 해서 링크 계층까지는 내가 제어를 못하지만...
인터넷 계층부터는 우리가 제어할 수 있습니다.
즉, 소켓 프로그래밍으로 IP 헤더부터 볼 수 있게 되는 것이지요...
단, OS가 해야할 일을 내가 다 해야하는 책임성이 필요하겠지요.. 의무성이라고 해야하나...
이를 아무튼 law 소켓 프로그래밍이라고 합니다.
그냥 가볍게 흘려 보내겠습니다...
자... 중요한것은
이런 과정을 거쳐서 'a' 글자를 쏴서 해당 PC의 어플리케이션까지 도착하게 되는것이지요...
쏠때는 포트번호, 프로토콜을 결정하고 IP와 도착할 IP를 결정하고...
이더넷을 내려보면 또 핑퐁해서 데이터가 전달되는 과정을 진행하겠지요...
그리고 또 데이터를 받는 PC는 우리가 거친 과정을 통해 데이터를 프로그램에 올려주는 것이고요.
이렇게 많은 과정을 거치게됩니다...
마지막으로,
TCP 수준에서 가장 중요한 요소에 대해서 알아보겠습니다.
물론 다 중요하겠지만, TCP 수준에서 가장 중요한 요소를 하나 꼽으라면 버퍼입니다.
Send 버퍼와 Recieve 버퍼이죠...
결론적으로 보낼 때 Send 버퍼에 들어갔다가 데이터를 받을 때에는 Recieve 버퍼에 들어갑니다.
즉, OS가 해주는 것은 Recieve 버퍼에 데이터를 채워주는 것 까지이고
그 데이터를 가져가는 것은 응용프로그램의 몫이 되는 것이지요....
TCP 수준에서 Recieve, Send 버퍼를 만들어주고
우리가 보낸 데이터는 단지 Send 버퍼에 들어갈 뿐인것입니다...
도착하면 Recieve 버퍼에 와 있는 것 뿐이구요...
자동적으로 데이터가 오고 가는것이 아니라 우리가 꺼내야한다는 사실을 기억하시길 바랍니다.
우리가 데이터를 보낼 때에도 최소한 Send 버퍼까지 넣어줘야한다!
지금까지 기가긴 데이터의 여정에 대해서 알아봤습니다.
다음시간에 뵙겠습니다. 이상 삽잡이였습니다!
'삽질의 현장 > - 네트워크 프로그래밍' 카테고리의 다른 글
#006_Window_Network_IP, DNS (0) | 2015.10.02 |
---|---|
#005_Window_Network_구조체 멤버 정렬 (0) | 2015.10.02 |
#004_Window_Network_바이트 정렬 (0) | 2015.10.02 |
#003_Window_Network_ 윈도우 소켓 초기화 및 종료 (0) | 2015.10.02 |
#001_Window_Network_ Intro (라우터) (0) | 2015.10.01 |