首先 这篇文章是基于 这里 这篇文章, 我自己抽取的部分内容.高手请移步上面链接吧. 感谢原文作者和译者.
boost::asio
1 . 提供了管理需要长时间运行操作的工具,但是不一定涉及到线程的并发模式和显示锁定
2 . 使用C++实现,提供如网络编程等操作系统的常用编程接口.
对于同步操作流程图:
可以看出来,应用程序跟操作系统打交道,要有一个io 对象, socket. 应用程序与操作系统交互需要通过 io 服务,就是 io_service
boost::asio::io_service io_service;
boost::asio::ip::tcp::socket socket(io_service); //用io_service 初始化 tcp::socket
与服务器通信需要以下步骤:
1. 应用程序通过调用IO对象初始化连接步骤:
socket.connect(server_endPoint);
2. IO对象向io_service提出请求
3. io_service条用操作系统接口执行连接操作
4. 操作系统向io_service 返回执行结果
5. io_service将错误的操作结果翻译成boost::system::error_code类型,error_code 与特定值比较,检测执行过程,结果返回给io对象.
6. 如果操作失败,io对象抛出boost::system::system_error类型的异常.
开始操作的代码如下所示:
boost::system::error_code ec;
socket.connect( server_endpoint, ec );
而后,error_code类型的变量ec被赋予操作的结果值,但不会抛出异常.
同步TCP daytime客户端
#include<iostream.h>
#include<boost/asio.hpp>
#include<boost/array.hpp>
程序的目的是要访问daytime服务器,因此需要用户指定一个服务器.
using boost::asio::ip::tcp;
int main(int argc, char *argv[])
{
try{
if( 2 != argc ){
std::err<<" Usage : client <host>"<<std::endl;
return 1;
}
//所有asio 的程序都有一个io_service对象
boost::asio::io_service io_service;
//我们需要将程序参数中指定的服务器名称转换成tcp端点,因此需要定义一个ip::tcp::resolver对象
tcp::resolver resolver( io_service );
//分析器使用一个查询对象获取一个端点列表,使用服务器的名称( argv[1] )和服务名称( daytime )作为参数来构造查询对象.
tcp::resolver::query query( argv[1], "daytime" );
//返回的端点列表为ip::tcp::resolver::iterater类型的迭代器.
tcp::resolver::iterater endPoint_iterater = resolver.resolve( query );
//现在创建并连接socket,上述的端点列表可能包括ipv4 或者ipv6类型的端点, 需要尝试每种可能,获取可用的端点.这样客户端就独立于ip的版本号了.boost::asio::connect()自动完成这些功能.
tcp::socket socket( io_service );
boost::asio::conect( socket, endPoint_iterater );
//连接已打开 现在可以从服务器读取数据了
//使用boost::array 来接收数据, boost::asio::buffer()自动管理数组大小,防止缓冲区溢出.除了boost::array还可以使用char []或者std::vector来接收
for(; ; ){
boost::array<char, 128> buf;
boost::system::errer_code ec;
size_t length = socket::read_some( boost::asio::buffer( buf ), ec);
//当服务器关闭了连接,socket::read_some方法接收到boost::asio::error::eof消息时,退出客户端循环
if ( ec == boost::asio::error::eof ){
break; //connection closed and clearly by peer.
}else if ( ec ){
throw boost::system::system_error( ec ); //Some Other Error.
std::cout.write( buf.data, len );
}
}catch( std::exception &e ){
std::cerr<<e.what() <<std::endl;
}
}
}
TCP daytime同步服务器 本例阐述如何使用boost::asio 实现 tcp 服务端程序
#include <ctime>
#include<iostream>
#include<string>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
//定义一个生成发送给客户端的字符串的方法
std::string make_daytime_string()
{
using namespace std;
time_t now = time( 0 );
return ctime( &now );
}
int main()
{
try {
boost::asio::io_service io_service;
tcp::acceptor acceptor( io_service, tcp::endpoint( tcp::v4(), 13 ) );
//这是个可迭代的服务端,即每次只处理一个连接.对每个客户端连接创立一个socket, 而后等待新到来的连接
for( ; ; ) {
tcp::socket socket( io_service );
acceptor.accept( socket );
//客户端访问服务端,把时间传给客户端
std::string message = make_daytime_string();
boost::system::errer_code ec_ignored;
boost::asio::write( socket, boost::asio::buffer( message ), ec_ignored );
}
} catch( std::exception &e ) {
std::cerr<< e.what()<<std::endl;
}
return 0;
}