코승호딩의 메모장

[네트워크와 소켓 프로그래밍] 본문

네트워크 프로그래밍

[네트워크와 소켓 프로그래밍]

코승호딩 2023. 9. 9. 18:56
 

TCP/IP 소켓 프로그래밍 : 네이버 도서

네이버 도서 상세정보를 제공합니다.

search.shopping.naver.com

이번 포스팅(TCP IP 소켓 프로그래밍)에서는 위 책을 기반으로 TCP/IP 기반 네트워크 프로그래밍에 대해 기술하며 결과적으로 이 전에 Winapi를 활용하여 개발한 슈팅 게임에 네트워크를 프로그램 기능을 넣어 2인 플레이가 가능한 게임을 제작해보고자 합니다.

또한 위 책은 윈도우와 리눅스를 모두 서술하고 있지만 필자는 윈도우에 대해서만 서술하도록 하겠습니다.


01 TCP/IP 프로토콜

  • 호스트 : 최종 사용자의 응용 프로그램을 수행하는 주체 ex) PC, 노트북, 스마트폰 등 
  • 라우터 : 호스트에서 생성된 데이터를 여러 네트워크를 거쳐 전송하여 서로 다른 네트워크에 속한 호스트 간에 데이터를 교환할 수 있게 하는 장비
  • 통신 프로토콜 : 호스트와 라우터, 라우터와 호스트가 통신하기 위해 정해진 절차와 방법

인터넷에서 사용하는 핵심 프로토콜이 TCP와 IP이며 TCP/IP는 운영체제의 일부로 구현되고 응용 프로그램은 운영체제가 제공하는 TCP/IP 프로토콜의 서비스를 사용해 통신한다.

 

통신 프로토콜은 통상적으로 기능별로 나누어 위 그림과 같이 계층적으로 구현한다.

다음으로 통신 프로토콜은 계층별로 어떠한 일을 하는지 구체적으로 살펴보자.

 

네트워크 접근 계층

  • 역할 : 물리적 네트워크를 통한 데이터 송수신
  • 구성 요소 : 네트워크 하드웨어 + 장치 드라이버 
  • 주소 지정 방식 : 물리 주소 ex) 이더넷(48비트 물리 주소)

인터넷 계층 

  • 역할 : 네트워크 접근 계층의 도움을 받아 데이터를 목적지 호스트까지 전달
  • 구성 요소 : IP 주소 + 라우터
  • 주소 지정 방식 : IP 주소(전 세계적인 유일성과 하드웨어 독립성을 가지는 주소)
  • 라우팅 : 데이터를 목적지까지 전달하는 일련의 작업(라우팅에 필요한 정보를 수집하고 라우팅 정보를 전달)

전송 계층

  • 역할 : 최종 통신 목적지를 지정하고 오류 없이 데이터를 전송(목적지는 호스트가 아닌 프로세스) 또한 데이터 손실 또는 손상을 검출하여 잘못된 데이터가 전달되는 일을 방지
  • 주소 지정 방식 : 포트 번호(16 비트 주소)
  • 프로토콜 : TCP, UDP

TCP와 UDP

응용 계층

  • 역할 : 전송 계층을 기반으로 하는 다수의 프로토콜과 이 프로토콜을 사용하는 응용 프로그램을 포괄
  • 프로토콜 : Telnet, FTP, HTTP, SMTP 등

송신 호스트의 응용 프로그램이 보내는 데이터를 수신 호스트의 응용 프로그램에 전송하기 위해서는 각 프로토콜에서 정의한 제어 정보(IP 주소, 포트 번호, 오류 체크 코드 등)가 필요하다.

  • 헤더(Header) : 앞쪽에 붙는 제어 정보 
  • 트레일러(Trailer) : 뒤쪽에 붙는 제어 정보 

데이터는 이런 제어 정보가 결합한 형태로 전송되며, 이를 패킷(제어 정보 + 데이터)이라고 부른다.

 

(좌)송신 측, (우)수신 측

위 그림은 이더넷에 연결된 두 호스트가 TCP/IP를 사용하여 데이터를 교환할 때의 패킷 전송 형태이다.

