네트워크 프로그래밍을 위한 준비로 인터넷 근간을 이루는 TCP/IP 프로토콜을 살펴보자
인터넷을 통해 통신을 수행하는 개체는 크게 호스트(Host)와 라우터(Router)로 나눌 수 있다.
호스트 (Host)
라우터 (Router)
호스트와 라우터, 라우터와 라우터, 그리고 호스트와 호스트가 통신하려면 정해진 절차와 방법을 따라야 하는데 이를 통신 프로토콜(communication protocol)이라고 한다.
(1-2 그림)
인터넷에서 사용하는 핵심 프로토콜은 TCP와 IP로, 이를 비롯한 각종 프로토콜들을 총칭하여 TCP/IP 프로토콜이라고 한다.
일반저긍로 운영체제(OS)의 일부로 구현되며, 응용 프로그램은 운영체제가 제공하는 TCP/IP 프로토콜의 서비를 사용해 통신한다. 여기에서 통신을 수행하는 주체이자 통신의 최종 목적지는 호스트 자체가 아닌 호스트에서 수행하는 응용프로그램이라는 것은 주의해야할 점이다ㅏ.
일반적으로 프로토콜들은 기능별로 나누어 계층적으로 구현하는데, TCP/IP 프로토콜도 이 구조를 따른다. 아래 그림은 TCP/IP 프로토콜의 각 계층별 기능을 요약한 것이다.
(1-3 그림)
네트워크 접근 계층(network access layer)은 물리적 네트워크를 통한 실제 데이터 송수신을 담당한다. 물리적 신호를 처리해 데이터를 송수신하는 네트워크 하드웨어와 운영체제가 제공하는 장치 드라이버로 구성된다.
하드웨어적으로 정의된 물리 주소(phsical address)를 사용해 통신하는데, 물리 주소는 네트워크 방식에 따라 다르며, 일반적으로 상호 호환되지 않는다.
많이 사용하는 이더넷(Ethernet)에서는 48비트 물리 주소를 사용한다. 윈도우에서는 명령 프롬프트에서 ipconfig/all
을 통해 확인 할 수 있다.
인터넷 계층(internet layer)은 네트워크 접근 계층의 도움을 받아 데이터를 목적지 호스트까지 전달하는 역할을 한다. 네트워크 접근 계층처럼 주소를 지정하는 방법이 필요한데, 하드웨어적으로 정의된 물리 주소 대신 소프트웨어적으로 정의된 논리 주소인 IP 주소(Internet Protocol address)를 사용한다.
IP 주소는 네트워크 접근 계층에서 사용하는 물리 주소와 별개로 정의하며, 전 세계적으로 유일성을 보장한다. 이러한 유일성과 하드웨어 독립성 때문에 TCP/IP 프로토콜은 다양한 네트워크 기술과 하드웨어에서 작동할 수 있어 이를 통해 전 세계적인 네트워크인 인터넷(Internet)을 만들 수 있게 되었다.
실제 통신을 하려면 전송 경로를 결정하고 그에 따라 데이터를 전달하는 절차가 필요한데, 이를 라우팅(routing)이라고 한다.
라우팅은 데이터를 목적지까지 전달하는 일련의 작업을 말하는 용어로, 라우팅에 필요한 정보를 수집하는 작업과 라우팅 정보를 기초로 실제 데이터를 전달하는 작업을 포함한다. 라우팅을 담당하는 전용 장비를 라우터(router)라고 하고, 라우터를 통해 서로 다른 네트워크에 연결된 호스트가 통신할 수 있다.
전송 계층(transport layer)은 최종 통신 목적지를 지정하고 오류 없이 데이터를 전송하는 역할을 한다. 위에 말한 IP 주소와 라우팅을 통해 목적지 호스트에 데이터가 도달할 수 있게 하는 것이다.
그러나 통신의 최종 목적지는 호스트가 아닌 해당 호스트에서 실행하고 있는 프로세스(응용프로그램)이다. 즉, 전송 계층에서 프로세스를 지정하는 일종의 주소를 사용하는데, 이를 포트 번호(port number)라고 한다.
인터넷 계층의 IP가 제공하는 전송 서비스는 최선을 다하지만(best-effort) 신뢰성은 없다(unreliable)는 특징이 있다. 즉, 데이터에 문제가 생겨 목적지에 도달하지 못하거나 도달하여도 실제 데이터의 내용이 손상되었을 가능성이 있다. 전송계층에서는 이러한 상황을 방지한다.
전송 계층에 해당하는 TCP/IP 프로토콜로는 TCP(Transmission Control Protocol)과 UDP(User Datagram Protocol)이 있다.
TCP | UDP |
---|---|
연결형(connection-oriented) 프로토콜 - 연결 설정 후 통신 가능 | 비연결형(connectionless) 프로토콜 - 연결 설정 없이 통신 가능 |
신뢰성 있는 데이터 전송 - 데이터를 재전송함 | 신뢰성 없는 데이터 전송 - 데이터를 재전송하지 않음 |
일대일 통신(unicast) | 일대일 통신(unicast) 일대다 통신(broadcast, multicast) |
데이터 경계 구분 안 함 - 바이트 스트림(byte-stream) 서비스 | 데이터 경계 구분함 - 데이터그램(datagram) 서비스 |
응용 계층(application layer)은 전송 계층을 기반으로 한 다수의 프로토콜(Telnet, FTP, HTTP, SMTP 등)과 이 프로토콜을 사용하는 응용 프로그램을 포괄한다. 소켓을 사용한 네트워크 프로그램도 여기에 속한다.
데이터 전송을 위해 먼저 송신 측 호스트의 응용 프로그램이 보내는 데이터를 수신 측 호스트이 응용 프로그램에 전송하려면 각 프로토콜에서 정의한 제어 정보(IP 주소, 포트 번호, 오류 체크 코드 등)이 필요하다. 제어 정보는 위치에 따라 앞쪽에 붙는 헤더(header)와 뒤쪽에 붙는 트레일러(trailer)로 나뉜다.
데이터는 이러한 제어 정보가 결합된 형태로 전송되며, 이를 패킷(packet)이라고 한다. (즉, 패킷 = 제어 정보 + 데이터)
이더넷에 연결된 두 호스트가 TCP/IP를 사용해 데이터를 교환하는 경우 패킷의 전송형태는 아래와 같다.
패킷 전송 형태: 송신 측
(1-5 그림)
패킷 전송 형태: 수신 측
(1-6 그림)
송신 측 응용 프로그램에서 보낸 데이터는 TCP/IP/이더넷 계층을 지나면서 제어 정보가 덧붙여 패킷이 형성되어 전송된다. 이런 패킷이 수신 측에 도착하면 이더넷/IP/TCP 계층을 지나 제어 정보가 제거되고 수신 측 응용 프로그램이 데이터를 받는다.
이 같은 패킷 전송 형태를 각 계층의 관점에서 보면 아래 그림과 같다
(1-7 그림)
(송신 측에서 보낸 이더넷 패킷이 그대로 수신 측에 도달하는 경우는 두 호스트가 같은 물리적 네트워크에 속한 경우뿐이기 때문에 포함되지 않았다.)
즉, 각 계층은 동일한 위치의 상대편 계층과 통신하는 것으로 생각할 수 있다. 따라서 응용 프로그래머는 주고 받을 데이터에만 집중하여 구현하고, 나머지는 운영체제가 제공하는 프로토콜이 처리하도록 맡기면 된다.
패킷 전송 형태: 인터넷
(1-8 그림)
TCP/IP 프로토콜을 사용한 데이터 전송 원리를 일반화하면 위와 같은데, 응용 계층과 전송 계층의 경우 물리적 연결은 없으나 인터넷 계층과 네트워크 접근 계층이 제공하는 기능을 통해 가상적 연결이 존재하는 것으로 생각할 수 있다. 두 계층은 모두 끝에서만(end-to-end) 존재하며 동작한다.
반면 인터넷 계층은 호스트와 라우터에 모두 존재하며, IP 주소와 라우팅 기능을 이용해 패킷 전송 경로를 결정한다. 실제 패킷 전송에는 네트워크 접근 계층이 제공하는 물리 주소를 사용하는데, 물리 주소는 패킷이 라우터를 통과할 때마다 다음 지점의 물리 주소로 계속 변경된다.
TCP/IP 프로토콜을 사용해 통신할 때는 IP 주소와 포트 번호를 사용한다. IP 주소는 IPv4(IP 버전 4)와 IPv6(IP 버전 6) 두 종류가 있다.
IPv4
.
(dot)으로 구분해 10진수 4개로 표기 (dotted-decimal notation)IPv6
:
(colon)으로 구분해 16진수 8개로 표기 (colon-hexadecimal notation)폐쇄된 네트워크거나 IP를 공유하는 경우가 아니라면 IP 주소는 전 세계적으로 값이 유일하다. 라우터가 라우팅을 할 때는 IP 헤더에 포함된 수신자 IP 주소를 사용하며, 데이터를 받은 곳에서 답장을 보낼 때는 IP 헤더에 포함된 송신자의 IP 주소를 사용한다.
IP 주소는 인터넷이 있는 호스트를 유일하게 구별 할 수 있지만 통신의 최종 주체인 프로세스는 식별하지 못한다. 프로세스 식별자로는 포트 번호를 사용한다. 그러나 실제로는 한 프로세스가 포트 번호를 두개 이상 사용하는 경우도 종종 있고, 둘 이상의 프로세스가 한 포트 변호를 사용할 수 도 있다. 즉, 포트 번호는 프로세스를 구별하는 식별자보다 통신의 종착점(하나 또는 여러 프로세스)을 나타내는 식별자로 생각하는 것이 좋다.
TCP와 UDP는 포트 번호로 부호 없는 16비트 정수를 사용하여 0 ~ 65535 범위가 가능하지만 모든 범위를 자유롭게 사용하지는 못한다.
포트 번호 | 분류 |
---|---|
0 ~ 1023 | 알려진 포트 (well-known ports) |
1024 ~ 49151 | 등록된 포트 (registered ports) |
49152 ~ 65535 | 동적/사설 포트 (dynamic and/or private ports) |
구체적인 내용은 포트 번호를 관리하는 공식 사이트 참고
위에 표에서 나와 있듯 0 ~ 1023번 포트의 경우 용도가 정해져 있어 함부로 사용하면 안되며, 일반저긍로 서버를 작성할 때는 1024 ~ 49151 범위에서 선택하여 사용하는 것이 바람직하다.
IP 주소와 포트 번호와 관계를 그림으로 나타내면 아래와 같다. 아래 그림은 IP 주소를 2개 가지는 호스트를 나타내며, 한 프로세스가 둘 이상의 TCP 또는 UDP 포트를 사용하기도 하고 한 포트 번호를 2개 이상의 프로세스가 사용하는 상황을 보여주고 있다.
(1-9 그림)
IP 주소는 기억하고 사용하기 불편해 도메인 이름(domain name)을 사용하는 경우가 많다. 도메인은 IP 주소에 대한 별명으로 실제 통신 시 IP 주소로 변환해야 한다.
네트워크 프로그램은 일반적으로 클라이언트-서버 모텔(client/server model)로 작성한다. 클라이언트-서버는 두 프로그램이 상호 작용하는 방식을 나타내는 것으로 서비스를 요청하는 곳은 클라이언트(client), 클라이언트가 요청하는 서비스를 처리하는 곳을 서버(server)라고 한다.
클라이언트-서버 모델을 한 컴퓨터에서 실행되는 두 프로그램에 적용할 경우 다양한 프로세스 간 통신(IPC, Inter-Process Communication) 기법을 사용해 데이터를 주고받을 수 있다.
그러나 네트워크로 연결된 컴퓨터에서 실행되는 두 프로그램에 적용할 경우 반드시 통신 프로토콜을 사용해야 데이터를 주고받을 수 있다.
(1-10 그림)
위에 그림처럼 서로 다른 호스트에서 실행되는 두 프로그램이 상호 접속하는 경우 접속이 성공하려면 반드시 상대 프로그램이 실행 중이어야 한다. 하지만 이 같은 동시 접속 모델을 사용하면 타이밍 문제때문에 접속이 실패할 확률이 높아지고, 결과적으로 통신할 수 없는 경우가 자주 발생한다.
(1-11 그림)
위 그림과 같은 클라이언트-서버 모델을 사용하면 한 프로세스가 먼저 실행하여 대기하고, 다른 프로세스가 나중에 실행하여 접속하여 타이밍 문제를 걱정해야할 필요가 없다.
이때 먼저 실행하는 쪽이 서버, 나중에 실행하는 쪽이 클라이언트이다.
클라이언트-서버 모델은 두 프로그램의 상호 작용 모델로 자연스러우면서도 로컬 통신과 네트워크 통신에 모두 적합해 주로 사용된다.
참고 자료
김성우 저, "TCP/IP 윈도우 소켓 프로그래밍", 한빛아카데미, 2018