您的位置:首頁 > 教程 > C語言教程 > boost.asio框架系列之socket編程

boost.asio框架系列之socket編程

2022-06-18 17:50:37 來源:易采站長站 作者:

boost.asio框架系列之socket編程

asio的主要用途還是用于socket編程,本文就以一個tcp的daytimer服務為例簡單的演示一下如何實現同步和異步的tcp socket編程。lec站長之家-易采站長站-Easck.Com

客戶端

客戶端的代碼如下:lec站長之家-易采站長站-Easck.Com

    #include <iostream>
    #include <boost/array.hpp>
    #include <boost/asio.hpp>

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

    int main(int argc, char* argv[])
    {
        try
        {
            boost::asio::io_service io_service;
            tcp::endpoint end_point(boost::asio::ip::address::from_string("127.0.0.1"), 3200);

            tcp::socketsocket(io_service);
            socket.connect(end_point);

            for (;;)
            {
                boost::array<char, 128> buf;
                boost::system::error_code error;

                size_t len = socket.read_some(boost::asio::buffer(buf), error);

                if (error == boost::asio::error::eof)
                    break; // Connection closed cleanly by peer.
                else if (error)
                    throw boost::system::system_error(error); // Some other error.

                std::cout.write(buf.data(), len);
            }
        }
        catch (std::exception& e)
        {
            std::cerr << e.what() << std::endl;
        }

        return 0;
    }

主要流程如下:lec站長之家-易采站長站-Easck.Com

    通過tcp::socket類定義一個tcp client對象socketlec站長之家-易采站長站-Easck.Com

    通過connect函數連接服務器,打開socket連接。lec站長之家-易采站長站-Easck.Com

    通過read_some函數來讀數據lec站長之家-易采站長站-Easck.Com

    另外,還可以通過write_some來寫數據,通過close來關閉socket連接(這里是通過釋放socket對象隱式釋放連接)。lec站長之家-易采站長站-Easck.Com

    服務器

    服務器代碼如下:lec站長之家-易采站長站-Easck.Com

        #include <ctime>
        #include <iostream>
        #include <string>
        #include <boost/asio.hpp>
    
        using namespace boost;
        using boost::asio::ip::tcp;
    
        int main()
        {
            try
            {
                asio::io_service io_service;
                tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 3200));
    
                for (;;)
                {
                    tcp::socket socket(io_service);
                    acceptor.accept(socket);
    
                    time_t now = time(0);
                    std::string message = ctime(&now);
    
                    system::error_code ignored_error;
                    socket.write_some(asio::buffer(message), ignored_error);
                }
            }
            catch (std::exception& e)
            {
                std::cerr << e.what() << std::endl;
            }
    
            return 0;
        }

    主要流程如下:lec站長之家-易采站長站-Easck.Com

      通過tcp::acceptor類創建一個tcp server對象,并綁定端口(也可以不在構造器中自動綁定,而通過bind函數手動綁定)lec站長之家-易采站長站-Easck.Com

      通過accept函數獲取遠端連接lec站長之家-易采站長站-Easck.Com

      通過遠端連接的write_some函數將數據發往客戶端lec站長之家-易采站長站-Easck.Com

      異步服務器

      前面的服務器是同步版本,在大并發的場景下一般需要用到異步socket。服務器的異步版本如下:lec站長之家-易采站長站-Easck.Com

          #include <ctime>
          #include <iostream>
          #include <string>
          #include <memory>
          #include <functional>
          #include <boost/asio.hpp>
      
          using boost::asio::ip::tcp;
          using namespace std;
      
          void process_client(shared_ptr<tcp::socket> client)
          {
              time_t now = time(0);
              shared_ptr<string> message(new string(ctime(&now)));
      
              auto callback = [=](const boost::system::error_code& err ,size_t size)
              {
                  if ((int)size == message->length())
                      cout << "write completed" << endl;
              };
      
              client->async_send(boost::asio::buffer(*message), callback);
          }
      
          typedef function<void (const boost::system::error_code&)> accept_callback;
          void start_accept(tcp::acceptor& server)
          {
              shared_ptr<tcp::socket> client(new tcp::socket(server.get_io_service()));
              accept_callback callback = [&server, client](const boost::system::error_code& error)
                  {
                      if (!error)
                          process_client(client);
      
                      start_accept(server);
                  };
      
              server.async_accept(*client, callback);
          }
      
          int main()
          {
              try
              {
                  boost::asio::io_service io_service;
                  tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 3200));
                  start_accept(acceptor);
                  io_service.run();
              }
              catch (std::exception& e)
              {
                  std::cerr << e.what() << std::endl;
              }
              return 0;
          }

      這個異步版本的邏輯倒不是很復雜,基本上和.net中傳統的異步socket相似,不過需要注意的是,由于c++中內存需要自己管理,而asio框架也沒有提供任何管理機制,因此需要注意async_accept、async_send等函數的參數生命周期,切記不能在里面傳入棧變量的引用。如果是堆變量,需要確保釋放,本例中我是通過share_ptr來實現的自動釋放。lec站長之家-易采站長站-Easck.Com

      到此這篇關于boost.asio框架系列之socket編程的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支持易采站長站。lec站長之家-易采站長站-Easck.Com

      如有侵權,請聯系QQ:279390809 電話:15144810328

