1. boost::asio之socket的創建和連接

網絡編程基本流程

網絡編程的基本流程對于服務端是這樣的
服務端
1)socket——創建socket對象。

2)bind——綁定本機ip+port。

3)listen——監聽來電,若在監聽到來電,則建立起連接。

4)accept——再創建一個socket對象給其收發消息。原因是現實中服務端都是面對多個客戶端,那么為了區分各個客戶端,則每個客戶端都需再分配一個socket對象進行收發消息。

5)read、write——就是收發消息了。

對于客戶端是這樣的
客戶端
1)socket——創建socket對象。

2)connect——根據服務端ip+port,發起連接請求。

3)write、read——建立連接后,就可發收消息了。

圖示如下
在這里插入圖片描述

終端節點的創建

所謂終端節點就是用來通信的端對端的節點,可以通過ip地址和端口構造,其的節點可以連接這個終端節點做通信.
如果我們是客戶端,我們可以通過對端的ip和端口構造一個endpoint,用這個endpoint和其通信。

類"boost:asio:ip:address"沒有成員"from_string”

在這里插入圖片描述


int  client_end_point() {// Step 1. Assume that the client application has already // obtained the IP-address and the protocol port number.std::string raw_ip_address = "127.0.0.1";unsigned short port_num = 3333;// Used to store information about error that happens// while parsing the raw IP-address.boost::system::error_code ec;// Step 2. Using IP protocol version independent address// representation.asio::ip::address ip_address =asio::ip::address::from_string(raw_ip_address, ec);if (ec.value() != 0) {// Provided IP address is invalid. Breaking execution.std::cout<< "Failed to parse the IP address. Error code = "<< ec.value() << ". Message: " << ec.message();return ec.value();}// Step 3.asio::ip::tcp::endpoint ep(ip_address, port_num);// Step 4. The endpoint is ready and can be used to specify a // particular server in the network the client wants to // communicate with.return 0;
}

如果是服務端,則只需根據本地地址綁定就可以生成endpoint


nt  server_end_point(){// Step 1. Here we assume that the server application has//already obtained the protocol port number.unsigned short port_num = 3333;// Step 2. Create special object of asio::ip::address class// that specifies all IP-addresses available on the host. Note// that here we assume that server works over IPv6 protocol.asio::ip::address ip_address = asio::ip::address_v6::any();// Step 3.asio::ip::tcp::endpoint ep(ip_address, port_num);// Step 4. The endpoint is created and can be used to // specify the IP addresses and a port number on which // the server application wants to listen for incoming // connections.return 0;
}

創建socket

創建socket分為4步,創建上下文iocontext,選擇協議,生成socket,打開socket。


int create_tcp_socket() {// Step 1. An instance of 'io_service' class is required by// socket constructor. asio::io_context  ios;// Step 2. Creating an object of 'tcp' class representing// a TCP protocol with IPv4 as underlying protocol.asio::ip::tcp protocol = asio::ip::tcp::v4();// Step 3. Instantiating an active TCP socket object.asio::ip::tcp::socket sock(ios);// Used to store information about error that happens// while opening the socket.boost::system::error_code ec;// Step 4. Opening the socket.sock.open(protocol, ec);if (ec.value() != 0) {// Failed to open the socket.std::cout<< "Failed to open the socket! Error code = "<< ec.value() << ". Message: " << ec.message();return ec.value();}return 0;
}

上述socket只是通信的socket,如果是服務端,我們還需要生成一個acceptor的socket,用來接收新的連接。


int  create_acceptor_socket() {// Step 1. An instance of 'io_service' class is required by// socket constructor. asio::io_context ios;// Step 2. Creating an object of 'tcp' class representing// a TCP protocol with IPv6 as underlying protocol.asio::ip::tcp protocol = asio::ip::tcp::v6();// Step 3. Instantiating an acceptor socket object.asio::ip::tcp::acceptor acceptor(ios);// Used to store information about error that happens// while opening the acceptor socket.boost::system::error_code ec;// Step 4. Opening the acceptor socket.acceptor.open(protocol, ec);if (ec.value() != 0) {// Failed to open the socket.std::cout<< "Failed to open the acceptor socket!"<< "Error code = "<< ec.value() << ". Message: " << ec.message();return ec.value();}return 0;
}

綁定acceptor

對于acceptor類型的socket,服務器要將其綁定到指定的斷點,所有連接這個端點的連接都可以被接收到。


