BOOST学习笔记

BOOST学习笔记

1 tool

 1 #pragma once
 2 #include <vector>
 3 
 4 #include "boost/noncopyable.hpp"
 5 #include "boost/typeof/typeof.hpp"
 6 #include "boost/serialization/singleton.hpp"
 7 
 8 #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
 9 using namespace boost;
10 using namespace std;
11 using namespace boost::serialization;
12 class CNo_copy_class : public noncopyable
13 {
14 public:
15     CNo_copy_class() : a(11){}
16     int a;
17 };
18 
19 void no_copy_test()
20 {
21     CNo_copy_class c1;
22     //CNo_copy_class c2(c1);
23 }
24 
25 vector<int> func()
26 {
27     return vector<int>(10, 2);
28 }
29 
30 void typeof_auto_test()
31 {
32     //decltype(20*3.0) x1 = 20*3.0;
33     BOOST_TYPEOF(20*3.0) x2 = 20*3.0;
34 
35     BOOST_AUTO(&a, new double[20]);
36     BOOST_AUTO(p, make_pair(1, "string"));
37 
38     BOOST_AUTO(v ,func());
39 
40     //注册自定义类型
41     BOOST_TYPEOF_REGISTER_TYPE(CNo_copy_class)
42     BOOST_AUTO( pdef, new CNo_copy_class());
43     cout<< typeid(pdef).name() << endl;
44 }
45 
46 typedef singleton<CNo_copy_class> origin;
47 
48 void singleton_test()
49 {
50     cout << origin::get_const_instance().a << endl;
51     //origin::get_const_instance().a = 5;
52     cout << origin::get_mutable_instance().a << endl;
53     origin::get_mutable_instance().a = 6;
54     cout << origin::get_const_instance().a << endl;
55 }

2 file

 1 #pragma once
 2 #include "boost/filesystem.hpp"
 3 
 4 using namespace boost;
 5 using namespace std;
 6 
 7 void path_string_opt_test()
 8 {
 9     filesystem::path p1;
10     assert(p1.empty());
11 
12     filesystem::path p2("c:/user/local/include/xx.js");
13     cout << p2.string() << endl;
14 
15     if (p2.has_stem())        //xx,文件名,无后缀
16     {
17         cout << p2.stem() << endl;
18     }
19     if (p2.has_extension())    //.js,文件名后缀
20     {
21         cout << p2.extension() << endl;
22     }
23     if (p2.has_filename())    //xx.js,文件全名,有后缀
24     {
25         cout << p2.filename() << endl;
26     }
27     if (p2.has_parent_path())    //c:/user/local/include,除去文件名的路径
28     {
29         cout << p2.parent_path() << endl;
30     }
31 
32     if (p2.has_root_name())        //windows路径为c:
33     {
34         cout << p2.root_name() << endl;
35     }
36     if (p2.has_root_directory())    //windows路径为/
37     {
38         cout << p2.root_directory() << endl;
39     }
40     if (p2.has_root_path())        //windows路径为c:/
41     {
42         cout << p2.root_path() << endl;
43     }
44 
45     //修改文件路径
46     cout << p2.replace_extension("hxx") << endl;        //修改扩展名,修改后为c:/user/local/include/xx
47     cout << p2.replace_extension() << endl;        //修改扩展名,修改后为c:/user/local/include/xx
48     cout << p2.remove_filename() << endl;        //移除文件名,修改后为c:/user/local/include
49 }
50 
51 void GetModulePath()
52 {
53     char szPath[MAX_PATH];
54     GetModuleFileName( NULL, szPath, MAX_PATH );
55     cout << szPath << endl;
56     //输出:p:workspaceproj	estoost_testuildsrcDebugBOOST_TEST.exe
57 
58     cout << boost::filesystem::initial_path<filesystem::path>().string() <<endl;
59     //输出:p:workspaceproj	estoost_testuildsrc
60     
61     //
62     cout << boost::filesystem::current_path().string() << endl;
63 }
64 
65 void directory_test()
66 {
67     boost::filesystem::path p1(boost::filesystem::current_path());
68     p1.append("123\456");
69     //循环创建目录
70     if (!boost::filesystem::exists(p1))
71     {
72         boost::filesystem::create_directories(p1);
73     }
74     //递归删除最底层目录
75     if (boost::filesystem::exists(p1))
76     {
77         boost::filesystem::remove_all(p1);
78     }
79 }

