记录 boost 中 使用 asio 编写 server和client代码片段
server:
//
// async_udp_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::udp;
class server
{
public:
server(boost::asio::io_service& io_service, short port)
: io_service_(io_service),
socket_(io_service, udp::endpoint(udp::v4(), port))
{
socket_.async_receive_from(
boost::asio::buffer(data_, max_length), sender_endpoint_,
boost::bind(&server::handle_receive_from, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void handle_receive_from(const boost::system::error_code& error,
size_t bytes_recvd)
{
if (!error && bytes_recvd > 0)
{
data_[bytes_recvd] = '\0';
std::cout<<data_<<", "<<std::endl;
socket_.async_send_to(
boost::asio::buffer(data_, bytes_recvd), sender_endpoint_,
boost::bind(&server::handle_send_to, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else
{
socket_.async_receive_from(
boost::asio::buffer(data_, max_length), sender_endpoint_,
boost::bind(&server::handle_receive_from, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
}
void handle_send_to(const boost::system::error_code& /*error*/,
size_t /*bytes_sent*/)
{
socket_.async_receive_from(
boost::asio::buffer(data_, max_length), sender_endpoint_,
boost::bind(&server::handle_receive_from, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
private:
boost::asio::io_service& io_service_;
udp::socket socket_;
udp::endpoint sender_endpoint_;
enum { max_length = 1024 };
char data_[max_length];
};
int main(int argc, char* argv[])
{
try
{
boost::asio::io_service io_service;
using namespace std; // For atoi.
server s(io_service, 9999);
io_service.run();
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "\n";
}
return 0;
}
client:
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <vector>
using boost::asio::ip::udp;
enum { max_length = 1024 };
class databuf
{
public:
char* buf;
boost::int32_t len;
public:
databuf(boost::int32_t alen)
{
buf = (char*)malloc(alen == 0 ? alen + 1 : alen);
len = alen;
}
public:
virtual unsigned char* data() { return (unsigned char*)buf;}
};
typedef boost::shared_ptr<boost::asio::io_service> io_service_ptr;
class client : public boost::enable_shared_from_this<client>
{
public:
client(io_service_ptr io_service_)
:ptr_io_service(io_service_)
,s(*ptr_io_service, udp::endpoint(udp::v4(), 0))
{
udp::resolver resolver(*ptr_io_service);
udp::resolver::query query(udp::v4(), "127.0.0.1", "9999");
itr = resolver.resolve(query);
}
void begin()
{
ptr_io_service->post(boost::bind(&client::send_data
, shared_from_this()));
}
static int get_request_id()
{
int ret;
{
boost::mutex::scoped_lock l(mutex_request_id_seq_);
req_index_ ++;
if (req_index_ == 0) {
req_index_++;
}
ret = req_index_;
//std::cout<<req_index_<<", "<<std::endl;
}
return ret;
}
void show()
{
std::vector<boost::shared_ptr<databuf> >::iterator it = vv.begin();
for (;it != vv.end();++it)
{
unsigned char* p = (*it)->data();
p[2] = '\0';
std::cout<<p<<std::endl;
}
}
void send_data()
{
if (req_index_ >= 30)
{
show();
}
std::stringstream str_data;
str_data.str("");
str_data<< get_request_id() <<"\0";
strcpy(request1, str_data.str().c_str());
s.async_send_to(boost::asio::buffer(request1, str_data.str().size()),
*itr, boost::bind(&client::recive_data, shared_from_this()));
std::stringstream str_data1;
str_data1.str("");
str_data1<< get_request_id();
str_data1<<"\0";
strcpy(request2, str_data1.str().c_str());
s.async_send_to(boost::asio::buffer(request2, str_data1.str().size()),
*itr, boost::bind(&client::recive_data, shared_from_this()));
}
void recive_data()
{
boost::shared_ptr<databuf> ss = boost::make_shared<databuf>(65535);
vv.push_back(ss);
s.async_receive_from(boost::asio::buffer(ss->data(), max_length),
endpoint_remote_,
boost::bind(&client::send_data, shared_from_this()));
}
private:
io_service_ptr ptr_io_service;
udp::socket s;
boost::asio::ip::udp::endpoint endpoint_remote_;
udp::resolver::iterator itr;
char request1[max_length];
char request2[max_length];
char request3[max_length];
std::string req;
static volatile int req_index_;
static boost::mutex mutex_request_id_seq_;
std::vector<boost::shared_ptr<databuf> > vv;
};
boost::mutex client::mutex_request_id_seq_;
volatile int client::req_index_(0);
void work_run(io_service_ptr io_ser)
{
io_ser->run();
}
int main()
{
io_service_ptr ptr_io_service = boost::make_shared<boost::asio::io_service>();
boost::asio::io_service::work work_(*ptr_io_service);
boost::thread th(boost::bind(&work_run, ptr_io_service));
boost::shared_ptr<client> ptr_cli = boost::make_shared<client>(ptr_io_service);
ptr_cli->begin();
getchar();
return 0;
}
tips:仅供个人学习测试用,记录下来,源码来自boost 官网和网上。