int  bind_acceptor_socket() {// Step 1. Here we assume that the server application has// already obtained the protocol port number.unsigned short port_num = 3333;// Step 2. Creating an endpoint.asio::ip::tcp::endpoint ep(asio::ip::address_v4::any(),port_num);// Used by 'acceptor' class constructor.asio::io_context  ios;// Step 3. Creating and opening an acceptor socket.asio::ip::tcp::acceptor acceptor(ios, ep.protocol());boost::system::error_code ec;// Step 4. Binding the acceptor socket.acceptor.bind(ep, ec);// Handling errors if any.if (ec.value() != 0) {// Failed to bind the acceptor socket. Breaking// execution.std::cout << "Failed to bind the acceptor socket."<< "Error code = " << ec.value() << ". Message: "<< ec.message();return ec.value();}return 0;
}

連接指定的端點

作為客戶端可以連接服務器指定的端點進行連接


int  connect_to_end() {// Step 1. Assume that the client application has already// obtained the IP address and protocol port number of the// target server.std::string raw_ip_address = "127.0.0.1";unsigned short port_num = 3333;try {// Step 2. Creating an endpoint designating // a target server application.asio::ip::tcp::endpointep(asio::ip::address::from_string(raw_ip_address),port_num);asio::io_context ios;// Step 3. Creating and opening a socket.asio::ip::tcp::socket sock(ios, ep.protocol());// Step 4. Connecting a socket.sock.connect(ep);// At this point socket 'sock' is connected to // the server application and can be used// to send data to or receive data from it.}// Overloads of asio::ip::address::from_string() and // asio::ip::tcp::socket::connect() used here throw// exceptions in case of error condition.catch (system::system_error& e) {std::cout << "Error occured! Error code = " << e.code()<< ". Message: " << e.what();return e.code().value();}
}

域名


int dns_connect_to_end() {std::string host = "llfc.club";//域名std::string port_num = "3333";asio::io_context ioc;boost::asio::ip::tcp::resolver resolver(ioc);//asio::ip::tcp::resolver::query resolver_query(host,port_num,asio::ip::tcp::resolver::query::numeric_service);//DNS解析器try{auto endpoints = resolver.resolve(host, port_num);//創建socket并連接到對應的地址asio::ip::tcp::socket sock(ioc);asio::connect(sock, endpoints);}catch (system::system_error& e){std::cout << "Error occured! Error code = " << e.code()<< ". Message: " << e.what();return e.code().value();}
}

服務器接收連接

當有客戶端連接時,服務器需要接收連接


int accept_new_connection(){// The size of the queue containing the pending connection// requests.const int BACKLOG_SIZE = 30;// Step 1. Here we assume that the server application has// already obtained the protocol port number.unsigned short port_num = 3333;// Step 2. Creating a server endpoint.asio::ip::tcp::endpoint ep(asio::ip::address_v4::any(),port_num);asio::io_context  ios;try {// Step 3. Instantiating and opening an acceptor socket.asio::ip::tcp::acceptor acceptor(ios, ep.protocol());// Step 4. Binding the acceptor socket to the // server endpint.acceptor.bind(ep);// Step 5. Starting to listen for incoming connection// requests.acceptor.listen(BACKLOG_SIZE);// Step 6. Creating an active socket.asio::ip::tcp::socket sock(ios);// Step 7. Processing the next connection request and // connecting the active socket to the client.acceptor.accept(sock);// At this point 'sock' socket is connected to //the client application and can be used to send data to// or receive data from it.}catch (system::system_error& e) {std::cout << "Error occured! Error code = " << e.code()<< ". Message: " << e.what();return e.code().value();}
}

關于buffer

任何網絡庫都有提供buffer的數據結構,所謂buffer就是接收和發送數據時緩存數據的結構。
boost::asio提供了asio::mutable_buffer 和 asio::const_buffer這兩個結構,他們是一段連續的空間,首字節存儲了后續數據的長度。
asio::mutable_buffer用于寫服務,asio::const_buffer用于讀服務。但是這兩個結構都沒有被asio的api直接使用。
對于api的buffer參數,asio提出了MutableBufferSequence和ConstBufferSequence概念,他們是由多個asio::mutable_buffer和asio::const_buffer組成的。也就是說boost::asio為了節省空間,將一部分連續的空間組合起來,作為參數交給api使用。
我們可以理解為MutableBufferSequence的數據結構為std::vectorasio::mutable_buffer
結構如下

在這里插入圖片描述
每隔vector存儲的都是mutable_buffer的地址,每個mutable_buffer的第一個字節表示數據的長度,后面跟著數據內容。
這么復雜的結構交給用戶使用并不合適,所以asio提出了buffer()函數,該函數接收多種形式的字節流,該函數返回asio::mutable_buffers_1 o或者asio::const_buffers_1結構的對象。
如果傳遞給buffer()的參數是一個只讀類型,則函數返回asio::const_buffers_1 類型對象。
如果傳遞給buffer()的參數是一個可寫類型,則返回asio::mutable_buffers_1 類型對象。
asio::const_buffers_1和asio::mutable_buffers_1是asio::mutable_buffer和asio::const_buffer的適配器,提供了符合MutableBufferSequence和ConstBufferSequence概念的接口,所以他們可以作為boost::asio的api函數的參數使用。
簡單概括一下,我們可以用buffer()函數生成我們要用的緩存存儲數據。
比如boost的發送接口send要求的參數為ConstBufferSequence類型

