C++03:使用Boost-用Asio实现简易Echo Server

C++03:使用Boost-用Asio实现简易Echo Server

C++03:使用Boost-用Asio实现简易Echo Server

一、编写代码

注:以下代码取自boost 1.40的示例代码:

//
// async_tcp_echo_server.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include <cstdlib>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/asio.hpp>

using boost::asio::ip::tcp;

class session {
public:
    session(boost::asio::io_service& io_service) :
        socket_(io_service) {
    }

    tcp::socket& socket() {
        return socket_;
    }

    void start() {
        socket_.async_read_some(boost::asio::buffer(data_, max_length),
                boost::bind(&session::handle_read, this,
                        boost::asio::placeholders::error,
                        boost::asio::placeholders::bytes_transferred));
    }

    void handle_read(const boost::system::error_code& error,
            size_t bytes_transferred) {
        if (!error) {
            boost::asio::async_write(socket_, boost::asio::buffer(data_,
                    bytes_transferred), boost::bind(&session::handle_write,
                    this, boost::asio::placeholders::error));
        } else {
            delete this;
        }
    }

    void handle_write(const boost::system::error_code& error) {
        if (!error) {
            socket_.async_read_some(boost::asio::buffer(data_, max_length),
                    boost::bind(&session::handle_read, this,
                            boost::asio::placeholders::error,
                            boost::asio::placeholders::bytes_transferred));
        } else {
            delete this;
        }
    }

private:
    tcp::socket socket_;
    enum {
        max_length = 1024
    };
    char data_[max_length];
};

class server {
public:
    server(boost::asio::io_service& io_service, short port) :
        io_service_(io_service), acceptor_(io_service, tcp::endpoint(tcp::v4(),
                port)) {
        session* new_session = new session(io_service_);
        acceptor_.async_accept(new_session->socket(), boost::bind(
                &server::handle_accept, this, new_session,
                boost::asio::placeholders::error));
    }

    void handle_accept(session* new_session,
            const boost::system::error_code& error) {
        if (!error) {
            new_session->start();
            new_session = new session(io_service_);
            acceptor_.async_accept(new_session->socket(), boost::bind(
                    &server::handle_accept, this, new_session,
                    boost::asio::placeholders::error));
        } else {
            delete new_session;
        }
    }

private:
    boost::asio::io_service& io_service_;
    tcp::acceptor acceptor_;
};

int main(int argc, char* argv[]) {
    try {
        if (argc != 2) {
            std::cerr << "Usage: async_tcp_echo_server <port>\n";
            return 1;
        }

        boost::asio::io_service io_service;

        using namespace std;
        // For atoi.
        server s(io_service, atoi(argv[1]));

        io_service.run();
    } catch (std::exception& e) {
        std::cerr << "Exception: " << e.what() << "\n";
    }

    return 0;
}

二、编译代码

$ g++ -g3 -Wall -o"async_tcp_echo_server" async_tcp_echo_server.cpp -lboost_system

注意:boost.asio库依赖boost_system

三、运行 async_tcp_echo_server

$ ./async_tcp_echo_server 8868   # 8868 是async_tcp_echo_server listen的端口号

四、用 telnet 命令作为客户端测试

新开启一个终端,注意:同样要登录到Linux实验室,执行: telnet localhost 8868

$ telnet localhost 8868
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
the first line    # 这是我们的输入
the first line    # 这是服务器 async_tcp_echo_server 的回应,以下类推
the second line
the second line
welcome to xuanyuan-soft.org.cn!
welcome to xuanyuan-soft.org.cn!

五、关于Boost更多的信息

请访问Boost的主页:http://www.boost.org/

posted on 2012-06-27 15:26  lexus 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/lexus/archive/2012/06/27/2565900.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
st_asio_wrapper是一组类,功能是对boost.asio的包装(调试环境:boost-1.51.0),目的是简化boost.asio开发; 其特点是效率高、跨平台、完全异步,当然这是从boost.asio继承而来; 自动重连,数据透明传输,自动解决分包粘包问题(你可以像udp一样使用它); 注:只支持tcp协议; 教程:http://blog.csdn.net/yang79tao/article/details/7724514 1.1版更新内容: 增加了自定义数据模式的支持,可用于st_asio_wrapper server与其它客户端的通信、或者st_asio_wrapper client与其它服务端的通信;当然,两端都是st_asio_wrapper的话,就用透明传输即可(1.0版已经支持了)。 1.2版更新内容: 修复BUG:当stop_service之后,再start_service时,client_base内部某些成员变量可能没有得到复位; 服务端增加修改监听地址功能,当然仍然要在start_service之前调用set_server_addr函数。 1.3版更新内容: 增加自定义消息格式的发送,这个本来是在1.1版本实现的,结果我漏掉了,只实现了自定义消息格式的接收。 1.4版更新内容: 将打包与解包器从client_base分离出来,以简化这个日益复杂的基类; 可以在运行时修改打包解包器。 1.5版更新内容: 增加ipv6支持,默认是ipv4,服务端和客户端都通过设置一个ipv6的地址来开启这个功能; 增加了一些服务端helper函数,小改了一下客户端set_server_addr函数签名(调换了两个参数的位置以保持和服务端一样)。 1.6版更新内容: 增加了接收消息缓存(改动较大,on_msg的语义有所变化,请看开发教程第三篇)。 1.7版更新内容: 修复vc2010下编译错误; 修复默认解包器BUG(同时修改解包器接口); 修复log输出BUG; 更好的包装了服务端类库,现在服务端可以像客户端一样简单的使用了(完全不用继承或者重写虚函数,申请一个对象即可); 结构大调整,类名大调整,请参看开发教程第一篇。 1.8版更新内容: 增加健壮性和稳定性; 退出服务更新优雅。 1.9版更新内容: 提高代码通用性; 可以指定服务端同时投递多少个async_accept; 修复BUG,此BUG可能造成数据发送不完全。 2.0版更新内容: 服务端增加对象池功能; 优化美化代码; 更规范化接口签名。 2.1版更新内容: 修复BUG,此BUG会造成st_client在stop_service之后,仍然可能尝试重新连接服务器; 在消息发送的时候,增加了一个参数can_overflow,用于确定是否在缓存满的时候返回失败,这在某些不能阻塞等待直到缓存可用的场合非常有用,比如on_msg; 当消息接收缓存满的时候,st_socket现在可以保证消息不丢失,之前的行为是调用on_recv_buffer_oveflow之后,丢弃消息; 更规范化接口签名; 更多更新请看st_asio_wrapper_socket.h,所有更新都会罗列在这个头文件的开头处,另外st_asio_wrapper_server.h的开头部分注释也很重要,有工作原理相关的说明。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值