最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++網(wǎng)絡(luò)編程詳細(xì)講解

 更新時(shí)間:2022年10月31日 10:39:23   作者:無(wú)水先生  
計(jì)算機(jī)是通過(guò)TCP/IP協(xié)議進(jìn)行互聯(lián)從而進(jìn)行通信的,為了把復(fù)雜的TCP/IP協(xié)議隱藏起來(lái),更方便的實(shí)現(xiàn)計(jì)算機(jī)中兩個(gè)程序進(jìn)行通信,引出了socket這個(gè)概念

一、網(wǎng)絡(luò)編程

盡管 Boost.Asio 可以異步處理任何類型的數(shù)據(jù),但它主要用于網(wǎng)絡(luò)編程。這是因?yàn)?Boost.Asio 早在添加額外的 I/O 對(duì)象之前就支持網(wǎng)絡(luò)功能。網(wǎng)絡(luò)函數(shù)非常適合異步操作,因?yàn)橥ㄟ^(guò)網(wǎng)絡(luò)傳輸數(shù)據(jù)可能需要很長(zhǎng)時(shí)間,這意味著確認(rèn)和錯(cuò)誤可能不會(huì)像發(fā)送或接收數(shù)據(jù)的函數(shù)那樣快。

二、庫(kù)示例

Boost.Asio 提供了許多 I/O 對(duì)象來(lái)開發(fā)網(wǎng)絡(luò)程序。示例 32.5 使用類 boost::asio::ip::tcp::socket 與另一臺(tái)計(jì)算機(jī)建立連接。此示例向網(wǎng)絡(luò)服務(wù)器發(fā)送 HTTP 請(qǐng)求以下載主頁(yè)。

示例 32.5。帶有 boost::asio::ip::tcp::socket 的網(wǎng)絡(luò)客戶端

#include <boost/asio/io_service.hpp>
#include <boost/asio/write.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <array>
#include <string>
#include <iostream>
using namespace boost::asio;
using namespace boost::asio::ip;
io_service ioservice;
tcp::resolver resolv{ioservice};
tcp::socket tcp_socket{ioservice};
std::array<char, 4096> bytes;
void read_handler(const boost::system::error_code &ec,
  std::size_t bytes_transferred)
{
  if (!ec)
  {
    std::cout.write(bytes.data(), bytes_transferred);
    tcp_socket.async_read_some(buffer(bytes), read_handler);
  }
}
void connect_handler(const boost::system::error_code &ec)
{
  if (!ec)
  {
    std::string r =
      "GET / HTTP/1.1\r\nHost: theboostcpplibraries.com\r\n\r\n";
    write(tcp_socket, buffer(r));
    tcp_socket.async_read_some(buffer(bytes), read_handler);
  }
}
void resolve_handler(const boost::system::error_code &ec,
  tcp::resolver::iterator it)
{
  if (!ec)
    tcp_socket.async_connect(*it, connect_handler);
}
int main()
{
  tcp::resolver::query q{"theboostcpplibraries.com", "80"};
  resolv.async_resolve(q, resolve_handler);
  ioservice.run();
}

Example32.5

示例 32.5 使用了三個(gè)處理程序:connect_handler() 和 read_handler() 在建立連接并接收到數(shù)據(jù)時(shí)被調(diào)用。 resolve_handler() 用于名稱解析。

因?yàn)橹挥性诮⑦B接之后才能接收數(shù)據(jù),并且因?yàn)橹挥性诮馕雒Q之后才能建立連接,所以各種異步操作都是在處理程序中啟動(dòng)的。在 resolve_handler() 中,指向從名稱解析的端點(diǎn)的迭代器 it 與 tcp_socket 一起用于建立連接。在 connect_handler() 中,訪問 tcp_socket 以發(fā)送 HTTP 請(qǐng)求并開始接收數(shù)據(jù)。由于所有操作都是異步的,處理程序被傳遞給各自的函數(shù)。根據(jù)操作,可能需要傳遞其他參數(shù)。例如,迭代器它指的是從名稱解析的端點(diǎn)。數(shù)組字節(jié)用于存儲(chǔ)接收到的數(shù)據(jù)。

