Boost C++ Libraries/Boost.Asio

Boost.Asio 개요 - 네트워킹 - TCP, UDP 및 ICMP

까마귀75 2020. 12. 10. 14:36
728x90
반응형

TCP, UDP 및 ICMP (TCP, UDP and ICMP)

Boost.Asio는 인터넷 프로토콜인 TCP, UDPICMP등 기성 프로토콜에 대한 지원을 제공한다.

TCP 클라이언트

호스트 이름 확인은 리졸버(resolver)를 사용해 수행된다. 여기서 호스트와 서비스 이름이 조회되고 하나 이상의 엔드포인트(endpoint)로 변환된다:

ip::tcp::resolver resolver(my_io_context);
ip::tcp::resolver::query query("www.boost.org", "http");
ip::tcp::resolver::iterator iter = resolver.resolve(query);
ip::tcp::resolver::iterator end; // End marker.
while (iter != end)
{
  ip::tcp::endpoint endpoint = *iter++;
  std::cout << endpoint << std::endl;
}

 

위에서 얻은 엔드포인트 목록에는 IPv4IPv6 엔드포인트가 모두 포함될 수 있으므로, 프로그램은 작동하는 엔드포인트를 찾을 때까지 각각을 시도해야 한다. 이렇게 하면 클라이언트 프로그램이 특정 IP 버전과 독립적으로 유지된다.

 

프로토콜에 독립적인 프로그램의 개발을 단순화하기 위해, TCP 클라이언트는 사용가능한 함수인 connect()async_connect()를 사용하여 연결을 설정할 수 있다. 이러한 작업은 소켓이 성공적으로 연결될 때까지 목록의 각 엔드포인트에 대해 시도한다. 예를 들어, 단일 호출이면 :

ip::tcp::socket socket(my_io_context);
boost::asio::connect(socket, resolver.resolve(query));

 

성공적으로 연결될 때까지 모든 엔드포인트를 동기식으로 시도한다. 마찬가지로 비동기식 연결은 다음과 같이 작성하여 수행할 수 있다:

boost::asio::async_connect(socket_, iter,
    boost::bind(&client::handle_connect, this,
      boost::asio::placeholders::error));

// ...

void handle_connect(const error_code& error)
{
  if (!error)
  {
    // Start read or write operations.
  }
  else
  {
    // Handle error.
  }
}

 

특정 엔드포인트를 사용할 수 있으면 소켓을 생성하고 연결할 수 있다:

ip::tcp::socket socket(my_io_context);
socket.connect(endpoint);

 

receive(), async_receive(), send() 또는 async_send() 멤버 함수를 사용하여 연결된 TCP 소켓에서 데이터를 읽거나 쓸 수 있다. 그러나 이로 인해 짧은 읽기와 짧은 쓰기(Streams, Short Reads and Short Writes)가 발생할 수 있으며, 응용프로그램은 일반적으로 read(), async_read(), write() 또는 async_write() 함수를 대신 사용한다.

TCP 서버

프로그램은 들어온 TCP 연결을 받아들이기 위해 승인기(acceptor)를 사용한다:

ip::tcp::acceptor acceptor(my_io_context, my_endpoint);
...
ip::tcp::socket socket(my_io_context);
acceptor.accept(socket);

 

소켓이 성공적으로 승인되면, 위에 TCP 클라이언트에 대한 설명처럼 소켓을 읽거나 쓸 수 있다.

UDP

UDP 호스트 이름 확인도 리졸버(resolver)를 사용하여 수행된다:

ip::udp::resolver resolver(my_io_context);
ip::udp::resolver::query query("localhost", "daytime");
ip::udp::resolver::iterator iter = resolver.resolve(query);
...

 

UDP 소켓은 일반적으로 로컬 엔드포인트에 바인딩된다. 다음 코드는 IP 버전 4 UDP 소켓을 만들고 포트 12345의 "any(모든)" 주소에 바인딩한다:

ip::udp::endpoint endpoint(ip::udp::v4(), 12345);
ip::udp::socket socket(my_io_context, endpoint);

 

receive_from(), aync_receive_from(), send_to() 또는 async_send_to() 멤버 함수를 사용하여 연결되지 않은 UDP 소켓에서 데이터를 읽거나 쓸 수 있다. 연결된 UDP 소켓에서는 receive(), aync_receive(), send() 또는 async_send() 멤버 함수를 사용한다.

ICMP

TCPUDP와 마찬가지로, ICMP 호스트 이름 확인은 리졸버(resolver)를 사용하여 수행된다.

ip::icmp::resolver resolver(my_io_context);
ip::icmp::resolver::query query("localhost", "");
ip::icmp::resolver::iterator iter = resolver.resolve(query);
...

 

ICMP 소켓은 로컬 엔드포인트에 바인딩될 수 있다. 다음 코드는 IP 버전 6 ICMP 소켓을 만들고 "any(모든)" 주소에 바인딩한다:

ip::icmp::endpoint endpoint(ip::icmp::v6(), 0);
ip::icmp::socket socket(my_io_context, endpoint);

 

포트 번호는 ICMP에서 사용되지 않는다.

 

receive_from(), async_receive_from(), send_to() 또는 async_send_to() 멤버 함수를 사용하여 연결되지 않은 ICMP 소켓에서 데이터를 읽거나 쓸 수 있다.

더 보기

ip::tcp, ip::udp, ip::icmp, daytime protocol tutorials, ICMP ping example.

 

 

네트워킹  Boost.Asio 개요  Boost.Asio 홈

728x90
반응형