保持活动
假如,你须要做以下的操作:
io_service service;
ip::tcp::socket sock(service);
char buff[512];
...
read(sock, buffer(buff));
在这个样例中,sock和buff的存在时间都必须比read()调用的时间要长。

也就是说,在调用read()返回之前,它们都必须有效。

这就是你期望的。你传给一个方法的全部參数在參数内部都必须有效。

当我们採用异步方式时,事情会变得越复杂。

io_service service;
ip::tcp::socket sock(service);
char buff[512];
void on_read(const boost::system::error_code &, size_t) {}
...
async_read(sock, buffer(buff), on_read);
在这个样例中。sock和buff的存在时间都必须比read()操作本身时间要长,可是read操作的时间我们是不知道的,由于它是异步的。
当使用socket缓冲区的时候,你会有一个buffer实例在异步调用时一直存在(使用boost::shared_array<>)。在这里,我们能够使用相同的方式。通过创建一个类并在其内部管理socket和它的读写缓冲区。

然后,对于全部的异步操作,我会传递一个包括智能指针的boost::bind仿函数:

using namespace boost::asio;
io_service service;
struct connection : boost::enable_shared_from_this<connection> {
       typedef boost::system::error_code error_code;
typedef boost::shared_ptr<connection> ptr;
connection() : sock_(service), started_(true) {}
void start(ip::tcp::endpoint ep) {
           sock_.async_connect(ep,
boost::bind(&connection::on_connect, shared_from_this(),

_1)); }

       void stop() {
if ( !started_) return;
started_ = false;
sock_.close();

}

       bool started() { return started_; }
private:
       void on_connect(const error_code & err) {
// here you decide what to do with the connection: read or
   write
if ( !err) do_read();
           else            stop();
}
       void on_read(const error_code & err, size_t bytes) {
if ( !started() ) return;
std::string msg(read_buffer_, bytes);

if ( msg == "can_login")
else if ( msg.find("data ") == 0)
else if ( msg == "login_fail")
do_write("access_data");
process_data(msg);
stop();
}
void on_write(const error_code & err, size_t bytes) {

do_read(); }

void do_read() {
           sock_.async_read_some(buffer(read_buffer_),
boost::bind(&connection::on_read, shared_from_this(),

_1, _2)); }

       void do_write(const std::string & msg) {
if ( !started() ) return;
// note: in case you want to send several messages before
// doing another async_read, you'll need several write
   buffers!
std::copy(msg.begin(), msg.end(), write_buffer_);
sock_.async_write_some(buffer(write_buffer_, msg.size()),
                 boost::bind(&connection::on_write, shared_from_this(),

_1, _2)); }

       void process_data(const std::string & msg) {
// process what comes from server, and then perform another

write }

   private:
ip::tcp::socket sock_;
enum { max_msg = 1024 };
char read_buffer_[max_msg];
char write_buffer_[max_msg];
bool started_;

};

   int main(int argc, char* argv[]) {
ip::tcp::endpoint ep( ip::address::from_string("127.0.0.1"),
   8001);
connection::ptr(new connection)->start(ep);

}

在全部异步调用中,我们传递一个boost::bind仿函数当作參数。

这个仿函数内部包括了一个智能指针,指向connection实例。仅仅要有一个异步操作等待时,Boost.Asio会保存boost::bind仿函数的拷贝,这个拷贝保存了指向连接实例的一个智能指针,从而保证connection实例保持活动。问题解决!

当然。connection类不过一个skeleton类;你须要依据你的需求对它进行调整(它看起来会和服务端的情况相当不同)。

你须要注意创建一个新的连接是相当简单的:connection::ptr(new connection)- >start(ep)。这种方法启动了到服务端的(异步)连接。

当你须要关闭这个连接时,调用stop()。

当实例被启动时(start()),它将会等待被连接。当连接发生时。on_connect()被调用。假设没有发生错误。它启动一个read操作(do_read())。

当read操作结束时,你解析这个消息;你应用的on_read()看起来会各种各样。

当你写回一个消息时,你须要把它复制到缓冲区。然后像我在do_write()方法中所做的一样将其发送出去,由于再一次,这个缓冲区须要在这个异步写操作中一直存活。最后须要注意的一点——当写回时,你须要指定写入的数量,否则。整个缓冲区都会被发送出去。

总结

网络api实际上要大得多,这个章节仅仅是一个參考,当你在实现你自己的网络应用时,你须要回来查看。

Boost.Asio实现了端点的概念。你能够觉得是IP和port。假设你不知道准确的IP,你能够使用resolver对象将主机名,比如www.yahoo.com转换为一个或多个IP地址。

我们也能够看到API的核心——socket类。Boost.Asio提供了TCP、UDP和 ICMP的实现。可是你能够用你自己的协议来对它进行扩展;当然,这个工作不适合胆小的人。

异步编程是必要之恶。你会明确为什么有时候须要它,尤其在写服务端的时候。调用service.run()来实现异步循环就已经能够让你非常开心。可是有时候你须要更进一步。尝试使用run_one()、poll()或者poll_one()。

当实现异步时,你能够用你自己方法来异步运行。使用service.post()或者service.dispatch()。