송신 측의 응용 프로그램에서 보낸 데이터에 TCP + IP + 이더넷 계층 각각들의 제어 정보가 덧붙어 패킷이 생성된다.

패킷이 수신 측에 도달하면 제어 정보가 하나씩 제거되고 결과적으로 수신 측의 응용 프로그램에 데이터가 전달된다.

 

위 그림은 패킷 전송 형태를 각 계층의 관점에서 본 것이다. 각 계층은 동일 위치의 상대편 계층과 통신하는데 궁극적으로 수신 측 응용 프로그램에서는 제어 정보가 제거 되기 때문이다. 따라서 응용 프로그래머는 주고받을 데이터에만 집중하면 되고 나머지는 운영체제가 제공하는 프로토콜이 알아서 처리하게 된다.

 

응용 계층과 전송 계층은 종단에서만 존재하고 작동하며, 인터넷 계층은 호스트와 라우터에 모두 존재한다. 실제 패킷 전송에는 네트워크 접근 계층이 제공하는 물리적 주소를 사용하며, 패킷이 라우터를 통과할 때마다 다음 물리적 주소로 변경되어 가며 최종 목적지 호스트에 도달한다.

  • 응용 계층, 전송 계층 : 하부 계층이 제공하는 가상적인 연결을 사용해 동작
  • 인터넷 계층 : IP 주소와 라우팅 기능을 이용해 패킷 전송 경로 결정
  • 네트워크 접근 계층 : 물리 주소를 사용해 실제 패킷 전송

TCP/IP 프로토콜을 사용해 통신할 때는 IP 주소와 포트 번호를 사용하며 IP 주소에는 두 종류가 있다.

 

IP 주소

IP 주소는 폐쇄된 네트워크이거나 IP를 공유하는 경우가 아니라면 전 세계적으로 유일한 값을 가진다.

  • IPv4 : 32비트를 사용하며 8비트 단위로 .(dot)으로 구분하며 10진수 네 개로 표기한다. ex) 147.46.114.70
  • IPv6 : 128비트를 사용하며 16비트 단위로 :(colon)으로 구분하며 16진수 8개로 표기한다.                                         ex) 2001:0230:abcd:ffab:0023:eb00:ffff:1111

숫자로 이루어진 IP 주소는 기억하기 어렵기 때문에 'www.suengho.com'과 같은 도메인 이름을 사용하는 경우가 많다. 도메인 이름은 IP 주소에 대한 별명에 불과하기 때문에 실제 통신할 때는 IP 주소로 변환해야 한다.

 

포트 번호

IP 주소는 인터넷에 있는 호스트를 구별할 수 있지만 통신의 최종 주체인 프로세스는 식별하지 못한다. 따라서 16 비트의 포트 번호를 사용한다. 

한 프로세스가 두 개 이상의 포트 번호를 사용하거나 둘 이상의 프로세스가 한 포트 번호를 사용할 수 있기 때문에 포트 번호는 프로세스를 구별하는 번호라기 보다는 인터넷 통신의 종착점(하나 이상의 여러 프로세스)을 나타내는 식별자이다.

TCP와 UDP는 부호 없는 16비트 정수를 포트 번호로 사용하여 0~65535 범위이지만 영역별로 포트 번호가 나뉘어져 있다.

영역별 포트 번호

알려진 포트는 용도가 정해져 있으므로 함부로 사용하면 안되고 일반적으로 응용 서버를 작성할 경우 등록된 포트 범위에서 하나 또는 일부를 선택하여 사용한다.


통상적으로 네트워크 프로그램은 클라이언트-서버 모델(Client-Server Model)로 작성한다. 클라이언트-서버 모델은 두 프로그램이 상호 작용하는 방식을 나타내는 용어로 서비스를 요청하는 쪽은 클라이언트(Client), 클라이언트가 요청한 서비스를 처리하는 쪽이 서버(Server)이다.

 