在 main() 中,boost::asio::ip::tcp::resolver::query 被實(shí)例化以創(chuàng)建對(duì)象 q。 q 表示對(duì)名稱解析器的查詢,一個(gè)類型為 boost::asio::ip::tcp::resolver 的 I/O 對(duì)象。通過(guò)將 q 傳遞給 async_resolve(),啟動(dòng)異步操作來(lái)解析名稱。示例 32.5 解析名稱 theboostcpplibraries.com。異步操作啟動(dòng)后,在 I/O 服務(wù)對(duì)象上調(diào)用 run() 以將控制權(quán)傳遞給操作系統(tǒng)。

解析名稱后,將調(diào)用 resolve_handler()。處理程序首先檢查名稱解析是否成功。在這種情況下,ec 為 0。只有這樣才能訪問套接字以建立連接。要連接的服務(wù)器地址由第二個(gè)參數(shù)提供,其類型為 boost::asio::ip::tcp::resolver::iterator。該參數(shù)是名稱解析的結(jié)果。

對(duì) async_connect() 的調(diào)用之后是對(duì)處理程序 connect_handler() 的調(diào)用。再次首先檢查 ec 以確定是否可以建立連接。如果是這樣,則在套接字上調(diào)用 async_read_some()。通過(guò)此調(diào)用,開始讀取數(shù)據(jù)。接收到的數(shù)據(jù)存儲(chǔ)在數(shù)組字節(jié)中,作為第一個(gè)參數(shù)傳遞給 async_read_some()。

當(dāng)接收到一個(gè)或多個(gè)字節(jié)并將其復(fù)制到字節(jié)時(shí)調(diào)用 read_handler()。 std::size_t 類型的參數(shù) bytes_transferred 包含已接收的字節(jié)數(shù)。像往常一樣,處理程序應(yīng)該首先檢查異步操作是否成功完成。只有在這種情況下,才會(huì)將數(shù)據(jù)寫入標(biāo)準(zhǔn)輸出。

請(qǐng)注意,在將數(shù)據(jù)寫入 std::cout 后,read_handler() 會(huì)再次調(diào)用 async_read_some()。這是必需的,因?yàn)槟鸁o(wú)法確定整個(gè)主頁(yè)是否已在單個(gè)異步操作中下載并復(fù)制到字節(jié)中。對(duì) async_read_some() 的重復(fù)調(diào)用和對(duì) read_handler() 的重復(fù)調(diào)用僅在連接關(guān)閉時(shí)結(jié)束,這發(fā)生在網(wǎng)絡(luò)服務(wù)器發(fā)送整個(gè)主頁(yè)時(shí)。然后 read_handler() 在 ec 中報(bào)告錯(cuò)誤。此時(shí),不會(huì)向 std::cout 寫入更多數(shù)據(jù),并且不會(huì)在套接字上調(diào)用 async_read()。因?yàn)闆]有掛起的異步操作,程序退出。

示例 32.6。具有 boost::asio::ip::tcp::acceptor 的時(shí)間服務(wù)器

#include <boost/asio/io_service.hpp>
#include <boost/asio/write.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <string>
#include <ctime>
using namespace boost::asio;
using namespace boost::asio::ip;
io_service ioservice;
tcp::endpoint tcp_endpoint{tcp::v4(), 2014};
tcp::acceptor tcp_acceptor{ioservice, tcp_endpoint};
tcp::socket tcp_socket{ioservice};
std::string data;
void write_handler(const boost::system::error_code &ec,
  std::size_t bytes_transferred)
{
  if (!ec)
    tcp_socket.shutdown(tcp::socket::shutdown_send);
}
void accept_handler(const boost::system::error_code &ec)
{
  if (!ec)
  {
    std::time_t now = std::time(nullptr);
    data = std::ctime(&now);
    async_write(tcp_socket, buffer(data), write_handler);
  }
}
int main()
{
  tcp_acceptor.listen();
  tcp_acceptor.async_accept(tcp_socket, accept_handler);
  ioservice.run();
}

Example32.6

示例 32.6 是一個(gè)時(shí)間服務(wù)器。您可以連接 telnet 客戶端以獲取當(dāng)前時(shí)間。之后時(shí)間服務(wù)器關(guān)閉。