3 container

 1 #pragma once
 2 #include <map>
 3 #include <vector>
 4 #include "boost/array.hpp"
 5 #include "boost/any.hpp"
 6 #include "boost/foreach.hpp"
 7 
 8 using namespace boost;
 9 using namespace std;
10 
11 void array_test()
12 {
13     array<int, 10> ar = {0,1};
14     array<string, 10> ars = {"123"};
15     for (int i=0; i<10; i++)
16     {
17         cout << ars[i] << endl;
18     }
19 }
20 
21 void any_test()
22 {
23     any a(10);
24     int n = any_cast<int>(a);
25 
26     any_cast<int&>(a) = 20;
27 }
28 
29 void foreach_test()
30 {
31     int a[] = {0, 1, 2, 3, 4, 5};
32     vector<int> vec(a , a + 6);
33     BOOST_FOREACH(int x, vec)
34     {
35         cout << x << endl;
36     }
37     BOOST_REVERSE_FOREACH(int x, vec)
38     {
39         cout << x << endl;
40     }
41 }

4 smart_ptr

 1 #pragma once
 2 #include<iostream>
 3 #include <vector>
 4 #include "boost/smart_ptr.hpp"
 5 using namespace boost;
 6 using namespace std;
 7 
 8 // 
 9 void scoped_ptr_test()
10 {
11     scoped_ptr<int> p(new int);
12     if (p)
13     {
14         *p = 100;
15         cout << *p << endl;
16     }
17     p.reset();
18 }
19 
20 void scoped_array_test()
21 {
22     scoped_array<int> p(new int[100]);
23     fill_n(&p[0], 100, 5);
24     p[10] = p[20] + p[30];
25 }
26 
27 void shared_ptr_test()
28 {
29     shared_ptr<int> p(new int(100));
30     *p = 5;
31     //shared_ptr< vector<int> > mp = make_shared< vector<int> >(100,5);
32 
33     //shardptr可以指定析构函数
34 
35 }
36 
37 void shared_array_test()
38 {
39     shared_array<int> p(new int[100]);
40     shared_array<int> p2 = p;
41     p[0] = 10;
42     assert( p2[0] == 10);
43 }
44 
45 void weak_ptr_test()
46 {
47     shared_ptr<int> sp(new int(100));
48     assert(sp.use_count() == 1);
49 
50     weak_ptr<int> wp(sp);
51     assert(wp.use_count() == 1);
52 
53     if (!wp.expired())
54     {
55         shared_ptr<int> sp2 = wp.lock();
56         *sp2 = 100;
57         assert(wp.use_count() == 2 );
58     }
59     assert(wp.use_count() == 1);
60     sp.reset();
61     assert(wp.expired());
62     assert(!wp.lock());
63 }

5 function

 1 #pragma once
 2 #include "boost/utility/result_of.hpp"
 3 #include "boost/any.hpp"
 4 #include "boost/bind.hpp"
 5 #include "boost/function.hpp"
 6 
 7 using namespace boost;
 8 using namespace std;
 9 
10 template<typename T, typename T1>
11 typename result_of<T(T1)>::type call_func(T t, T1 t1)
12 {
13     return t(t1);
14 }
15 
16 void result_of_test()
17 {
18     typedef double (*Func)(double);
19     Func func = sqrt;
20 
21     result_of<Func(double)>::type x = func(5.0);
22     cout << typeid(x).name() << endl;
23 
24     any x2 = call_func(func, 5.0);
25     cout << typeid(boost::any_cast<double>(x2)).name() << endl;
26 }
27 
28 int f(int a, int b)
29 {
30     return a + b;
31 }
32 
33 int g(int a, int b, int c)
34 {
35     return a + b*c;
36 }
37 
38 void bind_test()
39 {
40     cout << bind(f, 1, 2)() << endl;
41     int x = 1, y = 2, z = 3;
42     cout << bind(f, _1, 9)(x) << endl;    //使用占位符
43     cout << bind(g, _3, _2, _2)(x, y, z) << endl;    //使用占位符,乱序
44     
45     //绑定成员函数
46     class demo
47     {
48     public:
49         int f(int a, int b)
50         {
51             cout << a << " "<< b << endl;
52             return a + b;
53         }
54     } a;
55     demo& b = a;
56     demo* p = &a;
57     cout << bind(&demo::f, a, _1, 10)(10) << endl;
58     cout << bind(&demo::f, b, _2, _1)(10, 20) << endl;
59     cout << bind(&demo::f, p, _1, _2)(10, 20) << endl;
60 
61     //算法容器
62     class point
63     {
64     public:
65         int x,y;
66         point() : x(0), y(1) {}
67         void print()
68         {
69             cout << x << " " << y << endl;
70         }
71     };
72     std::vector<point> v(10);
73     for_each(v.begin(), v.end(), bind(&point::print, _1));    //成员函数_1表示函数指针
74 }
75 
76 void function_test()
77 {
78     boost::function<int(int, int)> func = f;
79     if (func)
80     {
81         cout << func(10, 20) << endl;
82     }
83     func.clear();
84 
85     boost::function<int(int)> func1 = boost::bind(f, _1, 20);
86     if (func1)
87     {
88         cout << func1(10) << endl;
89     }
90 }

