반응형
네트워크 프로그래밍 소개
네트워크 프로그래밍은 컴퓨터 네트워크를 통해 데이터를 송수신하는 소프트웨어를 작성하는 기술입니다. 이를 통해 두 개 이상의 컴퓨터가 데이터를 주고받을 수 있습니다. 네트워크 프로그래밍의 기본 단위는 소켓(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 작업을 쉽게 구현할 수 있습니다.
- Boost 라이브러리 다운로드
- Boost 공식 웹사이트(https://www.boost.org)에서 최신 버전을 다운로드합니다.
- Boost 라이브러리 설치
- Windows:
- 다운로드한 압축 파일을 해제하고, Boost 라이브러리 폴더로 이동합니다.
bootstrap.bat
파일을 실행하여 빌드 시스템을 설정합니다.b2.exe
파일을 실행하여 필요한 모듈을 빌드합니다.
- MacOS/Linux:
- 다운로드한 압축 파일을 해제하고, Boost 라이브러리 폴더로 이동합니다.
bootstrap.sh
스크립트를 실행하여 빌드 시스템을 설정합니다../b2
명령어를 실행하여 필요한 모듈을 빌드합니다.
- Windows:
libcurl 설치
libcurl은 HTTP 및 기타 프로토콜을 사용하여 데이터를 전송할 수 있는 라이브러리입니다.
- libcurl 다운로드
- libcurl 공식 웹사이트(https://curl.se/libcurl/)에서 최신 버전을 다운로드합니다.
- libcurl 설치
- Windows:
- 다운로드한 바이너리 패키지를 설치합니다.
- MacOS:
- Homebrew를 사용하여 설치합니다:
brew install curl
- Homebrew를 사용하여 설치합니다:
- Linux:
- 패키지 관리자를 사용하여 설치합니다:
sudo apt-get install libcurl4-openssl-dev
(Debian/Ubuntu 기반)
- 패키지 관리자를 사용하여 설치합니다:
- Windows:
간단한 네트워크 프로그램 작성
네트워크 프로그래밍의 기본을 이해하기 위해 간단한 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)"에 대해 학습하겠습니다.
반응형
'-----ETC----- > C++ 네트워크 프로그래밍 시리즈' 카테고리의 다른 글
[C++ 네트워크 프로그래밍] Day 6: 네트워크 프로토콜 기초 (0) | 2024.08.01 |
---|---|
[C++ 네트워크 프로그래밍] Day 3: 소켓 프로그래밍 기초 (UDP) (0) | 2024.08.01 |
[C++ 네트워크 프로그래밍] Day 4: 비동기 소켓 프로그래밍 (0) | 2024.08.01 |
[C++ 네트워크 프로그래밍] Day 2: 소켓 프로그래밍 기초 (TCP) (0) | 2024.08.01 |
[C++ 네트워크 프로그래밍] 목차 (0) | 2024.06.20 |