時(shí)間服務(wù)器使用 I/O 對(duì)象 boost::asio::ip::tcp::acceptor 來(lái)接受來(lái)自另一個(gè)程序的傳入連接。您必須初始化對(duì)象,以便它知道在哪個(gè)端口上使用哪個(gè)協(xié)議。在示例中,boost::asio::ip::tcp::endpoint 類型的變量 tcp_endpoint 用于告訴 tcp_acceptor 在端口 2014 上接受 Internet 協(xié)議版本 4 的傳入連接。

接收器初始化后,調(diào)用listen() 使接收器開始監(jiān)聽。然后調(diào)用 async_accept() 以接受第一次連接嘗試。必須將套接字作為第一個(gè)參數(shù)傳遞給 async_accept(),該參數(shù)將用于在新連接上發(fā)送和接收數(shù)據(jù)。

一旦另一個(gè)程序建立連接,就會(huì)調(diào)用accept_handler()。如果連接建立成功,當(dāng)前時(shí)間會(huì)通過(guò) boost::asio::async_write() 發(fā)送。此函數(shù)將 data 中的所有數(shù)據(jù)寫入套接字。 boost::asio::ip::tcp::socket 還提供了成員函數(shù) async_write_some()。此函數(shù)在至少發(fā)送一個(gè)字節(jié)時(shí)調(diào)用處理程序。然后處理程序必須檢查發(fā)送了多少字節(jié)以及還需要發(fā)送多少字節(jié)。然后,它必須再次調(diào)用 async_write_some()。使用 boost::asio::async_write() 可以避免重復(fù)計(jì)算要發(fā)送的字節(jié)數(shù)和調(diào)用 async_write_some()。使用此函數(shù)開始的異步操作僅在數(shù)據(jù)中的所有字節(jié)都發(fā)送完畢后才完成。

發(fā)送數(shù)據(jù)后,會(huì)調(diào)用 write_handler()。該函數(shù)使用參數(shù) boost::asio::ip::tcp::socket::shutdown_send 調(diào)用shutdown(),表示程序已完成通過(guò)套接字發(fā)送數(shù)據(jù)。由于沒有待處理的異步操作,示例 32.6 退出。請(qǐng)注意,雖然 data 僅在 accept_handler() 中使用,但它不能是局部變量。數(shù)據(jù)通過(guò) boost::asio::buffer() 引用傳遞到 boost::asio::async_write()。當(dāng) boost::asio::async_write() 和 accept_handler() 返回時(shí),異步操作已開始,但尚未完成。數(shù)據(jù)必須存在,直到異步操作完成。如果數(shù)據(jù)是一個(gè)全局變量,這是有保證的。

練習(xí)

開發(fā)可以將文件從一臺(tái)計(jì)算機(jī)傳輸?shù)搅硪慌_(tái)計(jì)算機(jī)的客戶端和服務(wù)器。當(dāng)服務(wù)器啟動(dòng)時(shí),它應(yīng)該顯示所有本地接口的 IP 地址列表并等待客戶端連接。當(dāng)客戶端啟動(dòng)時(shí),來(lái)自服務(wù)器的 IP 地址和本地文件的名稱應(yīng)作為命令行選項(xiàng)傳遞。客戶端應(yīng)將文件傳輸?shù)椒?wù)器,服務(wù)器將其保存到當(dāng)前工作目錄。在傳輸期間,客戶端應(yīng)該顯示某種進(jìn)度指示器,以便用戶知道傳輸正在進(jìn)行中。使用回調(diào)實(shí)現(xiàn)客戶端和服務(wù)器。