6 pool

 1 #pragma once
 2 #include <vector>
 3 #include "boost/pool/pool.hpp"
 4 #include "boost/pool/object_pool.hpp"
 5 #include "boost/pool/singleton_pool.hpp"
 6 #include "boost/pool/pool_alloc.hpp"
 7 using namespace boost;
 8 using namespace std;
 9 
10 class demo_class
11 {
12 public:
13     int a,b,c;
14     demo_class(int x =1 ,int y=2, int z=3):a(x), b(y), c(z)
15     {
16     }
17 };
18 typedef singleton_pool<demo_class , sizeof(demo_class)> spl;
19 
20 void pool_test()
21 {
22     pool<> pl(sizeof(int));
23     int* p = static_cast<int*>(pl.ordered_malloc());
24     assert(pl.is_from(p));
25 
26     pl.ordered_free(p);
27 
28     for (int i=0; i<10; i++)
29     {
30         pl.ordered_malloc(10);
31     }
32 }
33 
34 
35 void object_pool_test()
36 {
37     object_pool<demo_class> pl;
38     demo_class *p = pl.malloc();
39     assert(pl.is_from(p));
40 
41     assert(p->a != 1 || p->b != 2 || p->c != 3);
42     
43     p =pl.construct(7, 8, 9);
44     assert(p->a == 7);
45 
46     object_pool<std::string> pls;
47     for (int i=0; i<10 ;i++)
48     {
49         std::string *ps = pls.construct("hello");
50         cout<< ps->c_str() << endl;
51     }
52 }
53 
54 void singleton_pool_test()
55 {
56     demo_class* p = (demo_class*)spl::malloc();
57     assert(spl::is_from(p));
58     spl::release_memory();
59 }
60 
61 void pool_alloc_test()
62 {
63     std::vector<int, pool_allocator<int> > v;
64     v.push_back(10);
65 }