한 컴퓨터에서 두 프로그램을 실행할 때의 데이터 교환에는 프로세스 간 통신 기법을 사용할 수 있지만 네트워크로 연결된 컴퓨터의 두 프로그램에 적용할 때는 반드시 통신 프로토콜을 사용해야 데이터를 주고 받을 수 있다.

 

  •  동시 접속 : 서로 다른 호스트에서 실행되는 두 프로그램이 상호 접속하는 경우로 접속의 성공을 위해 반드시 상대 프로그램이 실행 중이어야 하며 타이밍 문제로 인해 실패 확률이 높아진다.
  • 서버와 클라이언트 : 한 프로세스가 먼저 실행하여 대기하고 다른 프로세스가 나중에 실행한다. 클라이언트-서버 모델로 동시 접속 문제가 해결된다. 먼저 실행하는 쪽이 서버, 나중이 클라이언트이다. 

클라이언트가 서버에 접속하기 위해서는 서버의 IP 주소 또는 도메인 이름과 포트 번호를 알아야 하지만 서버는 클라이언트의 주소를 미리 알 필요 없다. 클라이언트가 보낸 패킷에는 클라이언트의 주소 정보가 모두 들어 있기 때문에 서버는 언제든 클라이언트에게 데이터를 보낼 수 있다.


02 소켓의 개념

네트워크 통신을 위해서는 다양한 계층의 협력이 필요하지만 네트워크 프로그램을 제작하는 데 모든 분야의 지식이 필요한 것은 아니다. 예를 들어 TV, 컴퓨터 등의 전자 제품의 내부 회로는 알지 못하더라도 벽에 붙은 소켓에 전원 코드를 꽂고 버튼만 누르면 사용할 수 있는 것처럼 네트워크 프로그램 역시 통신 내부 처리 과정을 알지 못해도 데이터를 초기화하고 정해진 절차에 따라 함수를 호출하는 작업만으로 만들 수 있다.

 

사람을 응용프로그램, 전화를 소켓으로 비유한다.

전화기에 말을 하면 상대방의 전화기에서 들리듯, 소켓에 넣은 데이터는 상대편 소켓을 통해 빠져나온다.

 

소켓이 포트 번호 + IP 주소로 이뤄져 있다.

세부적으로, 내선 번호를 포트 번호, 대표 전화를 IP 주소라 비유한다면, 학교에 전화하였을 때, 대표 학교 번호가 IP 주소이고 학교 내 게임공학과 사무실 전화 번호가 포트 번호에 해당하며 포트 번호 + IP 주소가 소켓에 해당한다. 

다음으로 소켓이라는 용어의 의미를 세 가지 관점에서 살펴보도록 한다.


데이터 타입

소켓은 프로그래밍 관점에서 데이터 타입으로 볼 수 있으며, 윈도우 프로그래밍에서 사용되는 핸들(Handle) 혹은 파일 디스크립터와 유사한 개념이다. 

파일 입출력 코드와 소켓 통신 코드 비교

응용 프로그램 통신을 위해서는 사용할 프로토콜, 송수신 측 IP주소, 송수신 측 포트 번호 등과 같은 요소가 결정되어야 하는데 이 정보는 운영체제 내부적으로 관리하며, 응용 프로그램은 소켓을 사용해 이 정보에 접근할 수 있다. 

생성과 설정 과정이 끝나면 운영체제의 통신 관련 정보를 참조해 다양한 작업을 편리하게 할 수 있다.


통신 종단점

소켓은 응용 프로그램 관점에서 통신 종단점, 즉 통신의 출발점과 도착점이라고 볼 수 있다.

위 그림은 클라이언트가 서버에 데이터를 보내는 경우이다. 클라이언트는 자신의 소켓이 서버 소켓과 연결된 것으로 생각하고 send 함수를 호출하여 데이터를 보내며 서버는 recv 함수를 호출하여 데이터를 받는다.


네트워크 프로그래밍 인터페이스

소켓은 TCP/IP 프로토콜의 관점에서 네트워크 프로그래밍 인터페이스에 불과하다. 때문에 응용 프로그램이 통신을 위해 양쪽 모두 소켓을 사용할 필요는 없다. 둘 다 같은 프로토콜을 사용하고 정해진 형식과 절차로 데이터를 주고 받으면 된다.

 

소켓은 응용 프로그램 관점에서 TCP/IP 프로토콜 구조의 응용 계층과 전송 계층 사이의 인터페이스로 간주한다. 소켓 인터페이스를 사용하여 TCP나 UDP 프로토콜에 접근할 수 있다.


03 소켓의 특징 및 구조

