1. 程式人生 > >linux下使用boost庫編寫TCP客戶端/伺服器程式官方簡易教程

linux下使用boost庫編寫TCP客戶端/伺服器程式官方簡易教程

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