开源项目(库)之boost:asio学习(1)

开源项目(库)之boost::asio学习(一)

boost::asio库是一个很牛逼的库,想必接触过boost::asio开发过的人都应该有这种感觉,前段时间在项目中使用了下boost::asio库,给我的第一感觉就是boost::asio封装已到达如此的地步,于是勾起了我想要深入学习boost::asio库的冲动,好了,总结下之前在项目中使用boost::asio的一些案例,这些案例也是上网看到的,但是之后的一些编程实例,都是在这些案例上不断修改完善而得到的,先来看几个比较基础的代码吧

1)同步的boost::asio

服务器端代码

#include <iostream>
#include <boost/asio.hpp>

int main(int argc,char* argv[])
{
    using namespace boost::asio;
    io_service iosev;
    ip::tcp::acceptor acceptor(iosev,ip::tcp::endpoint(ip::tcp::v4(),9999));
    for(;;)
    {
        ip::tcp::socket socket(iosev);
        acceptor.accept(socket);
        std::cout<<socket.remote_endpoint().address()<< std::endl;
        boost::system::error_code ecode;
        socket.write_some(buffer("my name is zmyer"),ecode);
        if(ecode)
        {
            std::cout<<boost::system::system_error(ecode).what()<<std::endl;
            break;
        }
    }
    return 0;
}

客户端代码:

#include<iostream>
#include<boost/asio.hpp>

int main(int argc,char*argv[])
{
    using namespace boost::asio;
    io_service ioserv;
    ip::tcp::socket socket(ioserv);
    ip::tcp::endpoint epoint(ip::address_v4::from_string("127.0.0.1"),9999);
    boost::system::error_code ecode;
    socket.connect(epoint,ecode);
    if(ecode)
    {
        std::cout<<boost::system::system_error(ecode).what()<<std::endl;
        return -1;
    }
#define MAX_BUFFERSIZE 1024
    char buff[MAX_BUFFERSIZE];
    bzero(buff,sizeof(buff));
    size_t len = socket.read_some(buffer(buff),ecode);
    std::cout.write(buff,len);
    std::cout.write("\n",1);
    return 0;
}
上述代码很简单,下面我们就将这个案例修改为一个简单版的回显服务器吧,代码如下:

服务器端代码:

#include <iostream>
#include <unistd.h>
#include <boost/asio.hpp>

int main(int argc,char* argv[])
{
    using namespace boost::asio;
    io_service iosev;
    ip::tcp::acceptor acceptor(iosev,ip::tcp::endpoint(ip::tcp::v4(),9999));
    for(;;)
    {
        pid_t forkid;
        ip::tcp::socket socket(iosev);
        acceptor.accept(socket);
        std::cout<<socket.remote_endpoint().address()<< std::endl;
        forkid = fork();
        if(forkid == -1)
            break;
        else if(forkid ==0)
        {
            for(;;)
            {
                boost::system::error_code ecode;
#define MAX_BUFFERSIZE 1024
                char buff[MAX_BUFFERSIZE];
                bzero(buff,sizeof(buff));
                size_t len = socket.read_some(buffer(buff),ecode);
                if(ecode)
                {
                    std::cout<<boost::system::system_error(ecode).what()<<std::endl;
                    break;
                }
                std::cout.write(buff,len);
                std::cout.write("\n",1);

                socket.write_some(buffer(buff),ecode);
                if(ecode)
                {
                    std::cout<<boost::system::system_error(ecode).what()<<std::endl;
                    break;
                }
            }
        }
    }
    return 0;
}

客户端代码:

#include<iostream>
#include<boost/asio.hpp>

int main(int argc,char*argv[])
{
    using namespace boost::asio;
    io_service ioserv;
    ip::tcp::socket socket(ioserv);
    ip::tcp::endpoint epoint(ip::address_v4::from_string("127.0.0.1"),9999);
    boost::system::error_code ecode;
    socket.connect(epoint,ecode);
    if(ecode)
    {
        std::cout<<boost::system::system_error(ecode).what()<<std::endl;
        return -1;
    }
#define MAX_BUFFERSIZE 1024
    char buff[MAX_BUFFERSIZE];
    bzero(buff,sizeof(buff));
    while(1)
    {
        std::cin.getline(buff,sizeof(buff));
        socket.write_some(buffer(buff),ecode);
        bzero(buff,sizeof(buff));
        size_t len = socket.read_some(buffer(buff),ecode);
        std::cout.write(buff,len);
        std::cout.write("\n",1);
    }
    return 0;
}

这个回显服务器写的比较的简单,里面使用了子进程,也许你会感到很疑惑,父进程和子进程共用了一个socket接口。其实在fork完之后,在子进程的文件描述符表里面就已经有socket的副本了,好好地体会吧。

总结

      本篇博文主要是针对boost::asio库的同步机制写了几个简单点的程序,从这些程序中,我们可以初步了解boost::asio接口的一些基本用法,原本打算将上述的代码改进成聊天室,但是发现在实现中遇到了一个boost::asio库的底层问题,目前还在解决中,暂且不贴这部分代码,好了,这篇博文主要是一个开场,在后续的博文中,我们会陆续学习一些boost::asio库,好了,本篇博文到此结束。

如果需要,请注明转载,多谢