前面创建的UDP服务器和客户端,都是同步的方式,也就是说当接收数据时,不能参与别的事情执行的。如果在一个只有界面线程的程序里,又不想创建多线程,导致复杂程度的增加,在这种情况之下,我们还有一个方案可以选择,就是创建一个异步的UDP服务器或客户端,这样既有单线程的简单性,也可以让客户随便操作界面的快速响应的特性。在boost库里使用io_service对象来实现异步是轻而易举的事情,因为封装的接口简单、明了。具体的代码如下:
-
- #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>
-
- using boost::asio::ip::udp;
-
- std::string make_daytime_string()
- {
- using namespace std;
- time_t now = time(0);
- return ctime(&now);
- }
-
- class UdpTimeServer
- {
- public:
-
- 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
- {
-
- 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>
- const boost::system::error_code&
- std::size_t
- {
-
- }
-
- private:
- udp::socket m_sockUdp;
- 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;
- }
在这个例子里,主要封装了一个服务器UdpTimeServer,它是采用io_service对象和socket对象的异步特性来构造,有事件响应之后才去执行相应的操作,不过这样比前面的同步方式,还是复杂了一些,但带来了避免多线程之间的同步问题。