linux下使用boost库编写TCP客户端/服务器程序官方简易教程

来源:互联网 发布:牛客网算法视频下载 编辑:程序博客网 时间:2024/06/05 11:44

1.同步方式的TCP-daytime 客户端

源码文件g.cpp
#include <iostream>
#include <boost/array.hpp>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
int main(int argc, char* argv[])
{
  try
  {
    if (argc != 2)     //为客户端指定一个服务器
    {
      std::cerr << "Usage: client <host>" << std::endl;
      return 1;
    }
    boost::asio::io_service io_service;     //使用boost::asio的程序至少需要一个io_service对象
    tcp::resolver resolver(io_service);    //用来将服务器名转换成一个TCP的endpoint(端点)
    tcp::resolver::query query(argv[1], "daytime");    //resolver需要一个query对象作为参数,来解析出与服务器名相关的endpoint(端点)
    tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);    //得到endpoint列表的迭代器,以供套接字连接使用
    tcp::socket socket(io_service);    //获得一个套接字
    boost::asio::connect(socket, endpoint_iterator);    //将此套接字与endpoint列表中的端点尝试建立连接
    for (;;)
    {
      boost::array<char, 128> buf;    //此处可用char[ ],也可用 std::vector
      boost::system::error_code error;
      size_t len = socket.read_some(boost::asio::buffer(buf), error);    //boost::asio::buffer()函数知道buf的长度,可防止buffer溢出
      if (error == boost::asio::error::eof)    //服务器断开连接的话,ip::tcp::socket::read_some()会产生boost::asio::error::eof error
        break;     // 此时可以结束循环读取
      else if (error)
        throw boost::system::system_error(error); // 发生其它错误
      std::cout.write(buf.data(), len);    //将读到的数据打印到屏幕
    }
  }
  catch (std::exception& e)
  {
    std::cerr << e.what() << std::endl;    //输出错误内容
  }
  return 0;
}

编译:g++ g.cpp -lboost_system -lpthread -o g.out
======================================================================================

2.同步方式的TCP-daytime服务器


源文件h.cpp
#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));    //acceptor对象用来监听新连接,初始化在端口13,ipv4上
 
  for(;;){
   tcp::socket socket(io_service);    //创建一个套接字
   acceptor.accept(socket);    //接受新的连接
   std::string message = make_daytime_string();
   boost::system::error_code ignore_error;
   boost::asio::write(socket, boost::asio::buffer(message), ignore_error);    //发送信息到socket
  }
 }
 catch (std::exception &e){
  std::cerr << e.what() << std::endl;
 }
 return 0;
}
编译:g++ h.cpp -lboost_system -lpthread -o h.out
======================================================================================

3.异步方式的TCP-daytime服务器


源码k.cpp
#include <ctime>
#include <iostream>
#include <string>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>

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

std::string make_daytime_string()    //生成字符串的日期信息
{
  using namespace std; // For time_t, time and ctime;
  time_t now = time(0);
  return ctime(&now);
}

//这个类之所以要使用shared_ptr和enable_shared_from_this是为了保证tcp_connection对象在有对其引用时一直存活
class tcp_connection
  : public boost::enable_shared_from_this<tcp_connection>
{
public:
  typedef boost::shared_ptr<tcp_connection> pointer;
  static pointer create(boost::asio::io_service& io_service)
  {
    return pointer(new tcp_connection(io_service));    //返回新连接的共享指针
  }
  tcp::socket& socket()
  {
    return socket_;
  }
  void start()    //通过此方法向连接套接字发送字符信息
  {
    message_ = make_daytime_string();
    boost::asio::async_write(socket_, boost::asio::buffer(message_),
        boost::bind(&tcp_connection::handle_write, shared_from_this(),
          boost::asio::placeholders::error,
          boost::asio::placeholders::bytes_transferred));    /*异步写操作,handle_write()是执行完异步写操作后进一步的操作;这里的boost::asio::placeholders是占位符,因为handle_write()操作对这两个参数没有使用,因此编译时可能被删掉*/
  }
private:
  tcp_connection(boost::asio::io_service& io_service)
    : socket_(io_service)    //socket由连接套接字初始化,即boost中的acceptor的io_service对象
  {
  }

  void handle_write(const boost::system::error_code& /*error*/,
      size_t /*bytes_transferred*/)
  {
  }
  tcp::socket socket_;
  std::string message_;
};
class tcp_server
{
public:
  tcp_server(boost::asio::io_service& io_service)
    : acceptor_(io_service, tcp::endpoint(tcp::v4(), 13))    //初始化一个接收器,监听TCP端口13
  {
    start_accept();
  }
private:
  void start_accept()
  {
    tcp_connection::pointer new_connection =
      tcp_connection::create(acceptor_.get_io_service());    //创建一个连接套接字
    acceptor_.async_accept(new_connection->socket(),
        boost::bind(&tcp_server::handle_accept, this, new_connection,
          boost::asio::placeholders::error));    //初始化异步监听操作动作handle_accept()
  }
  void handle_accept(tcp_connection::pointer new_connection,
      const boost::system::error_code& error)    //当监听到一个连接时,执行这个操作动作
  {
    if (!error)
    {
      new_connection->start();    //执行新连接的start()函数
    }
    start_accept();    //监听新的客户连接
  }
  tcp::acceptor acceptor_;
};
int main()
{
  try
  {
    boost::asio::io_service io_service;    //io_service对象提供IO服务,例如套接字
    tcp_server server(io_service);
    io_service.run();    //运行io_service对象,由它代替你执行异步操作
  }
  catch (std::exception& e)
  {
    std::cerr << e.what() << std::endl;
  }
  return 0;
}

编译:g++ k.cpp -lpthread -lboost_system -o k.out
0 0
原创粉丝点击