相關文章

  • VS2019項目打包生成.exe文件與Setup的步驟實現

    VS2019項目打包生成.exe文件與Setup的步驟實現

    對于Visual Studio Installer ,我們通常稱為:setup項目,是一個用于自定義安裝部署的項目方案。但是在VS2019中不見了,微軟是有意廢除安裝項目的,合作了一個第三方的安裝項目單獨使用。
    2020-03-13
  • 基于c++ ege圖形庫實現五子棋游戲

    基于c++ ege圖形庫實現五子棋游戲

    本文分享的五子棋實例,制作基于ege圖像庫, 首先需要安裝配置ege環境 就可以編寫小游戲了. 用到的ege庫函數不多 , 主要是基于c++的. 先看界面效果: 輸入界面:(就是控制臺) 游戲勝利界面
    2020-01-06
  • C++基于easyx圖形庫實現推箱子游戲

    C++基于easyx圖形庫實現推箱子游戲

    本文實例為大家分享了C++實現推箱子游戲的具體代碼,供大家參考,具體內容如下 頭文件: #includestdio.h#includestdlib.h//#includeWindows.h#includeconio.h#includegraphics.h#includestdbool.h //播放音樂需要
    2020-06-30
  • VS2019 Nuget找不到包的問題處理

    VS2019 Nuget找不到包的問題處理

    VS不記得改了什么設置之后,發現找不到EF 解決辦法 1、點擊右側的設置按鈕 2、彈出窗中左側樹形結構選擇“程序包源”,再點擊右上方的添加按鈕 輸入一下信息:https://www.nuget.org/a
    2020-03-27
  • visual studio2019的安裝以及使用圖文步驟詳解

    visual studio2019的安裝以及使用圖文步驟詳解

    一、下載安裝包 下載地址 選擇visual studio 2019的community版本 二、下載好后運行 三、組件的選擇 如果是用來學CC++的話,選擇以下兩個就夠了 之后如果還需要其他一些功能的話,可以后
    2020-03-08
  • VScode編譯C++ 頭文件顯示not found的問題

    VScode編譯C++ 頭文件顯示not found的問題

    一直用codeblocks,想試試vscode,結果這個問題給我弄懵逼了。一開始以為是iostream這個頭文件not found,后來發現第一個頭文件都會這樣顯示,放到后面就不會了,然而,光這一個顯示not
    2020-03-20
  • C++多線程獲取返回值方法詳解

    C++多線程獲取返回值方法詳解

    在許多時候,我們會有這樣的需求——即我們想要得到線程返回的值。但是在C++11 多線程中我們注意到,std::thread對象會忽略頂層函數的返回值。 那問題來了,我們要怎么獲得線程的返
    2020-06-25
  • JVM系列之String.intern的性能解析

    JVM系列之String.intern的性能解析

    String對象有個特殊的StringTable字符串常量池,為了減少Heap中生成的字符串的數量,推薦盡量直接使用String Table中的字符串常量池中的元素。 那么String.intern的性能怎么樣呢?我們一起來
    2020-06-23
色七七影院_香港三级台湾三级在线播放_男人放进女人阳道猛进猛出