본문 바로가기
-----ETC-----/C++ 네트워크 프로그래밍 시리즈

[C++ 네트워크 프로그래밍 ] Day 1: 네트워크 프로그래밍 소개와 개발 환경 설정

by cogito21_cpp 2024. 8. 1.
반응형

네트워크 프로그래밍 소개

네트워크 프로그래밍은 컴퓨터 네트워크를 통해 데이터를 송수신하는 소프트웨어를 작성하는 기술입니다. 이를 통해 두 개 이상의 컴퓨터가 데이터를 주고받을 수 있습니다. 네트워크 프로그래밍의 기본 단위는 소켓(socket)입니다.

 

네트워크 프로그래밍의 주요 개념

클라이언트-서버 모델

  • 클라이언트: 네트워크에서 서비스를 요청하는 역할입니다. 예를 들어, 웹 브라우저가 웹 서버에 페이지를 요청합니다.
  • 서버: 네트워크에서 서비스를 제공하는 역할입니다. 웹 서버는 클라이언트의 요청에 따라 웹 페이지를 제공합니다.

프로토콜

  • 프로토콜은 데이터를 어떻게 형식화하고 송수신할지 정의하는 규칙입니다. 대표적인 프로토콜에는 TCP/IP, HTTP, FTP 등이 있습니다.
  • TCP (Transmission Control Protocol): 신뢰성 있는 데이터 전송을 보장하는 프로토콜입니다. 연결 지향적이며, 데이터의 순서와 무결성을 보장합니다.
  • UDP (User Datagram Protocol): 빠른 데이터 전송을 위한 프로토콜입니다. 비연결 지향적이며, 데이터의 순서와 무결성을 보장하지 않습니다.

소켓

  • 소켓은 네트워크 통신의 끝점을 나타내는 추상화된 개념입니다. 소켓을 통해 데이터를 송수신합니다.
  • IP 주소포트 번호로 소켓을 식별합니다.
    • IP 주소: 네트워크 상에서 장치의 위치를 나타내는 고유한 주소입니다.
    • 포트 번호: 특정 프로세스를 식별하기 위해 사용됩니다.

개발 환경 설정

네트워크 프로그래밍을 위해 필요한 개발 환경을 설정합니다. C++ 컴파일러와 네트워크 라이브러리를 설치하고 설정하는 과정을 다룹니다.

C++ 컴파일러 설치

  • Windows: Visual Studio를 설치합니다.
  • MacOS: Xcode를 설치합니다.
  • Linux: GCC를 설치합니다.

네트워크 라이브러리 설치

C++ 네트워크 프로그래밍에 유용한 라이브러리를 설치합니다.

  • Boost.Asio: 비동기 네트워크 프로그래밍을 지원하는 Boost 라이브러리의 모듈입니다.
  • libcurl: HTTP 클라이언트를 쉽게 개발할 수 있는 라이브러리입니다.

Boost.Asio 설치

Boost.Asio는 C++로 네트워크 프로그래밍을 할 때 많이 사용하는 라이브러리입니다. 비동기 I/O 작업을 쉽게 구현할 수 있습니다.

  1. Boost 라이브러리 다운로드
  2. Boost 라이브러리 설치
    • Windows:
      • 다운로드한 압축 파일을 해제하고, Boost 라이브러리 폴더로 이동합니다.
      • bootstrap.bat 파일을 실행하여 빌드 시스템을 설정합니다.
      • b2.exe 파일을 실행하여 필요한 모듈을 빌드합니다.
    • MacOS/Linux:
      • 다운로드한 압축 파일을 해제하고, Boost 라이브러리 폴더로 이동합니다.
      • bootstrap.sh 스크립트를 실행하여 빌드 시스템을 설정합니다.
      • ./b2 명령어를 실행하여 필요한 모듈을 빌드합니다.

libcurl 설치

libcurl은 HTTP 및 기타 프로토콜을 사용하여 데이터를 전송할 수 있는 라이브러리입니다.

  1. libcurl 다운로드
  2. libcurl 설치
    • Windows:
      • 다운로드한 바이너리 패키지를 설치합니다.
    • MacOS:
      • Homebrew를 사용하여 설치합니다: brew install curl
    • Linux:
      • 패키지 관리자를 사용하여 설치합니다: sudo apt-get install libcurl4-openssl-dev (Debian/Ubuntu 기반)

