Documentation for Boost.Asio

http://www.boost.org/doc/libs/1_62_0/doc/html/boost_asio.html

https://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting-started-with-boostasio?pg=7

1  Your program will have at least one io_service object. The io_service represents your program's link to the operating system's I/O services.

  Program->I/O Object-> I/O Service -> operating system
  (1)  only for asynchronous operation, should we call io_service.run()
  (2)  for synchornous operation, we don't have to call run() to block it

2  A strand is defined as a strictly sequential invocation of event handlers,
  that is, only when the privious handler has finished will the next one be executed
  Use of strands allows execution of code in a multithreaded program without the need for explicit locking.

3  Buffers, usually contiguous regions of memory, can be simply expressed as a tuple consisting of a pointer and a size in bytes: (char *, size_t )
  the library also includes mechanisms for automatically determining the size of a buffer from an array, boost::array or std::vector of POD elements, or from a std::string
  all buffers are of type of const_buffer or mutalbe_buffer

4    boost::asio::streambuf & boost::asio::buffers_begin()

5    Many I/O objects in Boost.Asio are stream-oriented, such as ip::tcp::socket, and provide stream read & write operation
  Programs typically want to transfer an exact number of bytes. When a short read or short write occurs the program must restart the operation,
  and continue to do so until the required number of bytes has been transferred.
  Boost.Asio provides generic functions that do this automatically: read(), async_read(), write() and async_write().(for udp, iocp, they are receive()/send())
  And streams are usually lined based, so there are functions like read_until()

6  Resolver, where host and service names are looked up and converted into one or more endpoints

7  Acceptor, accept incoming TCP connections:shall extract the first connection on the queue of pending connections, create a new socket with the same socket type protocol
  and address family as the specified socket, and allocate a new file descriptor for that socket

8  Boost.Asio includes classes that implement iostreams on top of sockets. These hide away the complexities associated with endpoint resolution, protocol independence, etc.

9  when perform synchronous wait, Timer can be used to decide the deadline

10  supports signal handling using a class called signal_set. Programs may add one or more signals to the set, and then perform an async_wait() operation.
  The specified handler will be called when one of the signals occurs. The same signal number may be registered with multiple signal_set objects,
  however the signal number must be used only with Boost.Asio.

11. when there is any io_service::work, io_service::run() will block the thread where it's called
  [io_service.post()->io_service.run()->io_service.dispacth()], like post(), async_read

12. if we had associated a work object with the io_service and wanted to let all queued work finish, we would not call stop but rather destroy the work objec,
  that is , we dont have to call any stop(), just call work.reset()

13  since the io_service cannot be copied and that is what boost::bind does for us behind the scenes. To get around this, we must make use of shared_ptr. is reference or pointer OK?

14  The post function "is used to ask the io_service to execute the given handler, but without allowing the io_service to call the handler from inside this function."
  The dispatch function "guarantees that the handler will only be called in a thread in which the run(), run_one(), poll() or poll_one() member functions is currently being invoked.
  Dispatched events can execute from the current worker thread even if there are other pending events queued up.
  This means if we post work1 -> work2 -> work3 through a strand, no matter how many worker threads we have, it will be executed in that order. will not Dispatch!!!

15  For variable on the stack, it's possible for it to go out of scope before the asynchronous operation completes.

16  io_service is thread-safe, but not sockets, so a socket be used in several threads should be lock!!!

17  The asynchronous support is based on the Proactor design pattern

18  Asynchronous completion handlers will only be called from threads that are currently calling io_service::run().

19  The open() function must be called before data can be sent or received on the socket

20  this is because the poll function will not block while there is more work to do. It simply executes the current
  set of work and then returns.if there is an event get, then call the handler, if none, just go ahread;

21 all threads call the same io_service.run() will be put in the thread pool of this io_service
  base on one io_service, there can more than one io object( socket)
  we can use several io_service object to create diffent thread pool

SSL (Secure Sockets Layer) is a standard security technology for establishing an encrypted link between a server and a client,
  allow encrypted communication to be layered on top of an existing stream
  Normally, data sent between browsers and web servers is sent in plain text

Composed operation: a operation composed of two or more simpler operations

POD: Plain Old Data, a type is a POD when the only things in it are built-in types and combinations of them

Coroutines are program components that generalize subroutines to allow multiple entry points for suspending and resuming execution at certain locations.

socket::iostream, null-buffer, Half duplex protocol

asynchronization & multithread

UDP/TCP examples