7 thread

  1 #pragma once
  2 #include <stack>
  3 #include <vector>
  4 #include "boost/thread.hpp"
  5 #include "boost/foreach.hpp"
  6 
  7 using namespace boost;
  8 using namespace std;
  9 
 10 boost::mutex io_mu_1;
 11 void time_test()
 12 {
 13     this_thread::sleep_for(chrono::seconds(20));
 14 
 15     this_thread::sleep_until(chrono::system_clock::now() + chrono::seconds(4));
 16 }
 17 
 18 void to_interrupt(int& x, const string& str)
 19 try
 20 {
 21     for (int i=0; i<5; i++)
 22     {
 23         boost::mutex::scoped_lock(io_mu_1);
 24         cout << str << ++x << std::endl;
 25         //this_thread::sleep_for(chrono::seconds(1));
 26         {
 27             //自动中断点
 28 
 29         }
 30         this_thread::interruption_point();
 31     }
 32 }
 33 catch(...)
 34 {
 35     cout << "thread_interrupted" << std::endl;
 36 };
 37 
 38 void thread_test()
 39 {
 40     int x = 0;
 41     boost::thread t(to_interrupt, boost::ref(x), "hello");
 42     this_thread::sleep_for(chrono::seconds(3));
 43 
 44     t.interrupt();
 45     assert(t.interruption_requested());
 46 
 47     t.join();
 48 }
 49 
 50 //测试条件变量
 51 class buffer
 52 {
 53 public:
 54     buffer(int n) : un_read(0),capacity(n)
 55     {
 56     }
 57     void put(int x)
 58     {
 59         {
 60             boost::mutex::scoped_lock lock(mu);
 61             while (if_full())
 62             {
 63                 {
 64                     //boost::mutex::scoped_lock lock2(io_mu_1);
 65                     cout<< "full waiting
";
 66                 }
 67                 cond_put.wait(mu);
 68             }
 69         }
 70         stk.push(x);
 71         ++un_read;
 72         cond_get.notify_one();
 73     }
 74     void get(int* x)
 75     {
 76         {
 77             boost::mutex::scoped_lock lock(mu);
 78             while (is_empty())
 79             {
 80                 {
 81                     //boost::mutex::scoped_lock lock2(io_mu_1);
 82                     cout<< "empty waiting
";
 83                 }
 84                 cond_get.wait(mu);
 85             }
 86         }
 87         --un_read;
 88         *x = stk.top();
 89         stk.pop();
 90         cond_put.notify_one();
 91     }
 92 private:
 93     boost::mutex mu;
 94     boost::condition_variable_any cond_put;
 95     boost::condition_variable_any cond_get;
 96     std::stack<int> stk;
 97     int un_read,capacity;
 98     bool if_full()
 99     {
100         return un_read == capacity;
101     }
102     bool is_empty()
103     {
104         return un_read == 0;
105     }
106 }    buf(5);
107 
108 void producer(int n)
109 {
110     for (int i=0; i< n; i++)
111     {
112         {
113             //boost::mutex::scoped_lock lock(io_mu_1);
114             cout << "put " << i << std::endl;
115         }
116         buf.put(i);
117     }
118 }
119 
120 void consumer(int n)
121 {
122     int x;
123     for (int i=0; i< n; i++)
124     {
125         buf.get(&x);
126         //boost::mutex::scoped_lock lock(io_mu_1);
127         cout << "get " << x << std::endl;
128     }
129 }
130 
131 void condition_test()
132 {
133     boost::thread t1(producer, 20);
134     boost::thread t2(consumer, 10);
135     boost::thread t3(consumer, 10);
136 
137     t1.join();
138     t2.join();
139     t3.join();
140 
141     boost::this_thread::sleep_for(boost::chrono::seconds(30));
142 }
143 
144 //共享互斥量
145 class rw_data
146 {
147 public:
148     rw_data() : m_x(0) {}
149     void write()
150     {
151         unique_lock<shared_mutex> ul(rw_mu);
152         ++m_x;
153     }
154     void read(int* x)
155     {
156         shared_lock<shared_mutex> sl(rw_mu);
157         *x = m_x;
158     }
159 private:
160     int m_x;
161     shared_mutex rw_mu;
162 };
163 
164 void writer(rw_data& d)
165 {
166     for (int i=0; i< 20; i++)
167     {
168         this_thread::sleep_for(chrono::milliseconds(10));
169         d.write();
170     }
171 }
172 
173 void reader(rw_data& d)
174 {
175     int x;
176     for (int i=0; i< 20; i++)
177     {
178         this_thread::sleep_for(chrono::milliseconds(5));
179         d.read(&x);
180         cout << this_thread::get_id()<< " read: "<<x<<std::endl;
181     }
182 }
183 
184 void shared_mutex_test()
185 {
186     rw_data d;
187     boost::thread_group pool;
188     pool.create_thread(bind(writer, boost::ref(d)));
189     pool.create_thread(bind(writer, boost::ref(d)));
190 
191     pool.create_thread(bind(reader, boost::ref(d)));
192     pool.create_thread(bind(reader, boost::ref(d)));
193     pool.create_thread(bind(reader, boost::ref(d)));
194     pool.create_thread(bind(reader, boost::ref(d)));
195 
196     pool.join_all();
197     this_thread::sleep_for(chrono::seconds(3000));
198 }
199 
200 //future,线程返回执行结果
201 int fab(int n)
202 {
203     if (n == 0 || n == 1)
204     {
205         return 1;
206     }
207     return fab(n-1) + fab(n-2);
208 }
209 
210 void future_test()
211 {
212     //单个future
213     boost::packaged_task<int> pt(bind(fab, 10));
214     boost::BOOST_THREAD_FUTURE<int> f = pt.get_future();
215 
216     boost::thread(boost::move(pt));
217     f.wait();
218 
219     cout << f.get() << endl;
220     this_thread::sleep_for(chrono::seconds());
221 
222     //多个future协调,wait for all/any
223     typedef boost::packaged_task<int> pti_t;
224     typedef boost::BOOST_THREAD_FUTURE<int> fi_t;
225 
226     boost::array<pti_t, 5> ap;
227     boost::array<fi_t, 5> af;
228 
229     for (int i = 0; i<5;i++)
230     {
231         ap[i] = pti_t(bind(fab, i+ 10));
232         af[i] = ap[i].get_future();
233         boost::thread(boost::move(ap[i]));
234     }
235 
236     boost::wait_for_all(af.begin(), af.end());
237     BOOST_FOREACH(fi_t& f, af)
238     {
239         cout << f.get() << endl;
240     }
241 
242     for (int i = 0; i<5;i++)
243     {
244         boost::thread(boost::move(ap[i]));
245     }
246 
247     boost::wait_for_any(af.begin(), af.end());
248     BOOST_FOREACH(fi_t& f, af)
249     {
250         if (f.is_ready() && f.has_value())
251         {
252             cout << f.get() << endl;
253         }
254     }
255 
256     this_thread::sleep_for(chrono::seconds(3000));
257 }
258 
259 //线程本地存储
260 boost::thread_specific_ptr<int> pi;        //本地线程存储一个int
261 
262 void printing()
263 {
264     pi.reset(new int(1));
265 
266     ++(*pi);
267     cout << this_thread::get_id() << " thread, value = " << *pi << endl;
268 }
269 void tls_test()
270 {
271     (boost::thread(bind(printing)));
272     (boost::thread(bind(printing)));
273 
274     this_thread::sleep_for(chrono::seconds(2000));
275 }

