boostライブラリが動作(39)ネットワークUDP非同期サービス端の9
2761 ワード
先に作成したUDPサーバとクライアントは,いずれも同期方式であり,つまりデータを受信すると,他のことに関与して実行できない.インタフェーススレッドのみのプログラムで、マルチスレッドを作成したくない場合、複雑さが増す場合、非同期のUDPサーバやクライアントを作成する方法もあります.これにより、単一スレッドの単純性もあれば、インタフェースの迅速な応答の特性を任意に操作することができます.boostライブラリでio_を使用サービスオブジェクトが非同期を実現するのは容易であり,パッケージのインタフェースが簡単で明瞭であるためである.具体的なコードは以下の通りです.
この例では、io_を採用したサーバUdpTimeServerを主にカプセル化しています.サービスオブジェクトとsocketオブジェクトの非同期特性を構築し、イベント応答があってから対応する操作を実行しますが、これは前の同期方式よりも複雑ですが、マルチスレッド間の同期問題を回避します.
// boost_028.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <ctime>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/array.hpp>
#include <iostream>
#include <string>
// UDP
using boost::asio::ip::udp;
// 。
std::string make_daytime_string()
{
using namespace std; // time_t, time ctime;
time_t now = time(0);
return ctime(&now);
}
//
// UDP 。
// : 2013-08-25
//QQ: 9073204
//
class UdpTimeServer
{
public:
// IO , UDP SOCKET,IPV4 , 13
UdpTimeServer(boost::asio::io_service& ioService)
:m_sockUdp(ioService, udp::endpoint(udp::v4(), 13))
{
// 。
RecvTime();
}
private:
// 。
void RecvTime(void)
{
//
m_sockUdp.async_receive_from(
boost::asio::buffer(m_recvBuf), m_endpointRemote,
boost::bind(&UdpTimeServer::handleRecvTime, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
// ,
void handleRecvTime(const boost::system::error_code& error,
std::size_t /*bytes_transferred*/)
{
// , 。
if (!error || error == boost::asio::error::message_size)
{
boost::shared_ptr<std::string> strMessage(
new std::string(make_daytime_string()));
m_sockUdp.async_send_to(boost::asio::buffer(*strMessage), m_endpointRemote,
boost::bind(&UdpTimeServer::handleSendTime, this, strMessage,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
// 。
RecvTime();
}
}
// 。
void handleSendTime(boost::shared_ptr<std::string> /*strMessage*/,
const boost::system::error_code& /*error*/,
std::size_t /*bytes_transferred*/)
{
}
private:
udp::socket m_sockUdp; // SOCKET。
udp::endpoint m_endpointRemote; // 。
boost::array<char, 1> m_recvBuf; // 。
};
void TestUdp(void)
{
boost::asio::io_service ioService;
UdpTimeServer udpTimeServer(ioService);
ioService.run();
}
int _tmain(int argc, _TCHAR* argv[])
{
//
TestUdp();
return 0;
}
この例では、io_を採用したサーバUdpTimeServerを主にカプセル化しています.サービスオブジェクトとsocketオブジェクトの非同期特性を構築し、イベント応答があってから対応する操作を実行しますが、これは前の同期方式よりも複雑ですが、マルチスレッド間の同期問題を回避します.