소켓 통신/Boost

Boost.asio 능동/수동 소켓 만들기

마달랭 2024. 11. 7. 21:49

개요

TCP/IP 표준에서는 소켓을 언급하지 않는다, API를 어떻게 구현해야 하는지에 대해서도 나와 있지 않다.

따라서 TCP 프로토콜 소프트웨어를 개발하는 모든 개발자는 자신만의 프로토콜 구현용 인터페이스를 마음대로 만들 수 있다. (UDP 프로토콜도 동일하다.)

 

가장 널리 사용되는 TCP/UDP 프로토콜 API는 버클리 소켓이다.

버클리 소켓 API는 통신 세션 문맥을 나타내는 소켓을 중심에 둔 디자인이다.

어떠한 네트워크 I/O 연산이든, 시작하기 전에 소켓 객체를 할당해야 하고, 그런 다음 소켓과 개별 I/O 연산을 해야한다.

 

Boost.asio는 버클리 소켓 API에서 많은 개념을 빌려왔다.

 

 

능동 소켓

원격 어플리케이션으로 데이터를 보내고 받거나 연결 수립 과정을 시작하는데 사용하는 소켓

 

  1. asio::io_service 클래스의 인스턴스를 생성한다.
  2. 이 소켓이 통신하려 하는 TCP나 UDP와 IP 프로토콜의 버전을 나타내는 클래스의 객체를 생성한다.
  3. 필요한 프로토콜형에 맞는 소켓을 나타내는 객체를 1번에 만든 인스턴스를 생성자로 전달하여 생성한다.
  4. 소켓의 open() 메서드를 호출하며, 2번에서 만들어준 프로토콜 객체를 인자로 전달한다.

 

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

using namespace boost;

int main()
{
	// Step 1. io_service 클래스의 인스턴스 생성
	asio::io_service ios;

	// Step 2. tcp, IPv4 프로토콜 객체 생성
	asio::ip::tcp protocol = asio::ip::tcp::v4();

	// Step 3. 능동 TCP 소켓 인스턴스화
	asio::ip::tcp::socket sock(ios);

	// 오류 정보 처리용
	boost::system::error_code ec;

	// Step 4. 소켓을 연다.
	sock.open(protocol, ec);

	if (ec.value() != 0) {
		// 오류 발생 시
		std::cout
			<< "Failed to open the socket! Error code = "
			<< ec.value() << ". Message: " << ec.message();
		return ec.value();
	}

	return 0;
}

 

 

수동 소켓

원격 어플리케이션에서 들어오는 연결 요청을 수동적으로 기다리는 소켓

  • 수동 소켓은 서버 프로그램 또는 서버와 클라이언트 역할 모두를 실행하는 복합 프로그램에서만 사용된다.
  • 수동 소켓은 TCP 프로토콜에서만 사용된다. UDP 프로토콜은 연결 수립을 하지 않기 때문에 수동 소켓이 필요 없다.

Boost.asio에서 수동 소켓은 asio::ip::tcp::acceptor 클래스이다.

이름에서 알 수 있듯이, 들어오는 연결 요청을 받아들이고 처리하는 것이다.

 

  1. asio::io_service 클래스의 인스턴스를 생성한다.
  2. TCP 프로토콜과 IP 프로토콜의 버전을 나타내는 클래스 객체를 생성한다.
  3. asio::ip::tcp::acceptor 클래스에 1번에서 생성한 인스턴스를 생성자로 전달해 객체를 생성한다.
  4. 2번에서 만들어준 프로토콜의 객체를 인자로 전달하여 소켓의 open() 메서드를 호출한다
#include <boost/asio.hpp>
#include <iostream>

using namespace boost;

int main()
{
	// Step 1. io_service 클래스 인스턴스 생성
	asio::io_service ios;

	// Step 2. TCP, IPv4 프로토콜 객체 생성
	asio::ip::tcp protocol = asio::ip::tcp::v4();

	// Step 3. 수동 소켓 인스턴스화.
	asio::ip::tcp::acceptor acceptor(ios);

	// 오류 정보 처리용
	boost::system::error_code ec;

	// Step 4. 수동 소켓을 연다.
	acceptor.open(protocol, ec);

	if (ec.value() != 0) {
		// 오류 발생 시
		std::cout
			<< "Failed to open the acceptor socket!"
			<< "Error code = "
			<< ec.value() << ". Message: " << ec.message();
		return ec.value();
	}

	return 0;
}

 

 

asio:io_service

Boost.asio I/O 구조의 핵심, 이 클래스를 통해 운영체제가 제공하는 네트워크 I/O 서비스로 접근이 가능하다.

Boost.asio 소켓은 이 클래스의 객체를 통해야만 네트워크 서비스를 사용할 수 있다.

따라서 모든 소켓 클래스 생성자는 asio::io_service 클래스의 객체를 인자로 받는다.

 

 

asio::ip::tcp

  • asio::ip::tcp.v4() : IPv4를 사용하는 TCP 프로토콜을 나타내는 객체 반환
  • asio::ip::tcp.v6() : IPv6 상동
  • asio::ip::tcp::socket : 소켓을 생성한다, open() 메서드를 호출할 때 실제 운영체제의 소켓이 할당된다.
  • asio::ip::tcp::acceptor : 수동 소켓을 생성한다, 이하 상동

 

Boost.asio에서 소켓을 연다는 것은 통신할 때 사용할 소켓에 앞으로 사용할 프로토콜을 가르키는 파라미터 집합을 연결시킨다는 뜻이다.

 

 

728x90

'소켓 통신 > Boost' 카테고리의 다른 글

Boost.asio 소켓 연결 수락  (0) 2024.11.07
Boost.asio 소켓 연결 요청  (2) 2024.11.07
Boost.asio 소켓 바인딩  (0) 2024.11.07
Boost.asio DNS 이름 해석하기  (1) 2024.11.07
Boost.asio 종료점 만들기  (0) 2024.11.07