8 asio

8.1 server

  1 #pragma once
  2 #include <vector>
  3 
  4 #include "boost/asio.hpp"
  5 #include "boost/date_time/posix_time/posix_time.hpp"
  6 #include "boost/smart_ptr.hpp"
  7 
  8 using namespace boost;
  9 using namespace boost::asio;
 10 using namespace std;
 11 
 12 boost::asio::io_service g_ios;    //所有的asio都要有个ios
 13 
 14 //同步定时器
 15 void deadlime_timer_sync_test()
 16 {
 17     boost::asio::deadline_timer t(g_ios, posix_time::seconds(2));
 18     cout << t.expires_at() << endl;        //终止绝对时间
 19     t.wait();
 20 }
 21 
 22 //异步定时器
 23 //异步定时器回调标准格式
 24 void print(system::error_code x)
 25 {
 26     cout << "deadline time
";
 27 }
 28 
 29 void deadlime_timer_async_test()
 30 {
 31     boost::asio::deadline_timer t(g_ios, posix_time::seconds(20));
 32     cout << t.expires_at() << endl;        //终止绝对时间
 33     t.async_wait(print);
 34     cout << "deadline time
";
 35     g_ios.run();
 36 }
 37 
 38 //tcp
 39 void tcp_address_test()
 40 {
 41     boost::asio::ip::address addr;
 42     //addr = addr.from_string("ab.12.23.34");
 43     //assert(addr.is_v6());
 44     addr = addr.from_string("127.0.0.1");
 45     assert(addr.is_v4());
 46     cout << addr.to_string() << endl;
 47     ip::tcp::endpoint ep(addr, 8866);
 48     assert(ep.address() == addr);
 49     assert(ep.port() == 8866);
 50 }
 51 
 52 //服务端
 53 void server_test()
 54 {
 55     ip::tcp::acceptor acceptor(g_ios, 
 56         ip::tcp::endpoint(ip::tcp::v4(), 8866));
 57 
 58     while (1)
 59     {
 60         ip::tcp::socket sock(g_ios);
 61         acceptor.accept(sock);
 62 
 63         cout << "recv client: " << sock.remote_endpoint().address() << endl;
 64         sock.write_some(boost::asio::buffer(std::string("hello")));        //发送数据
 65     }
 66 }
 67 
 68 //异步
 69 typedef boost::shared_ptr<ip::tcp::socket> sock_ptr;
 70 class server
 71 {
 72 public:
 73     server() : acceptor(g_ios, 
 74         ip::tcp::endpoint(ip::tcp::v4(), 8866))
 75     {
 76         start();
 77     }
 78     void start()
 79     {
 80         sock_ptr sock(new ip::tcp::socket(g_ios));
 81         acceptor.async_accept(*sock, 
 82             bind(&server::accept_handler, this, asio::placeholders::error, sock));
 83     }
 84     void accept_handler(const system::error_code& ec, sock_ptr sock)
 85     {
 86         if (ec)
 87         {
 88             return;
 89         }
 90         cout << sock->remote_endpoint().address() << endl;
 91         sock->async_write_some(boost::asio::buffer(std::string("hello")), 
 92             bind(&server::write_handler, this, asio::placeholders::error));
 93         start();
 94     }
 95     void write_handler(const system::error_code& ec)
 96     {    
 97         cout << "send msg ok
";
 98     }
 99 private:
100     ip::tcp::acceptor acceptor;
101 };
102 
103 void async_server_test()
104 {
105     server ser;
106     g_ios.run();
107 }
108 
109 void DNS_test()
110 {
111     ip::tcp::socket sock(g_ios);
112     ip::tcp::resolver rlv(sock.get_io_service());
113 
114     ip::tcp::resolver::query qry("www.baidu.com", lexical_cast<std::string>(80));
115     ip::tcp::resolver::iterator iter = rlv.resolve(qry);
116     ip::tcp::resolver::iterator end;
117 
118     system::error_code ec = error::host_not_found;
119     for ( ; ec && iter != end; ++iter)
120     {
121         sock.close();
122         sock.connect(*iter, ec);
123     }
124     if ( ec )
125     {
126         cout << "can't connect
";
127     }
128 }