在這里插入圖片描述
在這里插入圖片描述


void use_stream_buffer() {asio::streambuf buf;std::ostream output(&buf);// Writing the message to the stream-based buffer.output << "Message1\nMessage2";// Now we want to read all data from a streambuf// until '\n' delimiter.// Instantiate an input stream which uses our // stream buffer.std::istream input(&buf);// We'll read data into this string.std::string message1;std::getline(input, message1);// Now message1 string contains 'Message1'.
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/90214.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/90214.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/90214.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

WPF 控制動畫開關

記錄一種實現方式&#xff1a;第一步&#xff1a;首先定義一個靜態類&#xff0c;提供依賴屬性&#xff0c;進而方便在xaml中實現綁定&#xff1a;public static class AnimationBehavior{// 定義附加屬性public static readonly DependencyProperty IsAnimatingProperty Depen…

元素豎向的百分比設定是相對于父容器的高度嗎?

元素豎向的百分比設定是相對于父容器的高度嗎&#xff1f; 核心問題 在CSS中&#xff0c;當設置元素的豎向屬性&#xff08;如height、padding-top等&#xff09;為百分比值時&#xff0c;其計算基準是父容器的高度還是寬度&#xff1f; 權威結論height屬性 百分比值基于父容器…

web3.0怎么入局

Web3.0(第三代互聯網)融合了區塊鏈、去中心化應用(DApps)、NFT、DAO等新興技術,給個人和機構提供了許多全新的賺錢機會。入局 Web3.0 賺錢主要有以下幾種途徑,根據你的技術背景、資金能力和時間投入可以選擇適合自己的方式。 目錄 一、普通用戶賺錢方式(門檻低) 1. …

linux入門 相關linux系統操作命令(二)--文件管理系統 ubuntu22.04

以下有免費的4090云主機提供ubuntu22.04系統的其他入門實踐操作 地址&#xff1a;星宇科技 | GPU服務器 高性能云主機 云服務器-登錄 相關兌換碼星宇社區---4090算力卡免費體驗、共享開發社區-CSDN博客 兌換碼要是過期了&#xff0c;可以私信我獲取最新兌換碼&#xff01;&a…

Python-初學openCV——圖像預處理(二)

目錄 一、圖像仿射變換 1、基本性質 二、cv2.warpAffine() 函數 1、圖像旋轉 2、圖像平移 3、圖像縮放 4、圖像剪切 三、 插值方法 1、最近鄰插值 2、雙線性插值 3、像素區域插值 4、雙三次插值 5、Lanczos插值 一、圖像仿射變換 仿射變換&#xff08;Affine Tr…

醫療AI輕量化部署方案的深度梳理與優化路徑判研

摘要 醫療AI的快速發展為精準診斷、個性化治療和醫療資源優化提供了新機遇。然而,大規模模型的高計算復雜度和資源需求限制了其在資源受限環境(如邊緣設備、基層醫療機構)的應用。本文系統梳理了醫療AI輕量化部署的核心技術體系,包括模型壓縮、參數高效微調(PEFT)、邊緣-…

SSP通過SDK對接流量的原理與實現

一、核心概念解析 1.1 SSP&#xff08;供應方平臺&#xff09; 定義&#xff1a;SSP是程序化廣告生態中媒體方的核心工具&#xff0c;通過自動化技術幫助媒體&#xff08;如網站、應用、視頻平臺&#xff09;管理廣告資源、優化填充率并最大化廣告收益。核心功能&#xff1a;…

如何清理電腦c盤內存 詳細操作步驟

電腦使用時間不斷延長&#xff0c;許多用戶可能會遇到一個問題——C盤空間不足&#xff0c;導致系統運行緩慢或無法安裝新程序。如果C盤的存儲空間被大量占用&#xff0c;可能會影響到計算機的性能。本文將介紹幾種有效的方法&#xff0c;幫助你清理C盤內存&#xff0c;釋放空間…

ESP32的ADF詳解:5. Streams的API

一、算法流 (algorithm stream) 1. 初始化與配置API功能描述關鍵參數說明algo_stream_init()初始化算法流&#xff08;AEC/AGC/NS/VAD&#xff09;config->algo_mask 選擇算法組合config->sample_rate 設置采樣率&#xff08;默認16kHz&#xff09;config->partition_…

JavaScript對象鍵序問題解析

問題的發現&#xff1a; 我有一個接口返回一個json數據瀏覽器network里的Response里是從大到小排。 但Preview就是反過來的 問題的描述&#xff1a; 上面那個讓我發現瀏覽器處理對象或者json是會對其鍵值對做排序&#xff01;&#xff01;&#xff01; 在JavaScript中&am…

pandas庫的數據導入導出,缺失值,重復值處理和數據篩選,matplotlib庫 簡單圖繪制

目錄 一.數據導入導出 1.CSV文件讀取與參數說明 2.Excel與TST文件讀取 3.數據導出操作 二.缺失值處理 1.填充缺失值 2.刪除缺失值【刪除整行數據】 三.重復值處理 四.數據篩選與條件查詢 1.邏輯判斷取數 2.字符匹配 3.邏輯運算&#xff1a; &&#xff08;和&…

FPGA?如何實現另一個?FPGA?

如果你對 FPGA 有些了解&#xff0c;大概知道它的意思是“可編程邏輯器件”&#xff0c;可以把寫好的邏輯電路&#xff08;通常是 Verilog/VHDL&#xff09;通過工具綜合、布局布線、燒寫進去&#xff0c;讓一塊芯片變成“你想要的電路”。但如果我告訴你&#xff0c;現在有個開…

文思助手、新華妙筆 AI材料星的公文寫作深度測評

公文寫作一直都是體制內工作人員的日常核心任務&#xff0c;寫公文的難點不僅來自于對政策表述嚴謹性的高要求&#xff0c;也在于格式規范、內容深度以及效率壓力的多重考驗。隨著AI技術的發展&#xff0c;越來越多的文字輔助工具出現&#xff0c;很大程度的緩解了寫作壓力&…

Flutter開發環境搭建與工具鏈

Flutter開發實戰第1章&#xff1a;Flutter開發環境搭建與工具鏈1.1 Flutter簡介與優勢Flutter是Google推出的開源UI工具包&#xff0c;用于從單一代碼庫構建編譯為原生性能的移動、Web和桌面應用程序。Flutter的核心優勢包括&#xff1a;跨平臺一致性&#xff1a;一套代碼運行在…

io_uring:Linux異步I/O的革命性突破

目錄 1. io_uring是什么&#xff1f; io_uring核心優勢&#xff1a; 2. io_uring核心原理 2.1 雙環形緩沖區設計 2.2 關鍵數據結構 1、完成隊列CQ 2、提交隊列SQ 3、Params 3. io_uring工作流程 3.1 初始化階段 3.2 I/O操作流程 4. C代碼示例&#xff08;原始系統調…

線段樹學習筆記 - 練習題(2)

文章目錄1. 前言2. P3870 [TJOI2009] 開關3. P2184 貪婪大陸4. P1438 無聊的數列5. P1471 方差1. 前言 線段樹系列文章&#xff1a; 線段樹學習筆記。線段樹學習筆記 - 練習題&#xff08;1&#xff09;。 前一篇做了幾道線段樹的題目&#xff0c;這篇文章就繼續看下線段樹的…

Vue狀態管理:Pinia 與 Vuex 的使用方法與對比【文章附有完整案例】

最近在接手vue項目的需求&#xff0c;因為之前一直在做react的需求&#xff0c;日常的vue練習也少了很多&#xff0c;導致現在接手vue項目&#xff0c;很多關于vue的知識點基本上忘得干干凈凈了。但是好在有基礎&#xff0c;重新學也會很快掌握。分享這個過程中的一些復習內容。…

OpenMed 項目深度分析:推動醫療 NLP 領域的開源革命

摘要 醫療人工智能(AI)領域因高質量數據和模型的獲取受限而發展緩慢。OpenMed 項目通過開源超過380個醫療命名實體識別(NER)模型,顯著降低了研究與應用門檻。本文從項目背景、技術優勢、應用場景、實施挑戰及未來展望五個方面,系統分析 OpenMed 的核心價值與潛力,揭示其…

大模型開發

什么是Ai&#xff1f;AI的全拼是(Artificial Intelligence)人工智能&#xff0c;使機器能夠像人類一樣思考、學習和解決問題的技術。在AI的應用情況下我們更多的是學習自然語言處理。在自然語言處理(Natural Language Processing&#xff0c;NLP)中&#xff0c;有一項關鍵技術叫…

【正常配置了beast擴展,phpinfo信息也顯示了,但是就是不運行】

正常配置了beast擴展&#xff0c;phpinfo信息也顯示了&#xff0c;但是就是不運行場景原因解決排查過程擴展場景 項目中使用到了beast進行源碼保護&#xff0c;指定類存在&#xff0c;但是報錯信息提示類找不到&#xff0c;beast擴展添加到了正在運行的php版本下的ext文件夾下…