linux下使用boost庫編寫TCP客戶端/伺服器程式官方簡易教程 阿新 • • 發佈:2019-01-24 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