8.2 client

 1 #pragma once
 2 #include <vector>
 3 
 4 #include "boost/thread.hpp"
 5 #include "boost/asio.hpp"
 6 #include "boost/date_time/posix_time/posix_time.hpp"
 7 
 8 using namespace boost;
 9 using namespace boost::asio;
10 using namespace std;
11 
12 boost::asio::io_service g_ios;    //所有的asio都要有个ios
13 
14 
15 //客户端
16 void client_test()
17 {
18     while (1)
19     {
20         ip::tcp::socket sock(g_ios);
21         ip::tcp::endpoint ep(ip::address::from_string("127.0.0.1"), 8866);
22         sock.connect(ep);
23 
24         std::string str;
25         str.resize(100, 0);
26         sock.read_some(buffer(str));
27         cout << "receive from " << sock.remote_endpoint().address() << endl;
28         cout << "content : " << str << endl;
29 
30         sock.close();
31 
32         boost::this_thread::sleep_for(boost::chrono::seconds(5));
33     }
34     
35 }
36 
37 //异步通信客户端
38 typedef boost::shared_ptr<ip::tcp::socket> sock_ptr;
39 typedef boost::shared_ptr<std::string> str_ptr;
40 class client
41 {
42 public:
43     client() : ep(ip::address::from_string("127.0.0.1"), 8866)
44     {
45         start();
46     }
47     void start()
48     {
49         sock_ptr sock(new ip::tcp::socket(g_ios));
50         sock->async_connect(ep,
51             bind(&client::connect_handler, this, asio::placeholders::error, sock));
52     }
53     void connect_handler(const system::error_code& ec, 
54         sock_ptr sock)
55     {
56         if (ec)
57         {
58             return;
59         }
60         cout << "sock connect " << sock->remote_endpoint().address() << endl;
61         str_ptr pstr(new std::string(100,0));
62         sock->async_read_some(asio::buffer(*pstr),
63             bind(&client::read_hander, this, asio::placeholders::error, pstr));
64         start();
65     }
66     virtual void read_hander(const system::error_code& ec,
67         shared_ptr<std::string> str)
68     {
69         cout <<"recv msg: " <<str << endl;
70     }
71 protected:
72     ip::tcp::endpoint ep;
73 };
74 
75 class client11 : public client
76 {
77     virtual void read_hander(const system::error_code& ec,
78         shared_ptr<std::string> str)
79     {
80         cout <<"child recv msg: " <<str << endl;
81     }
82 };
83 
84 void async_client_test()
85 {
86     client11 cli;
87     g_ios.run();
88 }

 9 源码

  1-8的源码地址:https://download.csdn.net/download/honggangqianren/10538015

原文地址:https://www.cnblogs.com/hgwang/p/9301437.html