当前位置:编程学习 > C/C++ >>

boost------asio库的使用2(Boost程序库完全开发指南)读书笔记

网络通信

asio库支持TCP、UDP、ICMP通信协议,它在名字空间boost::asio::ip里提供了大量的网络通信方面的函数和类,很好地封装了原始的Berkeley Socket Api,展现给asio用户一个方便易用且健壮的网络通信库。

 


ip::tcp类是asio网络通信(TCP)部分主要的类,但它本身并没有太多的功能,而是定义了数个用于TCP通信的typedef类型,用来协作完成网络通信。这些typedef包括端点类endpoint、套接字类socket、流类iostream,以及接收器acceptor、解析器resolver等等。从某种程度上来看,ip::tcp类更像是一个名字空间。

 

1、IP地址和端点
IP地址独立于TCP、UDP等通信协议,asio库使用类ip::address来表示IP地址,可以同时支持ipv4和ipv6两种地址。

[cpp]
#include "stdafx.h"  
#include "boost/asio.hpp"  
#include "boost/date_time/posix_time/posix_time.hpp"  
#include "boost/bind.hpp"  
#include "boost/function.hpp"  
#include "iostream"  
using namespace std; 
 
 
int _tmain(int argc, _TCHAR* argv[]) 

    boost::asio::ip::address addr;          // 声明一个ip地址对象  
    addr = addr.from_string("127.0.0.1");   // 从字符串产生IP地址  
    assert(addr.is_v4());                   // ipv4的地址  
    cout << addr.to_string() << endl; 
 
    addr = addr.from_string("2000:0000:0000:0000:0001:2345:6789:abcd"); 
    assert(addr.is_v6()); 
    cout << addr.to_string() << endl; 
 
    return 0; 

#include "stdafx.h"
#include "boost/asio.hpp"
#include "boost/date_time/posix_time/posix_time.hpp"
#include "boost/bind.hpp"
#include "boost/function.hpp"
#include "iostream"
using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{
 boost::asio::ip::address addr;   // 声明一个ip地址对象
 addr = addr.from_string("127.0.0.1"); // 从字符串产生IP地址
 assert(addr.is_v4());     // ipv4的地址
 cout << addr.to_string() << endl;

 addr = addr.from_string("2000:0000:0000:0000:0001:2345:6789:abcd");
 assert(addr.is_v6());
 cout << addr.to_string() << endl;

 return 0;
}

 

有了IP地址,再加上通信用的端口号就构成了一个socket端点,在asio库中用ip::tcp::endpoint类来表示。它的主要用法就是通过构造函数创建一个可用于socket通信的端点对象,端点的地址和端口号可以用address()和port()获得:

 


[cpp]
#include "stdafx.h"  
#include "boost/asio.hpp"  
#include "boost/date_time/posix_time/posix_time.hpp"  
#include "boost/bind.hpp"  
#include "boost/function.hpp"  
#include "iostream"  
using namespace std; 
 
 
int _tmain(int argc, _TCHAR* argv[]) 

    boost::asio::ip::address addr;          // 声明一个ip地址对象  
    addr = addr.from_string("127.0.0.1");   // 从字符串产生IP地址  
 
    boost::asio::ip::tcp::endpoint ep(addr, 6688); 
 
    assert(ep.address() == addr); 
    assert(ep.port() == 6688); 
 
    return 0; 

#include "stdafx.h"
#include "boost/asio.hpp"
#include "boost/date_time/posix_time/posix_time.hpp"
#include "boost/bind.hpp"
#include "boost/function.hpp"
#include "iostream"
using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{
 boost::asio::ip::address addr;   // 声明一个ip地址对象
 addr = addr.from_string("127.0.0.1"); // 从字符串产生IP地址

 boost::asio::ip::tcp::endpoint ep(addr, 6688);

 assert(ep.address() == addr);
 assert(ep.port() == 6688);

 return 0;
}

 

 

2、同步socket处理

ip::tcp的内部类型socket、acceptor和resolver是asio库TCP通信中最核心的一组类,它们封装了socket的连接、断开和数据收发功能,使用它们可以很容易地编写出socket程序。

 


socket类是TCP通信的基本类,调用成员函数connect()可以连接到一个指定的通信端点,连接成功后用local_endpoint()和remote_endpoint()获得连接两端的端点信息,用read_some()和write_some()阻塞读写数据,当操作完成后使用close()函数关闭socket。如果不关闭socket,那么在socket对象析构时也会自动调用close()关闭。

 


acceptor类对应socketAPI的accept()函数功能,它用于服务器端,在指定的端口号接受连接,必须配合socket类才能完成通信。

 


resolver类对应socketAPI的getaddrinfo()系列函数,用于客户端解析网址获得可用的IP地址,解析得到的IP地址可以使用socket对象连接。

 


下面是一个使用socket类和acceptor类来实现一对同步通信的服务器和客户端程序:

服务器端(它使用一个acceptor对象在6688端口接受连接,当有连接时使用一个socket对象发送一个字符串):

 


server.cpp:

[cpp]
// server.cpp : 定义控制台应用程序的入口点。  
//  
 
#include "stdafx.h"  
#include "boost/asio.hpp"  
#include "boost/date_time/posix_time/posix_time.hpp"  
#include "boost/bind.hpp"  
#include "boost/function.hpp"  
#include "iostream"  
using namespace std; 
 
 
int _tmain(int argc, _TCHAR* argv[]) 

    try 
    { 
        cout << "server start" << endl; 
        boost::asio::io_service ios; 
 
        boost::asio::ip::tcp::acceptor acceptor(ios,  
            boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 6688)); 
 
        cout << acceptor.local_endpoint().address() << endl; 
 
        while (true) 
        { 
            boost::asio::ip::tcp::socket sock(ios); 
            acceptor.accept(sock); 
 
            cout << "client : "; 
            cout << sock.remote_endpoint().address() << endl; 
 
            sock.write_some(boost::asio::buffer("hello asio")); 
        } 

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,