boost::asioでUDP/IP通信

C++UDP/IP通信をやろう!

って思って、 http://www.geekpage.jp/programming/winsock/udp.php とか
http://www.geekpage.jp/programming/linux-network/udp.php とか
を見ながらシステムコールを実装してたんだけど、よく調べてみたらboostでもUDP/IPあつかえるじゃないか!

そういうことで簡単なメモ

まずは受信

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

using boost::asio::ip::udp;

int main(int argc, char* argv)
{
	try {
		boost::asio::io_service io_service;
		udp::socket socket(io_service, udp::endpoint(udp::v4(), 12345));

		boost::array<char,2048> recv_buf;
		udp::endpoint remote_endpoint;
		boost::system::error_code error;
		size_t len = socket.receive_from(boost::asio::buffer(recv_buf), remote_endpoint, 0, error);
		std::cout.write(recv_buf.data(), len);
	} catch (std::exception& e) {
		std::cerr << e.what() << std::endl;
	}
}


次に送信

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

using boost::asio::ip::udp;

int main(int argc, char* argv)
{
	try {
		boost::asio::io_service io_service;
		udp::resolver resolver(io_service);
		udp::resolver::query query(udp::v4(), "localhost", "12345");
		udp::endpoint receiver_endpoint = *resolver.resolve(query);

		udp::socket socket(io_service);
		socket.open(udp::v4());

		std::string str = "HELLO";
		socket.send_to(boost::asio::buffer(str), receiver_endpoint);
	} catch (std::exception& e) {
		std::cerr << e.what() << std::endl;
	}
}


非同期もできる。

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

using boost::asio::ip::udp;

boost::array<char,2048> recv_buf;
void receive(const boost::system::error_code&, std::size_t len)
{
	std::cout.write(recv_buf.data(), len);
}

int main(int argc, char* argv)
{
	try {
		boost::asio::io_service io_service;
		udp::socket socket(io_service, udp::endpoint(udp::v4(), 12345));

		udp::endpoint remote_endpoint;
		boost::system::error_code error;
		socket.async_receive_from(
			boost::asio::buffer(recv_buf), remote_endpoint, &receive);
		io_service.run();
	} catch (std::exception& e) {
		std::cerr << e.what() << std::endl;
	}
}

これでマルチプラットフォームで動かせるってすごいね。
asioはシリアルポートにも対応しているみたい。知らずにAPI直接叩いて自作してたよ・・・後でこっちも試してみる。

参考: http://www.boost.org/doc/libs/1_48_0/doc/html/boost_asio.html