TCP, UDP 및 ICMP (TCP, UDP and ICMP)
Boost.Asio는 인터넷 프로토콜인 TCP, UDP 및 ICMP등 기성 프로토콜에 대한 지원을 제공한다.
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; }
위에서 얻은 엔드포인트 목록에는 IPv4와 IPv6 엔드포인트가 모두 포함될 수 있으므로, 프로그램은 작동하는 엔드포인트를 찾을 때까지 각각을 시도해야 한다. 이렇게 하면 클라이언트 프로그램이 특정 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
TCP 및 UDP와 마찬가지로, 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 C++ Libraries > Boost.Asio' 카테고리의 다른 글
Boost.Asio 개요 - 네트워킹 - 소켓 Iostreams (0) | 2020.12.11 |
---|---|
Boost.Asio 개요 - 네트워킹 - 기타 프로토콜 지원 (0) | 2020.12.10 |
Boost.Asio 개요 - 네트워킹 (0) | 2020.12.10 |
Boost.Asio 개요 - 핵심 개념 및 기능 - 코-루틴 TS 지원 (0) | 2020.12.10 |
Boost.Asio 개요 - 핵심 개념 및 기능 - 스택형 코-루틴 (0) | 2020.12.10 |