간단한 네트워크 프로그램 작성

네트워크 프로그래밍의 기본을 이해하기 위해 간단한 TCP 클라이언트-서버 프로그램을 작성해보겠습니다.

 

TCP 서버

#include <iostream>
#include <boost/asio.hpp>

using boost::asio::ip::tcp;

int main() {
    try {
        boost::asio::io_context io_context;

        tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v4(), 12345));

        std::cout << "Server is listening on port 12345..." << std::endl;

        while (true) {
            tcp::socket socket(io_context);
            acceptor.accept(socket);

            std::string message = "Hello from server!";
            boost::system::error_code ignored_error;
            boost::asio::write(socket, boost::asio::buffer(message), ignored_error);
        }
    } catch (std::exception& e) {
        std::cerr << "Exception: " << e.what() << std::endl;
    }

    return 0;
}

 

TCP 클라이언트

#include <iostream>
#include <boost/asio.hpp>

using boost::asio::ip::tcp;

int main() {
    try {
        boost::asio::io_context io_context;

        tcp::resolver resolver(io_context);
        tcp::resolver::results_type endpoints = resolver.resolve("127.0.0.1", "12345");

        tcp::socket socket(io_context);
        boost::asio::connect(socket, endpoints);

        for (;;) {
            boost::asio::streambuf buf;
            boost::asio::read_until(socket, buf, "\n");

            std::istream is(&buf);
            std::string message;
            std::getline(is, message);
            std::cout << "Received: " << message << std::endl;
        }
    } catch (std::exception& e) {
        std::cerr << "Exception: " << e.what() << std::endl;
    }

    return 0;
}

 

실습 문제

문제 1: 간단한 에코 서버와 클라이언트 작성하기

TCP 에코 서버와 클라이언트를 작성하여, 클라이언트가 보낸 메시지를 서버가 다시 클라이언트에게 보내도록 구현하세요.

 

해설:

TCP 에코 서버

#include <iostream>
#include <boost/asio.hpp>

using boost::asio::ip::tcp;

int main() {
    try {
        boost::asio::io_context io_context;

        tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v4(), 12345));

        std::cout << "Server is listening on port 12345..." << std::endl;

        while (true) {
            tcp::socket socket(io_context);
            acceptor.accept(socket);

            boost::asio::streambuf buf;
            boost::asio::read_until(socket, buf, "\n");

            std::istream is(&buf);
            std::string message;
            std::getline(is, message);
            std::cout << "Received: " << message << std::endl;

            boost::asio::write(socket, boost::asio::buffer(message + "\n"));
        }
    } catch (std::exception& e) {
        std::cerr << "Exception: " << e.what() << std::endl;
    }

    return 0;
}

 

TCP 에코 클라이언트

#include <iostream>
#include <boost/asio.hpp>

using boost::asio::ip::tcp;

int main() {
    try {
        boost::asio::io_context io_context;

        tcp::resolver resolver(io_context);
        tcp::resolver::results_type endpoints = resolver.resolve("127.0.0.1", "12345");

        tcp::socket socket(io_context);
        boost::asio::connect(socket, endpoints);

        std::string message;
        while (std::getline(std::cin, message)) {
            message += "\n";
            boost::asio::write(socket, boost::asio::buffer(message));

            boost::asio::streambuf buf;
            boost::asio::read_until(socket, buf, "\n");

            std::istream is(&buf);
            std::string reply;
            std::getline(is, reply);
            std::cout << "Reply: " << reply << std::endl;
        }
    } catch (std::exception& e) {
        std::cerr << "Exception: " << e.what() << std::endl;
    }

    return 0;
}

 

이제 첫 번째 날의 학습을 마쳤습니다. 네트워크 프로그래밍의 기본 개념과 간단한 TCP 서버와 클라이언트를 작성해보았습니다.

질문이나 피드백이 있으면 언제든지 댓글로 남겨 주세요. 내일은 "소켓 프로그래밍 기초 (TCP)"에 대해 학습하겠습니다.

반응형