소켓의 특징

  • 윈도우 소켓(윈속) : 버클리 유닉스에서 개발한 네트워크 프로그래밍 인터페이스를 윈도우 환경에서 사용할 수 있게 만든 것으로 윈도우 95 버전부터 API에 정식으로 포함하여 제공한다.

윈도우 버전별로 지원하는 윈속 버전

윈속에서 지원하는 통신 프로토콜로는 IPv4(윈도우 95 이상), IPv6(윈도우 XP SP1 이상), Bluetooth(윈도우 XP SP2 이상), IrDA 적외선 통신(윈도우 98 이상)등이 있다.

  • 윈속의 장점 : 기존 코드 이식이 쉽고 한번 배워두면 여러 운영체제에서 사용할 수 있으며 다른 프로토콜도 지원하여 최소 코드 수정으로 통신에 사용되는 프로토콜을 응용 프로그램이 변경할 수 있다.
  • 윈속의 단점 : 응용 프로그램 수준의 프로토콜을 프로그래머가 직접 설계해야 한다. 주고 받는 데이터 형식 또는 전송 절차 등을 직접 프로그래밍 해야 하며 설계 변경 시 코드를 수정해야 한다. 그리고 서로 다른 바이트 정렬 방식을 사용하거나 데이터 처리 단위가 서로 다른 호스트끼리 통신한다면, 응용 프로그램 수준에서 데이터 변환을 해야 한다.
  •  

소켓의 구조

윈속이 지원하는 대부분의 기능은 WS2_32.DLL로 제공되며, 표준 윈속 API 외에 MS에서 확장한 API MSWSOCK.DLL도 존재한다. WS2_32.DLL은 응용 프로그램이 실제 사용할 하부 프로토콜을 선택하여 연결해준다.


04 소켓 프로그램 찍먹

TCP 클라이언트가 보낸 데이터를 그대로 화면에 출력하는 TCP 서버를 구현한 예제를 텔넷 클라이언트로 테스트한다.

윈도우 운영체제에 기본으로 내장된 텔넷 클라이언트를 사용하기 위해 cmd 창을 실행한 것이다.

 

 

GitHub - promche/TCP-IP-Socket-Prog-Book-2nd: TCP/IP 소켓 프로그래밍 2판(한빛아카데미, 2022) 예제 코드입니

TCP/IP 소켓 프로그래밍 2판(한빛아카데미, 2022) 예제 코드입니다. Contribute to promche/TCP-IP-Socket-Prog-Book-2nd development by creating an account on GitHub.

github.com

위 사이트에서 예제를 다운받아 .cpp 파일을 그대로 복사하여 자신의 프로젝트에 붙여 넣기 하여 실행하면 된다.

 

접속 전 텔넷 클라이언트와 서버
접속 후 텔넷 클라이언트와 서버

위 결과와 같이 텔넷 클라이언트에서 글자를 입력하면 입력한 글자는 네트워크로 전송되어 서버 화면에 표시된다. 서버 화면에는 클라이언트의 IP 주소와 포트 번호가 출력되며 클라이언트 종료는 Ctrl + ] 을 누른 후 quit를 입력하면 된다.

 

※ 릴리즈 모드로 프로그래밍 하자

디버그 모드에서 컴파일 하기 위해서는 비쥬얼 스튜디오가 있어야만 테스트할 수 있다. 그러나 네트워크 프로그램은 다양한 호스트 환경에서 테스트를 할 수 있어야 한다. 디버그 모드에선 무겁고 시간이 많이 걸리기 때문에 릴리즈 모드를 사용해야 한다. 똑같은 코드를 릴리즈 모드로 돌렸을때 문제 없이 돌아가는 경우가 있다. 디버그 모드에서 잘 돌아가지 않는 경우가 있다. 이런 시간을 줄이기 위해 릴리즈 모드로 돌려야 한다.

'네트워크 프로그래밍' 카테고리의 다른 글

[멀티스레드]  (0) 2023.10.11
[데이터 전송하기]  (0) 2023.09.27
[TCP 서버-클라이언트]  (0) 2023.09.26
[소켓 주소 구조체]  (0) 2023.09.12
[소켓 시작하기]  (0) 2023.09.10