C++網(wǎng)絡(luò)編程詳細(xì)講解_第1頁(yè)
C++網(wǎng)絡(luò)編程詳細(xì)講解_第2頁(yè)
C++網(wǎng)絡(luò)編程詳細(xì)講解_第3頁(yè)
C++網(wǎng)絡(luò)編程詳細(xì)講解_第4頁(yè)
C++網(wǎng)絡(luò)編程詳細(xì)講解_第5頁(yè)
已閱讀5頁(yè),還剩1頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第C++網(wǎng)絡(luò)編程詳細(xì)講解目錄一、網(wǎng)絡(luò)編程二、庫(kù)示例練習(xí)

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

盡管Boost.Asio可以異步處理任何類型的數(shù)據(jù),但它主要用于網(wǎng)絡(luò)編程。這是因?yàn)锽oost.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ò)客戶端

#includeboost/asio/io_service.hpp

#includeboost/asio/write.hpp

#includeboost/asio/buffer.hpp

#includeboost/asio/ip/tcp.hpp

#includearray

#includestring

#includeiostream

usingnamespaceboost::asio;

usingnamespaceboost::asio::ip;

io_serviceioservice;

tcp::resolverresolv{ioservice};

tcp::sockettcp_socket{ioservice};

std::arraychar,4096bytes;

voidread_handler(constboost::system::error_codeec,

std::size_tbytes_transferred)

if(!ec)

std::cout.write(bytes.data(),bytes_transferred);

tcp_socket.async_read_some(buffer(bytes),read_handler);

voidconnect_handler(constboost::system::error_codeec)

if(!ec)

std::stringr=

"GET/HTTP/1.1\r\nHost:\r\n\r\n";

write(tcp_socket,buffer(r));

tcp_socket.async_read_some(buffer(bytes),read_handler);

voidresolve_handler(constboost::system::error_codeec,

tcp::resolver::iteratorit)

if(!ec)

tcp_socket.async_connect(*it,connect_handler);

intmain()

tcp::resolver::queryq{"","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解析名稱。異步操作啟動(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ù)器

#includeboost/asio/io_service.hpp

#includeboost/asio/write.hpp

#includeboost/asio/buffer.hpp

#includeboost/asio/ip/tcp.hpp

#includestring

#includectime

usingnamespaceboost::asio;

usingnamespaceboost::asio::ip;

io_serviceioservice;

tcp::endpointtcp_endpoint{tcp::v4(),2014};

tcp::acceptortcp_acceptor{ioservice,tcp_endpoint};

tcp::sockettcp_socket{ioservice};

std::stringdata;

voidwrite_handler(constboost::system::error_codeec,

std::size_tbytes_transferred)

if(!ec)

tcp_socket.shutdown(tcp::socket::shutdown_send);

voidaccept_handler(constboost::system::error_codeec)

if(!ec)

std::time_tnow=std::time(nullptr);

data=std::ctime(now);

async_write(tcp_socket,buffer(data),write_handler);

intmain()

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í),

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論