最后,为了使socket和缓冲区(read或者write)在整个异步操作的生命周期中一直活动,我们须要採取特殊的防护措施。你的连接类须要继承自enabled_shared_from_this,在内部保存它须要的缓冲区。并且每一个异步调用都要传递一个智能指针给this操作。

下一章会让你进行实战操作;在实现回显client/服务端应用时会有大量的上手编程。

Boost.Asio c++ 网络编程翻译(14)的更多相关文章

  1. Boost.Asio c++ 网络编程翻译(20)

    异步服务端 这个图表是相当复杂的:从Boost.Asio出来你能够看到4个箭头指向on_accept.on_read,on_write和on_check_ping. 着也就意味着你永远不知道哪个异步调 ...

  2. Boost.Asio c++ 网络编程翻译(26)

    Boost.Asio-其他特性 这章我们讲了解一些Boost.Asio不那么为人所知的特性.标准的stream和streambuf对象有时候会更难用一些,但正如你所见.它们也有它们的益处.最后,你会看 ...

  3. Boost.Asio c++ 网络编程翻译(11)

    *_at方法 这些方法在一个流上面做随机存取操作.你来指定read和write操作从什么地方開始(offset): async_read_at(stream, offset, buffer [, co ...

  4. Boost.Asio c++ 网络编程翻译(21)

    同步VS异步 Boost.Asio的作者做了一个非常惊艳的工作:它能够让你在同步和异步中自由选择,从而更好的适应你的应用. 在之前的章节中,我们学习了每种类型应用的框架,比方同步client,同步服务 ...

  5. Boost.Asio c++ 网络编程翻译(16)

    TCP异步服务端 核心功能和同步服务端的功能类似,例如以下: class talk_to_client : public boost::enable_shared_from_this<talk_ ...

  6. Boost.Asio c++ 网络编程翻译(10)

    read/write方法 这些方法对一个流进行读写操作(能够是套接字,或者其它表现的像流的类): async_read(stream, buffer [, completion],handler):这 ...

  7. Boost.Asio c++ 网络编程翻译(18)

    同步服务端 同步服务端也相当简单.它须要两个线程,一个负责接收新的client.另外一个负责处理已经存在的client. 它不能使用单线程:等带一个新的client是一个堵塞操作,所以我们须要另外一个 ...

  8. 《Unix 网络编程》14:高级 I/O 函数

    高级 I/O 函数 ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ...

  9. boost.asio系列——socket编程

    asio的主要用途还是用于socket编程,本文就以一个tcp的daytimer服务为例简单的演示一下如何实现同步和异步的tcp socket编程. 客户端 客户端的代码如下: #include &l ...

随机推荐

  1. 解决 MySQL manager or server PID file could not be found! 的方法

    [root@centos var]# service mysqld stop MySQL manager or server PID file could not be found!       [F ...

  2. aix Mysql-Rpm puppet puppetAgent

    http://www.bullfreeware.com/toolbox.php   (Large Open Source Software Archieve for AIX 提供MySQL5.1 fo ...

  3. opennebula extend(expending) auth module ldap

    LDAP Authentication addon permits users to have the same credentials as in LDAP, so effectively cent ...

  4. BZOJ 2186 SDOI2008 沙拉公主的困惑 数论

    题目大意:给定询问组数T和取模数P,每次询问给定两个整数n和m,求1~(n!)的数中与m!互质的数个个数模P (m<=n) 首先T<=1W,暴力肯定过不去,我们须要预处理一些东西 首先我们 ...

  5. 响应式内容滑动插件bxSlider

    bxSlider特性 1.充分响应各种设备,适应各种屏幕: 2.支持多种滑动模式,水平.垂直以及淡入淡出效果: 3.支持图片.视频以及任意html内容: 4.支持触摸滑动: 5.支持Firefox,C ...

  6. 《think in python》学习-3

    函数 函数是指用于进行某种计算的一系列语句的有名称的组合. type(32) 就是一个函数调用的例子 类型转换函数 python提供了一些可将某个值从一种类型转换为另外一个类型的内置函数 int(32 ...

  7. CRM odata方法 js容易出现的错误,大小写区分 Value Id

    Id Value  注意大小写,I大写,V大写,typeResults.result[0].yt_category.Value; 否则会报 错,Result.yt_businessunit_terri ...

  8. 介绍Foundation框架

    开始介绍Foundation框架.OC中的Foundation框架是系统提供了,他就相当于是系统的一套api,和Java中的一些系统jar很相似,又早起的一批人开发的,内部有很多现有的类和功能提供给我 ...

  9. Phalcon 性能最高的php框架没有之一

    最近有个朋友说他们现在在用Phalcon框架开发项目,明显感觉性能有很大的提升,所有着手学习下这个高性能框架,网上是这样说的“虽然以C语言编写达到较高的效能,但相对的一项缺点就是在服务器上必须拥有管理 ...

  10. EC读书笔记系列之16:条款35、36、37、38、39、40

    条款35 考虑virtual函数以外的其他选择 记住: ★virtual函数的替代方案包括NVI手法及Strategy模式的多种形式.NVI手法自身是一个特殊形式的Template Method模式 ...