到此這篇關(guān)于C++網(wǎng)絡(luò)編程詳細(xì)講解的文章就介紹到這了,更多相關(guān)C++網(wǎng)絡(luò)編程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言詳解如何應(yīng)用模擬字符串和內(nèi)存函數(shù)

    C語(yǔ)言詳解如何應(yīng)用模擬字符串和內(nèi)存函數(shù)

    這篇文章主要介紹了C語(yǔ)言詳解如何應(yīng)用模擬字符串和內(nèi)存函數(shù),文章有點(diǎn)長(zhǎng),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-02-02
  • C++中內(nèi)存池和內(nèi)存分配區(qū)Arena概念詳解

    C++中內(nèi)存池和內(nèi)存分配區(qū)Arena概念詳解

    在 C++ 中,內(nèi)存分配區(qū)(Arena)通常指的是預(yù)先分配的一大塊連續(xù)內(nèi)存空間,這種方法的主要目的是提高內(nèi)存分配和釋放的效率,下面就跟隨小編一起了解一下C++中內(nèi)存池和內(nèi)存分配區(qū)Arena相關(guān)概念吧
    2023-12-12
  • C語(yǔ)言 動(dòng)態(tài)分配數(shù)組案例詳解

    C語(yǔ)言 動(dòng)態(tài)分配數(shù)組案例詳解

    這篇文章主要介紹了C語(yǔ)言 動(dòng)態(tài)分配數(shù)組案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • 解讀C++編程中類模板的三種特化

    解讀C++編程中類模板的三種特化

    這篇文章主要介紹了C++編程中類模板的三種特化,需要的朋友可以參考下
    2016-01-01
  • C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)中定位函數(shù)Index的使用方法

    C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)中定位函數(shù)Index的使用方法

    這篇文章主要介紹了C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)中定位函數(shù)Index的使用方法的相關(guān)資料,希望通過(guò)本文能幫助到大家,讓大家理解這部分內(nèi)容,需要的朋友可以參考下
    2017-10-10
  • 手把手教你實(shí)現(xiàn)漂亮的Qt?登錄界面

    手把手教你實(shí)現(xiàn)漂亮的Qt?登錄界面

    最近在使用Qt5,Qt?Creator做一個(gè)管理系統(tǒng)類的項(xiàng)目,需要用到登錄界面,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • C++?自定義單向鏈表?ListNode詳情

    C++?自定義單向鏈表?ListNode詳情

    這篇文章主要介紹了C++?自定義單向鏈表?ListNode詳情,文章將介紹鏈表中不帶頭結(jié)點(diǎn),沒有存放鏈表長(zhǎng)度的節(jié)點(diǎn),從頭結(jié)點(diǎn)開始就存放數(shù)據(jù)得一種,具有一定得參考價(jià)值,需要的小伙伴可以參考一下
    2022-03-03
  • C++線程池實(shí)現(xiàn)代碼

    C++線程池實(shí)現(xiàn)代碼

    C++11中,線程我們可以理解為對(duì)應(yīng)一個(gè)thread對(duì)象,任務(wù)可以理解為要執(zhí)行的函數(shù),通常是耗時(shí)的函數(shù)。線程過(guò)多或者頻繁創(chuàng)建和銷毀線程會(huì)帶來(lái)調(diào)度開銷,進(jìn)而影響緩存局部性和整體性能
    2021-12-12
  • C++核心編程之內(nèi)存分區(qū)詳解

    C++核心編程之內(nèi)存分區(qū)詳解

    這篇文章主要為大家詳細(xì)介紹了C++核心編程之內(nèi)存分區(qū),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-03-03
  • C++中delete指針后最好將其置空的操作方法

    C++中delete指針后最好將其置空的操作方法

    C++編程中,當(dāng)你使用delete運(yùn)算符釋放指針?biāo)赶虻膬?nèi)存后,通常將該指針置空,如果一個(gè)指針在被刪除后沒有置空,而你在代碼的其他部分再次嘗試刪除同一個(gè)指針,可能會(huì)導(dǎo)致程序崩潰或產(chǎn)生未定義行為,本文介紹C++中delete指針后最好將其置空的操作方法,感興趣的朋友一起看看吧
    2024-06-06

最新評(píng)論

绵阳市| 彩票| 青阳县| 长乐市| 茌平县| 无极县| 奉贤区| 孟津县| 河池市| 灵川县| 莎车县| 五台县| 沙坪坝区| 大田县| 东源县| 皮山县| 麦盖提县| 时尚| 久治县| 阿拉善左旗| 金门县| 铅山县| 永顺县| 项城市| 金坛市| 大同市| 广水市| 运城市| 三穗县| 酒泉市| 安远县| 衡南县| 临朐县| 子洲县| 深水埗区| 威信县| 无极县| 元朗区| 千阳县| 镇雄县| 青龙|