// file : tcp-client.cpp
// copied from official website of Boost::asio
#include<iostream>
#include<boost/array.hpp>
#include<boost/asio.hpp> using boost::asio::ip::tcp; int main(int argc, char* argv[])
{
try
{
if (argc != )
{
std::cerr << "Usage: client <host>" << std::endl;
return ;
}
boost::asio::io_service io_service;
tcp::resolver resolver(io_service);
// query(host,service)
// service: time, daytime, http, telnet, ftp, echo, smtp, "80"
// service, A string identifying the requested service.
// This may be a descriptive name or a numeric string corresponding to a port number.
tcp::resolver::query query(argv[], "daytime");
tcp::resolver::iterator endpointer_iterator = resolver.resolve(query);
tcp::socket socket(io_service);
// TCP::endpoint endpoint(boost::asio::ip::address_v4::from_string("127.0.0.1"), 10000);
boost::asio::connect(socket, endpointer_iterator); char a[] = { 'a', 'b' };
socket.write_some(boost::asio::buffer(a)); for (;;)
{
boost::array<char, > buf;
// read(socket, buf)
// read() suuceeds only when he supplied buffers are full.That is, the bytes transferred is equal to the sum of the buffer sizes.
// An error occurred.
boost::system::error_code error;
size_t len = socket.read_some(boost::asio::buffer(buf), error);
std::cout << "lenth is " << len << std::endl;
if (error == boost::asio::error::eof)
break;
else if (error)
{
throw boost::system::system_error(error);
}
std::cout.write(buf.data(), len);
}
}
catch (std::exception &e)
{
std::cerr << e.what() << std::endl;
}
}
#define _CRT_SECURE_NO_WARNINGS
#include<ctime>
#include<iostream>
#include<string>
#include<boost/bind.hpp>
#include<boost/shared_ptr.hpp>
#include<boost/enable_shared_from_this.hpp>
#include<boost/asio.hpp> using boost::asio::ip::tcp;
using boost::asio::ip::udp; std::string make_daytime_string()
{
using namespace std;
time_t now = time();
return ctime(&now);
} class tcp_connection
{
public:
/*
static pointer create(boost::asio::io_service& io_service)
{
return pointer(new tcp_connection(io_service));
}
*/
static tcp_connection * create(boost::asio::io_service& io_service)
{
tcp_connection * pConnection = NULL;
pConnection = new tcp_connection(io_service);
return pConnection;
}
tcp::socket& socket() {return socket_;} void start()
{
char a[] = { '\0' };
socket_.read_some(boost::asio::buffer(a));
std::cout << "get message " << a << std::endl;
message_ = make_daytime_string();
boost::asio::async_write(socket_, boost::asio::buffer(message_),
boost::bind(&tcp_connection::handle_write, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
} private:
tcp_connection(boost::asio::io_service & io_service) :socket_(io_service){}
void handle_write(const boost::system::error_code &, size_t) {
std::cout << "current socket address is " << this->socket_.local_endpoint().address()
<< " prot " << this->socket_.local_endpoint().port() << " finished writing" << std::endl;
}
tcp::socket socket_;
std::string message_;
}; class tcp_server
{
public:
tcp_server(boost::asio::io_service & io_service) : acceptor_(io_service, tcp::endpoint(tcp::v4(), ))
{
start_accept();
}
private:
void start_accept()
{
// without using share_ptr() here will cause mem leak!!!
tcp_connection * new_connection = tcp_connection::create(acceptor_.get_io_service());
// accept() function shall extract the first connection on the queue of pending connections,
// create a new socket with the same socket type protocol and address family as the specified socket,
// and allocate a new file descriptor for that socket
acceptor_.async_accept(new_connection->socket(), boost::bind(&tcp_server::handle_accept, this, new_connection,
boost::asio::placeholders::error));
} void handle_accept(tcp_connection * new_connection,
const boost::system::error_code& error)
{
if (!error)
{
new_connection->start();
}
start_accept();
}
tcp::acceptor acceptor_;
}; class udp_server
{
public:
udp_server(boost::asio::io_service& io_service)
: socket_(io_service, udp::endpoint(udp::v4(), ))
{
start_receive();
} private:
void start_receive()
{
socket_.async_receive_from(
boost::asio::buffer(recv_buffer_), remote_endpoint_,
boost::bind(&udp_server::handle_receive, this,
boost::asio::placeholders::error));
} void handle_receive(const boost::system::error_code& error)
{
if (!error || error == boost::asio::error::message_size)
{
std::cout << this->recv_buffer_ << std::endl;
boost::shared_ptr<std::string> message(
new std::string(make_daytime_string())); socket_.async_send_to(boost::asio::buffer(*message), remote_endpoint_,
boost::bind(&udp_server::handle_send, this, message)); start_receive();
}
} void handle_send(boost::shared_ptr<std::string> /*message*/)
{
} udp::socket socket_;
udp::endpoint remote_endpoint_;
char recv_buffer_ [];
}; int main()
{
try
{
boost::asio::io_service io_service;
tcp_server server(io_service);
udp_server server2(io_service);
io_service.run();
}
catch (std::exception &e)
{
std::cerr << e.what() << std::endl;
}
return ;
}
// file : udp-client.cpp
#include <iostream>
#include <string>
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp> using boost::asio::ip::udp;
using boost::thread; /* one socket, synchronous, serial executtion
int main()
{
boost::asio::io_service io;
udp::socket socket(io);
socket.open(udp::v4());
udp::endpoint endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 13);
while(1)
{
std::string str;
std::cout << "Input string: ";
std::cin >> str;
socket.send_to(boost::asio::buffer(str),endpoint); // receive
char rec_buf[128];
udp::endpoint sender_point;
size_t len = socket.receive_from(boost::asio::buffer(rec_buf), sender_point);
std::cout.write(rec_buf,len);
}
}
*/ /* as socket is not thread-safe, two threads may conflict, add mutext to prevent it;
void rev(udp::socket * socket)
{
while(1)
{
char rec_buf[128];
udp::endpoint sender_point;
// mutext.lock()
size_t len = socket->receive_from(boost::asio::buffer(rec_buf), sender_point);
// mutex.unlock()
std::cout.write(rec_buf,len);
} } int main()
{
boost::asio::io_service io;
udp::socket socket(io);
socket.open(udp::v4());
udp::endpoint endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 13);
thread thr(boost::bind(rev,&socket));
while(1)
{
std::string str;
std::cout << "Input string: ";
std::cin >> str;
// mutex.lock()
socket.send_to(boost::asio::buffer(str),endpoint);
// mutex.unlock()
}
thr.join();
}
*/ /* two sockets, from the result, we know the data supposed to receive is sent to socket1 not socket2
void rev(udp::socket * socket)
{
while(1)
{
char rec_buf[128];
udp::endpoint sender_point;
std::cout << socket->local_endpoint().address() <<" : " << socket->local_endpoint().port()
<< std::endl;
size_t len = socket->receive_from(boost::asio::buffer(rec_buf), sender_point);
std::cout.write(rec_buf,len) << std::endl;
}
} int main()
{
boost::asio::io_service io;
udp::socket socket(io);
udp::socket socket2(io);
socket.open(udp::v4());
socket2.open(udp::v4());
udp::endpoint endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 13);
thread thr(boost::bind(rev,&socket2));
while(1)
{
std::string str;
std::cout << "Input string: ";
std::cin >> str;
socket.send_to(boost::asio::buffer(str),endpoint);
std::cout << socket.local_endpoint().address() << " : " << socket.local_endpoint().port();
}
thr.join();
}
*/ char rec_buf[];
udp::endpoint endpoint(boost::asio::ip::address::from_string("127.0.0.1"), ); void rev(udp::socket * socket);
void on_rec(udp::socket * socket) {
std::cout<<rec_buf<<std::endl;
rev(socket);
} void rev(udp::socket * socket) {
udp::endpoint sender_point;
socket->async_receive_from(boost::asio::buffer(rec_buf), sender_point, boost::bind(on_rec,socket));
} void send(udp::socket *);
void on_send(udp::socket * socket, const boost::system::error_code & error) {
if(!error) {
std::cout << "send the message successfully" << std::endl;
}
send(socket);
}
void send(udp::socket * socket) { std::string str;
std::cout << "Input string: ";
std::cin >> str;
socket->async_send_to(boost::asio::buffer(str),endpoint,boost::bind(on_send, socket, boost::asio::placeholders::error));
} int main()
{
boost::asio::io_service io;
udp::socket socket(io);
socket.open(udp::v4());
io.post(boost::bind(rev,&socket));
send(&socket); thread thr(boost::bind(&boost::asio::io_service::run,&io));
thr.join();
}

to build it:

g++ -o tcp-client tcp-client.cpp -lboost_system -lpthread
g++ -o server server.cpp -lboost_system -lpthread
g++ -o udp-client udp.cpp -lboost_system -lpthread -lboost_thread

boost.Asio lib的更多相关文章

  1. boost::asio译文

        Christopher Kohlhoff Copyright © 2003-2012 Christopher M. Kohlhoff 以Boost1.0的软件授权进行发布(见附带的LICENS ...

  2. boost:asio编译

    参考:http://hi.baidu.com/need_for_dream/blog/item/c14a28086a504c33e92488b5.html 环境: VS2010, boost1.38. ...

  3. How to write simple HTTP proxy with Boost.Asio

    How to write simple HTTP proxy with Boost.Asio How to write simple HTTP proxy with Boost.Asio Russia ...

  4. Boost.Asio技术文档

    Christopher Kohlhoff Copyright © 2003-2012 Christopher M. Kohlhoff 以Boost1.0的软件授权进行发布(见附带的LICENSE_1_ ...

  5. 编译boost asio http/server 方法

    这段时间学习boost 的asio 编程,想编译asio自带的http/server的程序,无奈在网上根本找不到方法,只能自己摸索学习. 登陆boost asio 的example 目录,(我 boo ...

  6. cpprestsdk同时使用boost.asio,acceptor就一直报Invalid argument。

    本文目录,首先总结问题,然后案例还原. 总结: 问题的根本在于boost.asio作为header-only库,运行程序与动态库之间容易因为版本错配而产生运行期莫名其妙的问题. cpprestsdk使 ...

  7. c++ boost asio库初学习

    前些日子研究了一个c++的一个socket库,留下范例代码给以后自己参考. 同步server: // asio_server.cpp : コンソール アプリケーションのエントリ ポイントを定義します. ...

  8. 如何在多线程leader-follower模式下正确的使用boost::asio。

    #include <assert.h> #include <signal.h> #include <unistd.h> #include <iostream& ...

  9. BOOST.Asio——Tutorial

    =================================版权声明================================= 版权声明:原创文章 谢绝转载  啥说的,鄙视那些无视版权随 ...

随机推荐

  1. Linux基础(一)系统api与库函数的关系

    1. 系统api与库函数的关系 man 2 open 1.1 open 1.2 read/write 实现cat功能 #include <stdio.h> #include <uni ...

  2. apt-get使用命令

    apt-get的卸载命令:remove/purge/autoremove/clean/autoclean apt-get purge / apt-get –purge remove 删除已安装包(不保 ...

  3. .Net版微信支付

    一. 案例介绍 这里模拟一个实际业务场景,进行介绍微信支付,业务功能包括:登录.注册.充值.查看充值记录. 页面图:       二. 概要设计 1.数据库设计 这里数据库包括两张表:用户表和订单表. ...

  4. 网易PM599产品笔试题

    前几天做了网易PM599的云计算领域产培生的笔试题目,下面整理了一下各个方向的笔试题和我对这些题目的解答. 云计算领域: 1.对工业互联网的理解,结合自身优势谈谈自己应该怎么去创业. 工业互联网是一次 ...

  5. 开源框架.netCore DncZeus学习(五)下拉树的实现

    千里之行,始于足下,先从一个小功能研究起,在菜单管理页面有一个下拉树,先研究下它怎么实现的 1.先找到menu.vue页面 惯性思维先搜索请选择三个字,原来是动态生成的 再向上找DropDown组件, ...

  6. 使用 Topshelf 结合 Quartz.NET 创建 Windows 服务

    Ø  前言 之前一篇文章已经介绍了,如何使用 Topshelf 创建 Windows 服务.当时提到还缺少一个任务调度框架,就是 Quartz.NET.而本文就展开对 Quartz.NET 的研究,以 ...

  7. Tomcat配置到JEE版eclipse中

    接我上篇文中的tomcat下载,及环境变量配置,http://blog.csdn.net/qq_40223688/article/details/79451468 这篇文章我就讲一下怎么把tomcat ...

  8. 三十七、Linux 线程——线程清理和控制函数、进程和线程启动方式比较、线程的状态转换

    37.1 线程清理和控制函数 #include <pthread.h> void pthread_cleanup_push(void (* rtn)(void *), void *arg) ...

  9. c++ virtual 记录

    虚继承: http://zh.wikipedia.org/wiki/%E8%99%9A%E7%BB%A7%E6%89%BF 解决了菱形继承问题 cB cC 继承cA    cD继承cB,cC    c ...

  10. Hbase使用MapReduce编程导出数据到HDFS

    废话少说,直接上代码! package cn.com.oozie.demo;  import java.io.IOException;  import org.apache.hadoop.conf.C ...