久久精品国产精品国产精品污,男人扒开添女人下部免费视频,一级国产69式性姿势免费视频,夜鲁夜鲁很鲁在线视频 视频,欧美丰满少妇一区二区三区,国产偷国产偷亚洲高清人乐享,中文 在线 日韩 亚洲 欧美,熟妇人妻无乱码中文字幕真矢织江,一区二区三区人妻制服国产

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Boost.Asio 技术文档

發布時間:2024/3/26 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Boost.Asio 技术文档 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Christopher Kohlhoff

Copyright ? 2003-2012 Christopher M. Kohlhoff

以Boost1.0的軟件授權進行發布(見附帶的LICENSE_1_0.txt文件或從http://www.boost.org/LICENSE_1_0.txt)

Boost.Asio是用于網絡和低層IO編程的跨平臺C++庫,為開發者提供了C++環境下穩定的異步模型.

綜述

基本原理

應用程序與外界交互的方式有很多,可通過文件,網絡,串口或控制臺.例如在網絡通信中,完成獨立的IO操作需要很長時間.對應用程序開發者提出了一個挑戰.

Boost.Asio 提供了管理需長時間運行操作的工具,但不必涉及到線程的并發模式和顯式鎖定.

Boost.Asio 庫使用C++來實現,提供如網絡編程等常用的操作系統接口. Boost.Asio實現了如下目標:

· 可移植性Portability.庫支持一系列的常用系統操作,具有穩定的跨平臺特性.

· 可擴展性Scalability.庫可以幫助開發者構建數千并發連接的網絡應用程序.asio庫實現的每個系統操作都使用了最具擴展性的機制.

· 效率Efficiency.庫支持發散聚合IO(scatter-gather I/O)等技術,使應用程序盡量少的拷貝數據.

· 可以像BSD Sockets一樣通過API函數建立模型概念. BSD Socket API應用廣泛,有很多相關的程序庫.其他編程語言通常也使用其簡單的網絡API接口.出于這些原因, Boost.Asio同樣使用這種已存在的技術進行構建.

· 易于使用Ease of use.庫提供了工具箱而不是框架來降低新手入門門檻.使用最少時間投入來學習基本的規則和方針.而后,庫的使用者只需要理解用到的特定函數即可.

· 基于更多的抽象.Basis for further abstraction.asio庫提供了高層次的抽象允許其他開發者對庫進行擴展.例如,實現常用的HTTP協議.

雖然Boost.Asio一開始定位于網絡通信,但其異步IO的概念已經擴展到了如串口通信,文件描述符等其他操作系統的IO操作方面.

核心概念和功能

解析Boost.Asio

Boost.Asio 可用于如socket等IO對象的同步或異步操作.在使用Boost.Asio前首先了解一下Boost.Asio概念圖, 以及與應用程序的相互集成方式.

第一個范例,看看處理socket連接的情況.首先從同步操作開始.

應用程序必須有一個io_service對象. io_service對象負責連接應用程序與操作系統的IO服務.

boost::asio::io_service io_service;

要執行IO操作應用程序需要一個像TCP Socket的IO對象:

boost::asio::ip::tcp::socket socket(io_service);

而后執行同步連接操作,發送如下事件:

1. 應用程序調用IO對象的初始化連接操作:

socket.connect(server_endpoint);

2. IO對象向io_service 提出請求.

3. io_service 調用操作系統的功能執行連接操作.

4. 操作系統向io_service 返回執行結果.

5. io_service將錯誤的操作結果翻譯為boost::system::error_code類型. error_code可與特定值進行比較,或作為boolean值檢測(false表示無錯誤).結果再傳遞給IO對象.

6. 如果操作失敗,IO對象拋出boost::system::system_error類型的異常.開始操作的代碼如下所示:

boost::system::error_code ec;

socket.connect(server_endpoint, ec);

而后error_code類型的變量ec被賦予操作的結果值,但不會拋出異常.

對于異步操作,事件順序有所不同.

1. 應用程序調用IO對象進行連接操作:

socket.async_connect(server_endpoint, your_completion_handler);

your_completion_handler函數的簽名為:

void your_completion_handler(const boost::system::error_code& ec);

執行的異步操作需要嚴格的函數簽名.每種操作的合法形式可見參考文檔.

2. IO對象請求io_service的服務.

3. io_service 通知操作系統其需要開始一個異步連接.

時序過程:(在同步情況下等待包括連接操作時間.)

4. 操作系統指示連接操作完成, io_service從隊列中獲取操作結果.

5. 應用程序必須調用io_service::run()(io_service相似的成員函數)以便于接收結果.調用io_service::run()會阻塞應用程序等待未完成的異步操作,因此可在啟動第一個異步操作后調用這個函數.

6. 調用io_service::run()后,io_service返回一個操作結果,并將其翻譯為error_code,傳遞到事件處理器中.

這是Boost.Asio的簡單圖形.更多特性可從文檔中獲取,如使用Boost.Asio執行其他類型的異步操作.

Proactor設計模式:無線程并發

Boost.Asio庫同時支持同步和異步操作.異步支持基于Proactor設計模式.下面討論這種方式與同步操作及Reactor方式相比的優缺點.

Proactor和Boost.Asio

現在討論Proactor不依賴于平臺細節的特性.

Proactor 設計模式

異步操作:定義一個異步執行操作,如Socket異步讀寫.

異步操作處理器:執行異步操作,并在操作完成后執行完成事件隊列中的隊列事件.從更高層次上說,服務端的stream_socket_service 就是一個異步操作處理器.

完成事件隊列:存放完成事件,這些事件會被異步事件信號分離器移出隊列.

完成句柄:異步操作完成后執行的函數.這是一個函數對象,通常使用boost::bind創建.

異步事件信號分離器:在完成事件隊列中阻塞等待事件,受信后向調用者返回完成事件.

Proactor :調用異步事件信號分離器將相應的處理事件移出隊列,并為這個事件分配一個完成句柄(如調用函數對象).這個功能封裝在io_service類中.

初始化器: 執行特定程序代碼啟動異步操作.初始化器通過如basic_stream_socket等高層次接口與異步操作處理器交互,并返回stream_socket_service等類型的服務端代理.

使用Reactor的實現

在很多平臺上Boost.Asio按照Reactor機制實現Proactor設計模式,如select,epoll或kqueue等.相對于Proactor,其實現方式如下:

異步操作處理器:Reactor使用select,epoll或kqueue機制實現.如果reactor指示運行操作的資源已經就位,處理器執行異步操作并在完成事件隊列中插入相應的完成句柄.

完成事件隊列:存放完成句柄的鏈表(如函數對象).

異步事件信號分離器:在事件或條件變量上等待,直到完成事件隊列中的完成句柄可用.

實現Windows的重疊IO

在Windows NT,2000,和XP系統中, Boost.Asio使用重疊IO高效實現了Proactor設計模式:

異步操作處理器:由操作系統實現.調用如AcceptEx等重疊函數進行初始化.

完成事件隊列:由操作系統實現,與IO的完成端口相關聯.每個io_service實例對應一個IO完成端口.

異步事件信號分離器:由Boost.Asio從隊列中移除事件及其相關聯的完成句柄.

優點

可移植性Portability:很多操作系統都提供原生的異步操作IO API(如Windows中的重疊IO),是開發者開發高性能網絡應用程序的最佳選擇.ASIO庫盡可能使用原生的異步IO.如果原生支持不可用,ASIO庫可使用同步事件信號分離器實現典型的Reactor模式,如POSIX的select().

— 去除多線程并發的耦合

應用程序使用異步方式調用長時間運行的操作.但應用程序不必為增加的并發而顯式的創建大量線程.

每個連接一個線程的實現策略(僅需要同步的方式)--太多的線程會產生大量的CPU上下文切換,同步和數據移動,導致系統效率降低.異步操作創建最小數量的操作系統線程,避免線程上下文切換的代價--CPU是典型的有限資源,這時僅由激活的邏輯線程進行事件處理.

— 簡單的應用程序同步.

異步操作完成句柄可以在已存在的單線程環境中進行設置,此時開發出來的應用程序邏輯清晰,不必涉及同步問題.

— 功能組合.

功能組合是指實現高層次的操作功能,如按特定格式發送消息.每個功能的實現都是依賴于多次調用底層的讀或寫操作.

例如, 一個包含固定長度包頭和變長包體的協議,包體長度在包頭中指定.假設read_message操作由兩個底層的讀來實現,第一次接收包頭,得到長度,第二次接收包體.

如果用異步方式來組合這些功能,可將這些異步調用連接到一起.前一個操作的完成句柄初始化下一個操作.使用時只需要調用封裝鏈中的第一個操作,調用者不會意識到這個高層次的操作是按異步操作鏈的方式實現的.

按此方式可以很簡單的向網路庫中添加新的操作,開發出更高層次的抽象,如實現特定協議的功能和支持.

缺點

— 抽象復雜.

由于操作初始化和完成在時間和空間上是分離的,增加了使用異步機制開發程序的難度.而且控制流顛倒使應用程序很難調試.

— 內存占用.

在讀和寫過程中必須獨占緩沖區空間,而后緩沖區又變為不確定的,每個并發操作都需要一個獨立的緩沖區.換句話說,在Reactor模式中,直到socket準備讀或寫時才需要緩沖區空間.

線程和Boost.Asio

線程安全

通常在并發操作中使用相互獨立的局部對象是安全的,但并發操作中使用同一個全局對象就不安全了.然而如io_service 等類型可以保證并發操作中使用同一個對象也是安全的.

線程池

在多個線程中調用io_service::run()函數,就可以創建一個包含這些線程的線程池,其中的線程在異步操作完成后調用完成句柄.也可通過調用io_service::post()實現橫跨整個線程池的任意計算任務來達到相同的目的.

注意所有加入io_service池的線程都是平等的,io_service可以按任意的方式向其分配工作.

內部線程

這個庫的特定平臺實現會創建幾個內部線程來模擬異步操作.同時,這些線程對庫用戶是不可見的.這些線程特性:

  • 不會直接調用用戶的代碼
  • 阻塞所有信號

使用如下擔保來實現:

  • 異步完成句柄只會由調用io_service::run()的線程來調用.

因此,由庫的使用者來建立和管理投遞通知的線程.

原因:

  • 在單線程中調用io_service::run(),用戶代碼避免了復雜的線程同步控制.例如,ASIO庫用戶可以使用單線程實現伸縮性良好的服務端(特定用戶觀點).
  • 線程啟動后在其他應用程序代碼執行前,ASIO庫用戶需要在線程中執行一些簡短的初始化操作.例如在線程中調用微軟的COM操作之前必須調用CoInitializeEx.
  • 將ASIO庫接口與線程的創建和管理進行了解耦,確保可在不支持線程的平臺中進行調用.

Strands:無顯式鎖定的線程

Strand被定義為嚴格按順序調用(如無并發調用)事件句柄的機制.使用Strand可以在多線程程序中同步執行代碼而無需顯式地加鎖(如互斥量等).

Strand可以按如下兩種方式來隱式或顯式的應用:

· 僅在一個線程中調用io_service::run()意味著所有的事件句柄都執行在一個隱式的Strand下,因為io_service保證所有的句柄都在run()中被調用.

· 鏈接中只有一個相關的異步操作鏈(如半雙工的HTTP),句柄是不可能并發執行的.也是隱式Strand的情況.

· 顯式Strand需要創建一個io_service::strand實例.所有的事件句柄函數對象都需要使用io_service::strand::wrap()進行包裝,或使用io_service::strand進行投遞或分發.

在組合的異步操作中,如async_read() 或 async_read_until(),如果完成句柄使用一個Strand管理,則其他所有中間句柄都要由同一個Strand來管理.這可以確保線程安全的訪問所有在調用者和組合的操作中共享的對象(例如socket中的async_read(),調用者可以調用close()來取消操作).這是通過在所有中間句柄中添加一個鉤子函數實現的,在執行最終句柄前調用自定義的鉤子函數:

struct my_handler

{

? void operator()() { ... }

};

?

template<class F>

void asio_handler_invoke(F f, my_handler*)

{

? // Do custom invocation here.

? // Default implementation calls f();

}

io_service::strand::wrap()函數生成一個新的定義了asio_handler_invoke的完成句柄,以便于Strand管理函數對象的運行.

緩沖區

通常IO在連續的內存區域(緩沖區)上傳輸數據.這個緩沖區可以簡單的認為是包含了一個指針地址和一些字節的東西.然而,為了高效的開發網絡應用程序, Boost.Asio支持分散聚合操作,需要一個或多個緩沖區:

  • 一個分散讀(scatter-read)接收數據并存入多緩沖區.
  • .一個聚合寫(gather-write)傳輸多緩沖區中的數據.

因此需要一個抽象概念代表緩沖區集合.為此Boost.Asio定義了一個類(實際上是兩個類)來代表單個緩沖區.可存儲在向分散集合操作傳遞的容器中.

此外可將緩沖區看做是一個具有地址和大小的字節數組, Boost.Asio區別對待可修改內存(叫做mutable)和不可修改內存(后者在帶有const聲明的存儲區域上創建).這兩種類型可以定義為:

typedef std::pair<void*, std::size_t> mutable_buffer; typedef std::pair<const void*, std::size_t> const_buffer;

這里mutable_buffer 可以轉換為const_buffer ,但反之不成立.

然而,Boost.Asio沒有使用上述的定義,而是定義了兩個類: mutable_buffer 和 const_buffer.目的是提供了不透明的連續內存概念:

  • 類型轉換上同std::pair.即mutable_buffer可以轉換為const_buffer ,但反之不成立.
  • 可防止緩沖區溢出.對于一個緩沖區實例,用戶只能創建另外一個緩沖區來代表同樣的內存序列或子序列.為了更加安全,ASIOI庫也提供了從數組(如boost::array 或 std::vector,或std::string)中自動計算緩沖區大小的機制.
  • 必須明確的調用buffer_cast函數進行類型轉換.應用程序中通常不必如此,但在ASIO庫的實現中將原始內存數據傳遞給底層的操作系統函數時必須如此.

最后將多個緩沖區存入一個容器中就可以傳遞給分散聚合操作了.(如read()write()).為了使用std::vector, std::list, std::vector 或 boost::array等容器而定義了MutableBufferSequence和ConstBufferSequence概念.

Streambuf與IoStream整合

類boost::asio::basic_streambuf從std::basic_streambuf繼承,將輸入輸出流與一個或多個字符數組類型的對象相關聯,其中的每個元素可以存儲任意值.這些字符數組對象是內部的streambuf對象,但通過直接存取數組中的元素使其可用于IO操作,如在socket中發送或接收:

  • streambuf 的輸入序列可以通過data()成員函數獲取.函數的返回值滿足ConstBufferSequence的要求.
  • streambuf 的輸出序列可以通過prepare()成員函數獲取.函數的返回值滿足MutableBufferSequence的要求.
  • 調用commit()成員函數將數據從前端的輸出序列傳遞到后端的輸入序列.
  • 調用consume()成員函數從輸入序列中移除數據.

streambuf 構造函數接收一個size_t的參數指定輸入序列和輸出序列大小的總和.對于任何操作,如果成功,增加內部數據量,超過這個大小限制會拋出std::length_error異常.

遍歷緩沖區序列的字節

buffers_iterator<>類模板可用于像遍歷連續字節序列一樣遍歷緩沖區序列(如MutableBufferSequence 或 ConstBufferSequence).并提供了buffers_begin() 和 buffers_end()幫助函數, 會自動推斷buffers_iterator<>的模板參數.

例如,從socket中讀取一行數據,存入std::string中:

boost::asio::streambuf sb; ... std::size_t n = boost::asio::read_until(sock, sb, '\n'); boost::asio::streambuf::const_buffers_type bufs = sb.data(); std::string line( ??? boost::asio::buffers_begin(bufs), ??? boost::asio::buffers_begin(bufs) + n);

緩沖區調試

有些標準庫實現,如VC++8.0或其后版本,提供了叫做迭代器調試的特性.這意味著運行期會驗證迭代器是否合法.如果應用程序試圖使用非法的迭代器,會拋出異常.例如:

std::vector<int> v(1) std::vector<int>::iterator i = v.begin(); v.clear(); // invalidates iterators *i = 0; // assertion!

Boost.Asio 利用這個特性實現緩沖區調試.對于下面的代碼:

void dont_do_this() { std::string msg = "Hello, world!"; boost::asio::async_write(sock, boost::asio::buffer(msg), my_handler); }

當調用異步讀或寫時需要確保此操作的緩沖區在調用完成句柄時可用.上例中,緩沖區是std::string變量msg.變量在棧中,異步完成前已經過期了.如果幸運的話程序崩潰,但更可能會出現隨機錯誤.

當緩沖區調試啟動后,Boost.Asio會存儲一個字符串的迭代器,一直保存到異步操作完成,然后解引用來檢查有效性.上例中在Boost.Asio調用完成句柄前就會看到一個斷言錯誤.

當定義_GLIBCXX_DEBUG 選項時,會自動在VS8.0及其以后版本和GCC中啟動這個特性.檢查需要性能代價,因此緩沖區調試只在debug生成時啟用.其他編譯器可通過定義BOOST_ASIO_ENABLE_BUFFER_DEBUGGING選項來啟動.也可顯式的通過BOOST_ASIO_DISABLE_BUFFER_DEBUGGING選項停止.

,短讀短寫

很多Boost.Asio中的IO對象都是基于流的.意味著:

  • 無消息邊界.被傳輸的數據就是一個連續的字節序列.
  • 讀寫操作可能會傳遞少量不需要的字節.這被稱為短讀或短寫.

提供基于流IO操作模型的對象需要模擬如下幾個操作:

  • SyncReadStream, 調用成員函數read_some()執行同步讀操作.
  • AsyncReadStream, 調用成員函數async_read_some()執行異步讀操作.
  • SyncWriteStream, 調用成員函數write_some()執行同步寫操作.
  • AsyncWriteStream, 調用成員函數async_write_some()執行異步寫操作.

基于流的IO對象包括ip::tcp::socket, ssl::stream<>, posix::stream_descriptor, windows::stream_handle等等.

通常程序需要傳遞指定數量的字節數據.啟動操作后就會發生短讀或短寫,直到所有數據傳輸完畢.Boost.Asio提供了通用函數來自動完成這些操作: read(), async_read(), write() 和 async_write().

為什么EOF是一個錯誤

  • 流終止會導致read, async_read, read_until or async_read_until 函數違反約定.如要讀取N個字節,但由于遇到EOF而提前結束.
  • EOF錯誤可以區分流終止和成功讀取0個字節.

?

Reactor風格操作

有時應用程序必須整合第三方的庫來實現IO操作.為此,Boost.Asio提供一個可用于讀和寫操作的null_buffers類型.null_buffers直到IO對象準備好執行操作后才會返回.

例如,如下代碼執行無阻塞讀操作:

ip::tcp::socket socket(my_io_service); ... socket.non_blocking(true); ... socket.async_read_some(null_buffers(), read_handler); ... void read_handler(boost::system::error_code ec) { ? if (!ec) ? { ??? std::vector<char> buf(socket.available()); ??? socket.read_some(buffer(buf)); ? } }

Socket在所有平臺上都支持這種操作,是POSIX基于流的描述符合類.

基于行的傳輸操作

很多常用的網絡協議都是基于行的,即這些協議元素被字符序列"\r\n"限定.例如HTTP,SMTP和FTP.為了便于實現基于行的協議,以及其他使用分隔符的協議,Boost.Asio包括了read_until() 和 async_read_until()函數.

如下代碼展示在HTTP服務端使用async_read_until()接收客戶端的第一行HTTP請求:

class http_connection { ? ... ? ? void start() ? { ??? boost::asio::async_read_until(socket_, data_, "\r\n", ??????? boost::bind(&http_connection::handle_request_line, this, _1)); ? } ? ? void handle_request_line(boost::system::error_code ec) ? { ??? if (!ec) ??? { ????? std::string method, uri, version; ????? char sp1, sp2, cr, lf; ????? std::istream is(&data_); ????? is.unsetf(std::ios_base::skipws); ????? is >> method >> sp1 >> uri >> sp2 >> version >> cr >> lf; ????? ... ??? } ? } ? ? ... ? ? boost::asio::ip::tcp::socket socket_; ? boost::asio::streambuf data_; };

Streambuf數據成員用于存儲在查找到分隔符前接收的數據.記錄分隔符以后的數據也是很重要的.這些保留在streambuf中的冗余數據會被保留下來用于隨后調用的read_until()或async_read_until()函數進行檢查.

分隔符可以是單個字符,一個std::string或一個boost::regex. read_until() 和 async_read_until()函數也可接收一個用戶定義函數作為參數,獲取匹配條件.例如,在streambuf中讀取數據,遇到一個空白字符后停止.:

typedef boost::asio::buffers_iterator< ??? boost::asio::streambuf::const_buffers_type> iterator; ? std::pair<iterator, bool> match_whitespace(iterator begin, iterator end) { ? iterator i = begin; ? while (i != end) ??? if (std::isspace(*i++)) ????? return std::make_pair(i, true); ? return std::make_pair(i, false); } ... boost::asio::streambuf b; boost::asio::read_until(s, b, match_whitespace);

從streambuf中讀取數據,直到遇到匹配的字符:

class match_char { public: ? explicit match_char(char c) : c_(c) {} ? ? template <typename Iterator> ? std::pair<Iterator, bool> operator()( ????? Iterator begin, Iterator end) const ? { ??? Iterator i = begin; ??? while (i != end) ????? if (c_ == *i++) ??????? return std::make_pair(i, true); ??? return std::make_pair(i, false); ? } ? private: ? char c_; }; ? namespace boost { namespace asio { ? template <> struct is_match_condition<match_char> ??? : public boost::true_type {}; } } // namespace boost::asio ... boost::asio::streambuf b; boost::asio::read_until(s, b, match_char('a'));

is_match_condition<>類型會自動的對函數,及帶有嵌套result_type類型定義的函數對象的返回值值進行評估是否為true.如上例所示,其他類型的特性必須顯式指定.

自定義內存分配

很多異步操作需要分配對象,用來存儲與操作有關的狀態數據.例如,Win32的實現中需要將重疊子對象傳遞給Win32 API函數.

幸好程序包含一個易于識別的異步操作鏈.半雙工協議(如HTTP服務)為每個客戶端創建一個單操作鏈.全雙工協議實現有兩個并行的執行鏈.程序運用這個規則可以在鏈上的所有異步操作中重用內存.

假設復制一個用戶定義的句柄對象h,如果句柄的實現需要分配內存,應該有如下代碼:

void* pointer = asio_handler_allocate(size, &h);

同樣要釋放內存:

asio_handler_deallocate(pointer, size, &h);

這個函數實現了參數依賴的定位查找.asio空間中有這個函數的默認實現:

void* asio_handler_allocate(size_t, ...); void asio_handler_deallocate(void*, size_t, ...);

實現了::operator new() 和 ::operator delete()功能.

函數實現保證了相關句柄調用前會發生內存重新分配,這樣就可以實現同一個句柄上的異步操作重用內存.

在任意調用庫函數的用戶線程中都可調用自定義內存分配函數.實現保證庫中的這些異步操作不會并發的對句柄進行內存分配函數調用.實現要加入適當的內存間隔,保證不同線程中調用的內存分配函數有正確的內存可見性.

句柄跟蹤

為調試異步程序,Boost.Asio提供了句柄跟蹤支持.當激活BOOST_ASIO_ENABLE_HANDLER_TRACKING定義,Boost.Asio向標準錯誤流中寫入調試輸出信息.輸出信息記錄異步操作及其句柄間的關系.

這個特性對調試很有幫助,需要知道異步操作是如何被鏈接在一起的,或什么異步操作被掛起了.如下是HTTP服務輸出的調試信息,處理單個請求,而后按Ctrl+C退出:

@asio|1298160085.070638|0*1|signal_set@0x7fff50528f40.async_wait @asio|1298160085.070888|0*2|socket@0x7fff50528f60.async_accept @asio|1298160085.070913|0|resolver@0x7fff50528e28.cancel @asio|1298160118.075438|>2|ec=asio.system:0 @asio|1298160118.075472|2*3|socket@0xb39048.async_receive @asio|1298160118.075507|2*4|socket@0x7fff50528f60.async_accept @asio|1298160118.075527|<2| @asio|1298160118.075540|>3|ec=asio.system:0,bytes_transferred=122 @asio|1298160118.075731|3*5|socket@0xb39048.async_send @asio|1298160118.075778|<3| @asio|1298160118.075793|>5|ec=asio.system:0,bytes_transferred=156 @asio|1298160118.075831|5|socket@0xb39048.close @asio|1298160118.075855|<5| @asio|1298160122.827317|>1|ec=asio.system:0,signal_number=2 @asio|1298160122.827333|1|socket@0x7fff50528f60.close @asio|1298160122.827359|<1| @asio|1298160122.827370|>4|ec=asio.system:125 @asio|1298160122.827378|<4| @asio|1298160122.827394|0|signal_set@0x7fff50528f40.cancel

每行的格式為:

<tag>|<timestamp>|<action>|<description>

<tag>一直是@asio,用于在程序輸出中識別和提取句柄跟蹤消息.

<timestamp>是從UTC時間1970年一月一日起至今的秒數.

<action>有如下幾種形式:

>n

程序進入了第n個句柄.<description>描述句柄參數.

<n

程序退出第n個句柄.

!n

程序由于異常退出第n個句柄.

~n

第n個句柄沒有執行就被銷毀了.通常是由于io_service銷毀時異步操作還沒有完成.

n*m

第n個句柄創建了一個生成第m個完成句柄的新異步操作.<description>描述什么異步操作被啟動.

n

第n個句柄執行其他操作.<description>顯示調用了哪些函數.通常只記錄close()和cancel()操作,因為其影響了異步操作掛起狀態.

當<description>顯示同步或異步操作,格式為<object-type>@<pointer>.<operation>. 并以逗號間隔來顯示執行句柄的參數和值.

如上所示,每個句柄都由唯一的數字進行標識.句柄跟蹤輸出的句柄編號是0的,表示操作不是這些句柄執行的.

可視化

句柄跟蹤輸出可以使用包含在handlerviz.pl中的工具進行處理,創建可視化的界面.

網絡

TCP,UDP和ICMP

Boost.Asio 對TCP,UDP和ICMP提供了完整的支持.

TCP客戶端

使用resolver執行主機名稱解析,查詢主機和服務名稱并轉換為一個或多個端點:

ip::tcp::resolver resolver(my_io_service); ip::tcp::resolver::query query("www.boost.org", "http"); ip::tcp::resolver::iterator iter = resolver.resolve(query); ip::tcp::resolver::iterator end; // End marker. while (iter != end) { ? ip::tcp::endpoint endpoint = *iter++; ? std::cout << endpoint << std::endl; }

上面列表中包含的端點可以是IPv4和IPv6端點,因此程序需要對每種情況進行嘗試直到得到一個可用的端點.這使程序不依賴于特定的IP版本.

為了開發獨立與協議的程序,TCP客戶端可以使用connect()和async_connect()函數建立連接.這個操作將嘗試列表中的每個端點直到Socket連接成功為止.例如,簡單的調用:

ip::tcp::socket socket(my_io_service); boost::asio::connect(socket, resolver.resolve(query));

將同時嘗試所有端點直到找到連接成功.同樣異步操作的方式為:

boost::asio::async_connect(socket_, iter, ??? boost::bind(&client::handle_connect, this, ????? boost::asio::placeholders::error)); ? // ... ? void handle_connect(const error_code& error) { ? if (!error) ? { ??? // Start read or write operations. ? } ? else ? { ??? // Handle error. ? } }

當特定端點可用,socket創建并連接.方式為:

ip::tcp::socket socket(my_io_service); socket.connect(endpoint);

使用成員函數receive(),async_receive(),send() 或 async_send()可將數據讀于或寫到TCP連接的Socket上.然而為了快速的讀寫操作,通常使用read(),async_read(),write()和async_write()函數進行操作.

TCP服務

程序使用接收器來接收到達的TCP連接:

ip::tcp::acceptor acceptor(my_io_service, my_endpoint); ... ip::tcp::socket socket(my_io_service); acceptor.accept(socket);

當成功接收一個socket連接(向如上例中的TCP客戶端),就可以在其上讀取或寫入數據了.

UDP

UDP也使用來resolver解析主機名稱:

ip::udp::resolver resolver(my_io_service); ip::udp::resolver::query query("localhost", "daytime"); ip::udp::resolver::iterator iter = resolver.resolve(query); ...

UDP綁定到了本地端點.如下代碼創建一個IPv4的UDP Socket,綁定到任意地址的12345端口上:

ip::udp::endpoint endpoint(ip::udp::v4(), 12345); ip::udp::socket socket(my_io_service, endpoint);

使用成員函數receive_from(),async_receive_from(),send_to() 或 async_send_to()可在無連接的UPD Socket上讀出或寫入數據.對于連接的UDP Socket,可使用receive(),async_receive(),send() 或 async_send()成員函數.

ICMP

如同TCP和UPD一樣,ICMP也是用resolver解析主機名稱:

ip::icmp::resolver resolver(my_io_service); ip::icmp::resolver::query query("localhost", ""); ip::icmp::resolver::iterator iter = resolver.resolve(query); ...

ICMP Socket可能綁定到本地端點.如下代碼創建IPv6版本的ICMP Socket,并綁定到任意的地址:

ip::icmp::endpoint endpoint(ip::icmp::v6(), 0); ip::icmp::socket socket(my_io_service, endpoint);

ICMP不必指定端口號.

使用成員函數receive_from(),async_receive_from(),send_to() 或 async_send_to()在無連接的ICMP上讀出或寫入數據.

其他協議

其他Socket協議的支持(如藍牙或IRCOMM)可按協議要求進行實現.

Socket IO

Boost.Asio 中包含一個在Socket上實現的iostream類.將端點解析,協議無關等復雜特性的實現隱藏起來.要創建連接只需簡單的寫幾行代碼:

ip::tcp::iostream stream("www.boost.org", "http"); if (!stream) { ? // Can't connect. }

iostream 類可以與接收器一起創建簡單的服務端.例如:

io_service ios; ? ip::tcp::endpoint endpoint(tcp::v4(), 80); ip::tcp::acceptor acceptor(ios, endpoint); ? for (;;) { ? ip::tcp::iostream stream; ? acceptor.accept(*stream.rdbuf()); ? ... }

可使用expires_at() 或 expires_from_now()函數設置超時期限.超時的Socket操作會將iostream設置為"bad"狀態.

例如,一個簡單的客戶端程序:

ip::tcp::iostream stream; stream.expires_from_now(boost::posix_time::seconds(60)); stream.connect("www.boost.org", "http"); stream << "GET /LICENSE_1_0.txt HTTP/1.0\r\n"; stream << "Host: www.boost.org\r\n"; stream << "Accept: */*\r\n"; stream << "Connection: close\r\n\r\n"; stream.flush(); std::cout << stream.rdbuf();

如果所有的Socket操作時間加起來超過60秒則失敗.

如果發生錯誤,可使用iostream的error()成員函數獲取最近系統操作的錯誤碼:

if (!stream) { ? std::cout << "Error: " << stream.error().message() << "\n"; }
注意

這個iostream模板只支持char,不支持wchar_t,不要用于這樣的代碼版本.

BSD Socket APIBoost.Asio

Boost.Asio 包含了實現BSD Socket API的低層次Socket接口的庫.在其他語言中后者也作為最基本的網絡API,如Java.底層次接口可用來開發高效率和高可伸縮性的應用程序.例如,程序員可以更好的控制系統調用次數,避免基礎數據拷貝,最小化如線程等資源的使用等.

BSD Socket API包含了不安全和有錯誤傾向的方面.例如,使用整型數字代表socket缺乏安全性. Boost.Asio 中使用不同的Socket類型代表不用的協議,如TCP對應的是ip::tcp::socket,UDP對應的ip::udp::socket.

下表是BSD Socket API和Boost.Asio的對比:

BSD Socket API 元素

Boost.Asio中等價內容

Socket描述符-int (POSIX)或SOCKET (Windows)

TCP: ip::tcp::socket, ip::tcp::acceptor

UDP: ip::udp::socket

basic_socket,basic_stream_socket,basic_datagram_socket,basic_raw_socket

in_addr, in6_addr

ip::address,ip::address_v4,ip::address_v6

sockaddr_in, sockaddr_in6

TCP: ip::tcp::endpoint

UDP: ip::udp::endpoint

ip::basic_endpoint

accept()

TCP: ip::tcp::acceptor::accept()

basic_socket_acceptor::accept()

bind()

TCP: ip::tcp::acceptor::bind(), ip::tcp::socket::bind()

UDP: ip::udp::socket::bind()

basic_socket::bind()

close()

TCP: ip::tcp::acceptor::close(), ip::tcp::socket::close()

UDP: ip::udp::socket::close()

basic_socket::close()

connect()

TCP: ip::tcp::socket::connect()

UDP: ip::udp::socket::connect()

basic_socket::connect()

getaddrinfo(), gethostbyaddr(), gethostbyname(), getnameinfo(), getservbyname(), getservbyport()

TCP: ip::tcp::resolver::resolve(), ip::tcp::resolver::async_resolve()

UDP: ip::udp::resolver::resolve(), ip::udp::resolver::async_resolve()

ip::basic_resolver::resolve(),ip::basic_resolver::async_resolve()

gethostname()

ip::host_name()

getpeername()

TCP: ip::tcp::socket::remote_endpoint()

UDP: ip::udp::socket::remote_endpoint()

basic_socket::remote_endpoint()

getsockname()

TCP: ip::tcp::acceptor::local_endpoint(), ip::tcp::socket::local_endpoint()

UDP: ip::udp::socket::local_endpoint()

basic_socket::local_endpoint()

getsockopt()

TCP: ip::tcp::acceptor::get_option(), ip::tcp::socket::get_option()

UDP: ip::udp::socket::get_option()

basic_socket::get_option()

inet_addr(), inet_aton(), inet_pton()

ip::address::from_string(),ip::address_v4::from_string(),ip_address_v6::from_string()

inet_ntoa(), inet_ntop()

ip::address::to_string(),ip::address_v4::to_string(),ip_address_v6::to_string()

ioctl()

TCP: ip::tcp::socket::io_control()

UDP: ip::udp::socket::io_control()

basic_socket::io_control()

listen()

TCP: ip::tcp::acceptor::listen()

basic_socket_acceptor::listen()

poll(), select(), pselect()

io_service::run(),io_service::run_one(),io_service::poll(),io_service::poll_one()

注意:包括異步操作.

readv(), recv(), read()

CP: ip::tcp::socket::read_some(), ip::tcp::socket::async_read_some(), ip::tcp::socket::receive(), ip::tcp::socket::async_receive()

UDP: ip::udp::socket::receive(), ip::udp::socket::async_receive()

basic_stream_socket::read_some(),basic_stream_socket::async_read_some(),basic_stream_socket::receive(),basic_stream_socket::async_receive(),basic_datagram_socket::receive(),basic_datagram_socket::async_receive()

recvfrom()

UDP: ip::udp::socket::receive_from(), ip::udp::socket::async_receive_from()

basic_datagram_socket::receive_from(),basic_datagram_socket::async_receive_from()

send(), write(), writev()

TCP: ip::tcp::socket::write_some(), ip::tcp::socket::async_write_some(), ip::tcp::socket::send(), ip::tcp::socket::async_send()

UDP: ip::udp::socket::send(), ip::udp::socket::async_send()

basic_stream_socket::write_some(),basic_stream_socket::async_write_some(),basic_stream_socket::send(),basic_stream_socket::async_send(),basic_datagram_socket::send(),basic_datagram_socket::async_send()

sendto()

UDP: ip::udp::socket::send_to(), ip::udp::socket::async_send_to()

basic_datagram_socket::send_to(),basic_datagram_socket::async_send_to()

setsockopt()

TCP: ip::tcp::acceptor::set_option(), ip::tcp::socket::set_option()

UDP: ip::udp::socket::set_option()

basic_socket::set_option()

shutdown()

TCP: ip::tcp::socket::shutdown()

UDP: ip::udp::socket::shutdown()

basic_socket::shutdown()

sockatmark()

TCP: ip::tcp::socket::at_mark()

basic_socket::at_mark()

socket()

TCP: ip::tcp::acceptor::open(), ip::tcp::socket::open()

UDP: ip::udp::socket::open()

basic_socket::open()

socketpair()

local::connect_pair()

注意:僅適合POSIX操作系統.

定時器

長時間運行的操作通常都會設置一個最終的完成期限.這個最終期限可以是使用絕對時間來表示,但通常使用相對時間.

一個簡單的范例,在相對時間內執行等待異步操作:

io_service i; ... deadline_timer t(i); t.expires_from_now(boost::posix_time::seconds(5)); t.wait();

通常,程序會基于計時器來執行異步等待操作:

void handler(boost::system::error_code ec) { ... } ... io_service i; ... deadline_timer t(i); t.expires_from_now(boost::posix_time::milliseconds(400)); t.async_wait(handler); ... i.run();

定時器相關聯的超時期限可以是相對時間:

boost::posix_time::time_duration time_until_expiry ? = t.expires_from_now();

或使用絕對時間:

deadline_timer t2(i); t2.expires_at(t.expires_at() + boost::posix_time::seconds(30));

串口

Boost.Asio包含用靈活的方式創建和操作串口的類.例如,打開串口的代碼:

serial_port port(my_io_service, name);

name是如Windows中的"COM1",及POSIX平臺下的"/dev/ttyS0".

打開后,串口就可以向流一樣使用了.既這個對象可以用于async_read(),write(),async_write(),read_until() 或 async_read_until()函數.

串口實現中還包括配置串口波特率,流控制,奇偶校驗,停止位和字符數量等可選類.

注意

串口可用于所有POSIX平臺.Windows中串口通信需要在編譯期將IO完成端口激活.程序可以測試BOOST_ASIO_HAS_SERIAL_PORTS宏來檢查Windows系統是否支持串口操作.

信號處理

Boost.Asio通過signal_set類實現信號處理.程序可以向集合中加入一個或多個信號,而后執行asyn_wait()操作.當其中一個信號發生時執行特定的事件處理函數.同一個信號可注冊在多個singal_set對象中,但這些信號只能用于Boost.Asio .

void handler( ??? const boost::system::error_code& error, ??? int signal_number) { ? if (!error) ? { ??? // A signal occurred. ? } } ? ... ? // Construct a signal set registered for process termination. boost::asio::signal_set signals(io_service, SIGINT, SIGTERM); ? // Start an asynchronous wait for one of the signals to occur. signals.async_wait(handler);

信號處理也可在Windows中使用,與VC++運行時庫映射到控制臺的事件如Ctrl+C等價.

POSIX特有功能

UNIX領域的Socket

Boost.Asio 提供了UNIX領域的Socket基本支持(又叫做本地Socket).最簡單的使用情況是有一對連接Socket.代碼如下:

local::stream_protocol::socket socket1(my_io_service); local::stream_protocol::socket socket2(my_io_service); local::connect_pair(socket1, socket2);

將創建一對基于流的Socket.要實現基于數據包的Socket,使用:

local::datagram_protocol::socket socket1(my_io_service); local::datagram_protocol::socket socket2(my_io_service); local::connect_pair(socket1, socket2);

UNIX領域的Socket服務可以創建在一個綁定一個端點的接收器上,TCP服務也類似:

::unlink("/tmp/foobar"); // Remove previous binding. local::stream_protocol::endpoint ep("/tmp/foobar"); local::stream_protocol::acceptor acceptor(my_io_service, ep); local::stream_protocol::socket socket(my_io_service); acceptor.accept(socket);

客戶端連接到服務端代碼:

local::stream_protocol::endpoint ep("/tmp/foobar"); local::stream_protocol::socket socket(my_io_service); socket.connect(ep);

Boost.Asio不支持跨UNIX領域Socket傳輸文件描述符或證書,但可以使用native()函數調用Socket的底層描述符來實現.

注意

UNIX領域的Socket僅在支持的平臺上編譯的時候激活.可以測試BOOST_ASIO_HAS_LOCAL_SOCKETS宏檢查是否支持.

基于流的文件描述符

Boost.Asio 包含在POSIX文件描述符上同步或異步讀寫的類,如管道,標準輸入輸出,和各種設備(但不是常規的文件).

例如,在標準輸入輸出上執行讀寫,創建如下對象:

posix::stream_descriptor in(my_io_service, ::dup(STDIN_FILENO)); posix::stream_descriptor out(my_io_service, ::dup(STDOUT_FILENO));

而后進行同步或異步讀寫流.即對象可用于read(),async_read(),write(),async_write(),read_until() 或 async_read_until()等函數.

注意

POSIX流描述符僅在支持平臺上編譯時激活.程序可以檢查BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR宏查詢是否支持.

Fork

Boost.Asio 支持程序使用fork()系統調用.程序可以在適當時間調用io_service.notify_fork(),Boost.Asio可重新創建一個內部的文件描述符(如使用"self-pipe trick"描述符技巧激活反應器(reactor)).通知用法如下:

io_service_.notify_fork(boost::asio::io_service::fork_prepare); if (fork() == 0) { ? io_service_.notify_fork(boost::asio::io_service::fork_child); ? ... } else { ? io_service_.notify_fork(boost::asio::io_service::fork_parent); ? ... }

用戶定義服務可以重寫io_service::service::fork_service()虛函數有意制造fork操作.

注意所有Boost.Asio的公共API函數可訪問的文件描述符(如basic_socket<>, posix::stream_descriptor下的描述符)在fork期間不會更改.這需要程序按需要進行管理.

Windows特有功能

面向流的句柄

Boost.Asio 包含允許在Windows句柄上執行異步讀或寫操作的類,如命名管道.

例如,在命名管道上執行異步操作,創建如下對象:

HANDLE handle = ::CreateFile(...); windows::stream_handle pipe(my_io_service, handle);

而后使用同步或異步方式讀寫流.即對象可用于read(),async_read(),write(),async_write(),read_until() 或 async_read_until()函數.

句柄相對的內核對象必須支持IO完成端口(命名管道支持,但匿名管道和控制臺流不支持).

注意

Windows句柄流只能在編譯期激活,而且必須只用IO完成端口作為后臺處理(默認).可使用BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE宏檢測.

隨機存取句柄

Boost.Asio提供特定的類實現在規則文件相關句柄上執行異步讀寫操作.

例如,在文件上執行異步操作代碼:

HANDLE handle = ::CreateFile(...); windows::random_access_handle file(my_io_service, handle);

可以通過成員函數read_some_at(), async_read_some_at(), write_some_at() 或 async_write_some_at()來讀出或寫入數據.然而,和流上的等價函數(read_some()等)一樣,這些函數只需要在單個操作中傳遞一個或多個字節.因此創建了read_at(),async_read_at(),write_at() 和 async_write_at()函數,內部重復調用相應的*_some_at()函數直到所有數據傳遞完畢為止.

注意

Windows隨機讀取句柄只能在編譯期激活,而且后臺使用IO完成端口進行處理才可用.可使用BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE宏來檢測.

對象句柄

Boost.Asio提供Windows特有的類實現在內核對象句柄上進行異步等待的操作:

  • 修改通知
  • 控制臺輸入
  • 事件
  • 內存資源通知
  • 進程
  • 信號量
  • 線程
  • 等待定時器

例如,在事件上執行異步操作,創建如下對象:

HANDLE handle = ::CreateEvent(...); windows::object_handle file(my_io_service, handle);

wait()和async_wait()成員函數用于等待內核對象受信.

注意

Windows對象句柄需要在編譯期激活.可使用BOOST_ASIO_HAS_WINDOWS_OBJECT_HANDLE宏檢查.

SSL

Boost.Asio 包括對SSL支持的類和類模板.這些類可以在通信時將已存在的流(如TCP Socket)進行加密.

在創建加密流前,應用程序必須構造SSL上下文對象.這個對象中通常設置了如驗證模式,證書文件等SLL選項.例如,客戶端初始化代碼如下:

ssl::context ctx(ssl::context::sslv23); ctx.set_verify_mode(ssl::verify_peer); ctx.load_verify_file("ca.pem");

在TCP Socket下使用SSL:

ssl::stream<ip::tcp::socket> ssl_sock(my_io_service, ctx);

執行特定的Socket操作,如建立遠程連接或接收連接,底層的Socket必須使用ssl::stream模板的lowest_layer()成員函數來獲取:

ip::tcp::socket::lowest_layer_type& sock = ssl_sock.lowest_layer(); sock.connect(my_endpoint);

有時底層的流對象的生命期要比SSL流長,這時模板參數需要引用流類型:

ip::tcp::socket sock(my_io_service); ssl::stream<ip::tcp::socket&> ssl_sock(sock, ctx);

SSL的加密連接握手需要在傳輸或接收數據前進行.可通過ssl::stream模板的handshake()或async_handshake()成員函數建立連接.

連接后,SSL流對象即可向同步或異步讀寫流一樣的方式使用了.即對象可用于read(),async_read(),write(),async_write(),read_until() 或 async_read_until()函數.

證書驗證

Boost.Asio 提供各種方法來配置SSL證書驗證:

  • ssl::context::set_default_verify_paths()
  • ssl::context::set_verify_mode()
  • ssl::context::set_verify_callback()
  • ssl::context::load_verify_file()
  • ssl::stream::set_verify_mode()
  • ssl::stream::set_verify_callback()

簡單情況下證書驗證規則為RFC2818(HTTPS下證書驗證), Boost.Asio 提供一個可重用的證書驗證回調函數對象:

  • ssl::rfc2818_verification

下例演示用HTTPS的方式驗證遠程主機的證書:

using boost::asio::ip::tcp; namespace ssl = boost::asio::ssl; typedef ssl::stream<tcp::socket> ssl_socket; ? // Create a context that uses the default paths for // finding CA certificates. ssl::context ctx(ssl::context::sslv23); ctx.set_default_verify_paths(); ? // Open a socket and connect it to the remote host. boost::asio::io_service io_service; ssl_socket sock(io_service, ctx); tcp::resolver resolver(io_service); tcp::resolver::query query("host.name", "https"); boost::asio::connect(sock.lowest_layer(), resolver.resolve(query)); sock.lowest_layer().set_option(tcp::no_delay(true)); ? // Perform SSL handshake and verify the remote host's // certificate. sock.set_verify_mode(ssl::verify_peer); sock.set_verify_callback(ssl::rfc2818_verification("host.name")); sock.handshake(ssl_socket::client); ? // ... read and write as normal ...

SSL和線程

SSL流對象在無鎖定的情況下執行.因此,異步執行SSL都需要隱式或顯式的應用strand.注意這意味著在單線程程序中不需同步控制(不必使用鎖).

注意

OpenSSL需要Boost.Asio的SSL支持.當應用程序使用未由Boost.Asio包裝的OpenSSL功能時,底層的OpenSSL類可通過調用ssl::context::native_handle() 或ssl::stream::native_handle()獲得.

C++2011支持

可移動IO對象

C++支持移動對象后(通過右值引用),Boost.Asio可以對socket,串口,POSIX描述符和Windows句柄進行移動構造和賦值.

通過移動對象可實現如下代碼:

tcp::socket make_socket(io_service& i) { ? tcp::socket s(i); ? ... ? std::move(s); }

或:

class connection : public enable_shared_from_this<connection> { private: ? tcp::socket socket_; ? ... public: ? connection(tcp::socket&& s) : socket_(std::move(s)) {} ? ... }; ? ... ? class server { private: ? tcp::acceptor acceptor_; ? tcp::socket socket_; ? ... ? void handle_accept(error_code ec) ? { ??? if (!ec) ????? std::make_shared<connection>(std::move(socket_))->go(); ??? acceptor_.async_accept(socket_, ...); ? } ? ... };

同時:

std::vector<tcp::socket> sockets; sockets.push_back(tcp::socket(...));

一字真言:當異步操作掛起時是可以繼續移動對象的,但這不是一個好主意.特別是操作由如async_read()等函數觸發時其引用了流對象.在操作期間移動對象將會導致相應操作訪問已移動的對象.

移動支持在g++4.5及以后版本加入-std=c++0x 或 -std=gnu++0x編譯選項即可自動支持.可通過BOOST_ASIO_DISABLE_MOVE定義宏禁用或BOOST_ASIO_HAS_MOVE宏激活.注意這些宏還會影響可移動句柄.

可移動句柄

優化后,用戶定義的完成句柄可支持移動構造,Boost.Asio的實現會優先于拷貝構造函數使用移動構造函數.當前環境下,Boost.Asio也可能去除所有句柄的拷貝構造函數.然而,句柄類型還是需要拷貝構造函數的.

當激活移動支持,異步代碼為:

template <typename Handler> void async_XYZ(..., Handler handler);

實際上聲明為:

template <typename Handler> void async_XYZ(..., Handler&& handler);

句柄參數在async_XYZ函數體內部完美的傳遞,并發生了移動構造.這可確保函數的所有其他參數都會提前評估移動.尤其是在async_XYZ()的其他參數為句柄的成員時更重要.例如:

struct my_operation { ? shared_ptr<tcp::socket> socket; ? shared_ptr<vector<char>> buffer; ? ... ? void operator(error_code ec, size_t length) ? { ??? ... ??? socket->async_read_some(boost::asio::buffer(*buffer), std::move(*this)); ??? ... ? } };

移動支持在g++4.5及以后版本加入-std=c++0x 或 -std=gnu++0x編譯選項即可自動支持.可通過BOOST_ASIO_DISABLE_MOVE定義宏禁用或BOOST_ASIO_HAS_MOVE宏激活.注意這些宏還會影響可移動IO對象.

可變參模板

如果編譯器支持,Boost.Asio可以使用可變參模板實現basic_socket_streambuf::connect() 和basic_socket_iostream::connect()函數.

可變參模板支持在g++4.3及以后版本中的編譯期添加-std=c++0x 或 -std=gnu++0x編譯選項會自動激活.可使用BOOST_ASIO_DISABLE_VARIADIC_TEMPLATES宏禁用,使用BOOST_ASIO_HAS_VARIADIC_TEMPLATES宏激活.

數組容器

由于標準庫提供了std::array<>,Boost.Asio:

  • 為buffer()函數提供了重載.
  • 相對于ip::address_v4::bytes_type和ip::address_v6::bytes_type優先使用boost::array<>.
  • 固定大小的數組優先使用boost::array<>.

G++4.3及以后版本中加上-std=c++0x 或 -std=gnu++0x編譯選項即可自動激活std::array<>,同時VC++10也支持.使用BOOST_ASIO_DISABLE_STD_ARRAY宏禁用,或BOOST_ASIO_HAS_STD_ARRAY宏激活.

原語

Boost.Asio的實現相對于boost::detail::atomic_count優先使用std::atomic<>.

在g++4.5及以后版本中加入-std=c++0x 或 -std=gnu++0x編譯選項即可激活標準的原語整數模板.可使用BOOST_ASIO_DISABLE_STD_ATOMIC宏禁用,或BOOST_ASIO_HAS_STD_ATOMIC宏啟用.

共享指針

Boost.Asio 優先使用std::shared_ptr<>和std::weak_ptr<>.

在g++4.3及以后版本中編譯期添加編譯選項則會自動激活智能指針,MC++10也同樣.可定義BOOST_ASIO_DISABLE_STD_SHARED_PTR宏禁用,用BOOST_ASIO_HAS_STD_SHARED_PTR宏激活.

Chrono

Boost.Asio基于std::chrono機制通過basic_waitable_timer類模板提供了基本的定時器功能.system_timer,steady_timer 和 high_resolution_timer分別使用system_clock, steady_clock 和 high_resolution_clock標準時鐘.

g++4.6級以后版本添加-std=c++0x 或 -std=gnu++0x編譯選項即可自動支持std::chrono.(注意,g++中使用monotonic_clock替代steady_clock.)使用BOOST_ASIO_DISABLE_STD_CHRONO宏禁用, BOOST_ASIO_HAS_STD_CHRONO宏激活.

如果chrono不可用,可使用Boost.Chrono庫. basic_waitable_timer類仍可用.

使用Boost.Asio

支持平臺

在如下平臺和編譯器下測試通過:

  • Win32 and Win64 using Visual C++ 7.1 and Visual C++ 8.0.
  • Win32 using MinGW.
  • Win32 using Cygwin. (__USE_W32_SOCKETS must be defined.)
  • Linux (2.4 or 2.6 kernels) using g++ 3.3 or later.
  • Solaris using g++ 3.3 or later.
  • Mac OS X 10.4 using g++ 3.3 or later.

也可用于如下平臺:

  • AIX 5.3 using XL C/C++ v9.
  • HP-UX 11i v3 using patched aC++ A.06.14.
  • QNX Neutrino 6.3 using g++ 3.3 or later.
  • Solaris using Sun Studio 11 or later.
  • Tru64 v5.1 using Compaq C++ v7.1.
  • Win32 using Borland C++ 5.9.2

依賴

為使程序可連接到Boost.Asio如下庫必須可用:

  • 提供boost::system::error_code 和 boost::system::system_error 的Boost.System庫.
  • 如果使用帶boost::regex參數重載的read_until()或async_read_until()函數,需要Boost.Regex庫.
  • 如果使用了Boost.Asio的SSL支持需要OpenSSL庫.

而且有些范例需要Boost.Thread, Boost.Date_Time 或 Boost.Serialization庫的支持.

?

注意Note

在MSVC或Borland C++中可以在項目設置加入-DBOOST_DATE_TIME_NO_LIB 和 -DBOOST_REGEX_NO_LIB來禁止分別對庫Boost.Date_Time 和 Boost.Regex的自動連接.否則需要生成這些庫并進行連接.

生成Boost庫

可以按需要生成Boost的子庫,下例在Boost的根目錄中運行命令行:

bjam --with-system --with-thread --with-date_time --with-regex --with-serialization stage

這里假設已經生成了bjam.更多信息見Boost.Build文檔.

可選的獨立編譯

默認情況下,Boost.Asio僅是一個有頭文件的庫.然而,有些開發者更愿意分開編譯Boost.Asio的源碼.只需要在程序的源文件中加入#include<boost/asio/impl/src.hpp>,而后在項目/編譯器設置中加入BOOST_ASIO_SEPARATE_COMPILATION編譯選項并進行編譯.或者使用BOOST_ASIO_DYN_LINK選項將Boost.Asio獨立編譯為靜態庫.

如果使用Boost.Asio的SSL支持,需要加入#include <boost/asio/ssl/impl/src.hpp>.

下表中的宏可用來控制Boost.Asio的行為.

宏Macro

描述Description

BOOST_ASIO_ENABLE_BUFFER_DEBUGGING

激活Boost.Asio的緩沖區調試支持,可幫助識別出在讀寫中引用的無效緩沖區(例如,向std::string寫數據,但在操作完成前就已經被釋放了).

在Microsoft Visual C++中,如果激活編譯器的迭代調試支持這個宏會自動定義,否則需要定義BOOST_ASIO_DISABLE_BUFFER_DEBUGGING.

在G++中,如果啟動標準庫調試(定義了_GLIBCXX_DEBUG宏)這個宏會自動定義,否則需要定義BOOST_ASIO_DISABLE_BUFFER_DEBUGGING 宏.

BOOST_ASIO_DISABLE_BUFFER_DEBUGGING

顯式的關閉Boost.Asio緩沖區調試支持.

BOOST_ASIO_DISABLE_DEV_POLL

顯式關閉Solaris的/dev/poll支持,強制使用select-based實現.

BOOST_ASIO_DISABLE_EPOLL

顯式關閉Linux的epoll支持,強制使用select-based實現.

BOOST_ASIO_DISABLE_EVENTFD

顯式關閉Linux的eventfd支持,強制使用管道進行中斷阻塞的epoll/select系統調用.

BOOST_ASIO_DISABLE_KQUEUE

Explicitly disables kqueue support on Mac OS X and BSD variants, forcing the use of a select-based implementation.

BOOST_ASIO_DISABLE_IOCP

Explicitly disables I/O completion ports support on Windows, forcing the use of a select-based implementation.

BOOST_ASIO_DISABLE_THREADS

Explicitly disables Boost.Asio's threading support, independent of whether or not Boost as a whole supports threads.

BOOST_ASIO_NO_WIN32_LEAN_AND_MEAN

By default, Boost.Asio will automatically define WIN32_LEAN_AND_MEAN when compiling for Windows, to minimise the number of Windows SDK header files and features that are included. The presence of BOOST_ASIO_NO_WIN32_LEAN_AND_MEAN prevents WIN32_LEAN_AND_MEAN from being defined.

BOOST_ASIO_NO_NOMINMAX

By default, Boost.Asio will automatically define NOMINMAX when compiling for Windows, to suppress the definition of the min() and max() macros. The presence of BOOST_ASIO_NO_NOMINMAX prevents NOMINMAX from being defined.

BOOST_ASIO_NO_DEFAULT_LINKED_LIBS

When compiling for Windows using Microsoft Visual C++ or Borland C++, Boost.Asio will automatically link in the necessary Windows SDK libraries for sockets support (i.e.ws2_32.lib andmswsock.lib, orws2.lib when building for Windows CE). The BOOST_ASIO_NO_DEFAULT_LINKED_LIBS macro prevents these libraries from being linked.

BOOST_ASIO_SOCKET_STREAMBUF_MAX_ARITY

Determines the maximum number of arguments that may be passed to the basic_socket_streambuf class template's connect member function. Defaults to 5.

BOOST_ASIO_SOCKET_IOSTREAM_MAX_ARITY

Determines the maximum number of arguments that may be passed to the basic_socket_iostream class template's constructor and connect member function. Defaults to 5.

BOOST_ASIO_ENABLE_CANCELIO

Enables use of the CancelIo function on older versions of Windows. If not enabled, calls to cancel() on a socket object will always fail with asio::error::operation_not_supported when run on Windows XP, Windows Server 2003, and earlier versions of Windows. When running on Windows Vista, Windows Server 2008, and later, the CancelIoEx function is always used.

The CancelIo function has two issues that should be considered before enabling its use:

* It will only cancel asynchronous operations that were initiated in the current thread.

* It can appear to complete without error, but the request to cancel the unfinished operations may be silently ignored by the operating system. Whether it works or not seems to depend on the drivers that are installed.

For portable cancellation, consider using one of the following alternatives:

* Disable asio's I/O completion port backend by defining BOOST_ASIO_DISABLE_IOCP.

* Use the socket object's close() function to simultaneously cancel the outstanding operations and close the socket.

BOOST_ASIO_NO_TYPEID

Disables uses of the typeid operator in Boost.Asio. Defined automatically if BOOST_NO_TYPEID is defined.

BOOST_ASIO_HASH_MAP_BUCKETS

Determines the number of buckets in Boost.Asio's internal hash_map objects. The value should be a comma separated list of prime numbers, in ascending order. The hash_map implementation will automatically increase the number of buckets as the number of elements in the map increases.

Some examples:

* Defining BOOST_ASIO_HASH_MAP_BUCKETS to 1021 means that the hash_map objects will always contain 1021 buckets, irrespective of the number of elements in the map.

* Defining BOOST_ASIO_HASH_MAP_BUCKETS to 53,389,1543 means that the hash_map objects will initially contain 53 buckets. The number of buckets will be increased to 389 and then 1543 as elements are added to the map.

郵件列表

Boost.Asio 的郵件列表可從SourceForge.net查找.新聞組見Gmane.

Wiki

用戶通常受益于Boost.Asio WIKI上的共享范例,提示和FAQ.,請見http://think-async.com/Asio/.

入門教程

基本技能

入門教程的第一小節介紹使用asio工具的基本概念.在開發復雜的網絡程序前,范例程序闡述使用異步定時器的基本技巧.

  • Timer.1 - Using a timer synchronously 同步定時程序
  • Timer.2 - Using a timer asynchronously 異步定時程序
  • Timer.3 - Binding arguments to a handler向處理函數綁定參數
  • Timer.4 - Using a member function as a handler 使用成員函數作為處理函數
  • Timer.5 - Synchronising handlers in multithreaded programs 多線程程序中的處理函數同步

Sockets簡介

本節教程展示如何使用asio開發一個簡單的客戶端和服務端程序.程序使用TCP和UDP實現了基本的daytime協議.

前面三個程序使用TCP實現daytime協議.

  • Daytime.1 - A synchronous TCP daytime client
  • Daytime.2 - A synchronous TCP daytime server
  • Daytime.3 - An asynchronous TCP daytime server

后面三個程序使用UDP實現daytime協議.

  • Daytime.4 - A synchronous UDP daytime client
  • Daytime.5 - A synchronous UDP daytime server
  • Daytime.6 - An asynchronous UDP daytime server

本節最后的程序展示如何在一個程序中使用asio來組合TCP和UDP服務.

  • Daytime.7 - A combined TCP/UDP asynchronous server

定時器1-使用同步定時器

本教程演示如何使用asio的定時器執行阻塞等待.

需要包含必要的頭文件:

簡單的包含"asio.hpp"頭文件即可使用所有的asio類.

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

由于本例使用了定時器,需要包含相應的Boost.Date_Time頭文件以便于操作定時器.

#include <boost/date_time/posix_time/posix_time.hpp>

所有使用asio的程序都要創建一個io_service對象.這個類提供IO功能支持.在main函數中首先聲明這個類的對象.

int main() { ? boost::asio::io_service io;

接著聲明一個boost::asio::deadline_timer類型的對象.這些提供IO功能的核心asio類 (或是定時器功能)構造函數的第一個參數總是io_service類的實例.第二個參數設置過期時間為從現在起5秒鐘以后.

? boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));

這是在定時器上阻塞等待的簡單范例.調用deadline_timer::wait()會在定時器到期(5秒鐘)后才返回.

定時器總是有兩個狀態: "到期" 或 "未到期".如果deadline_timer::wait()函數在一個已過期的時間上執行,會立即返回.

? t.wait();

最后在時間到期后輸出著名的"Hello, world!"消息.

? std::cout << "Hello, world!\n"; ? return 0; }

定時器2--異步使用定時器

本范例修改了time1范例,通過在定時器上異步等待演示了如何使用asio異步回調功能.

#include <iostream> #include <boost/asio.hpp> #include <boost/date_time/posix_time/posix_time.hpp>

使用asio的異步功能意味著需要定義一個回調函數,在異步操作完成后執行.本程序中定義了一個叫做print的函數,異步等待完成后調用.

void print(const boost::system::error_code& /*e*/) { ? std::cout << "Hello, world!\n"; } ? int main() { ? boost::asio::io_service io; ? ? boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));

接下來,替換范例1中的阻塞等待.調用deadline_timer::async_wait()函數執行異步等待.在這個函數中傳遞了上面定義的print回調函數.

? t.async_wait(&print);

最后,必須在io_service對象上調用io_service::run()成員函數.

Asio庫保證回調函數在調用了io_service::run()的線程上執行.因此只有調用了io_service::run()函數,異步等待完成的回調函數才能被調用.

Io_service::run()將會一直在運行,因為其還有工作要做.本例中,這個工作是異步等待定時器,因此直到定時器過期而且回調函數執行完畢,才會退出.

在調用io_service::run()前為其指定工作是很重要的.例如,如果上例中忘記調用deadline_timer::async_wait(),io_service無事可做,則io_service::run()調用會立即返回.

? io.run(); ? return 0; }

定時器3-向處理器傳遞參數

本程序從Timer2程序修改而來,將timer改為每秒觸發一次.用來闡述如何向處理函數傳遞其他參數.

#include <iostream> #include <boost/asio.hpp> #include <boost/bind.hpp> #include <boost/date_time/posix_time/posix_time.hpp>

為了讓timer循環的過期,需要在回調函數中修改timer的過期時間,而后開始一個新的異步等待.當然必須讓回調函數可以訪問到timer對象.要實現這個效果需要向print函數傳遞兩個參數:

  • 指向timer對象的指針.
  • Timer觸發計數器,以便于實現觸發6次后結束程序運行.
void print(const boost::system::error_code& /*e*/, ??? boost::asio::deadline_timer* t, int* count) {

如上所述,程序使用計時器來停止運行,如果定時器觸發測試超過6次則退出.然而這里并沒有顯式的讓io_service停止運行.在定時器2范例中我們知道,只有無事可做時io_service::run()才會退出.當計數器等于5時就不在啟動新的異步等待,則io_service完成了工作并停止運行.

? if (*count < 5) ? { ??? std::cout << *count << "\n"; ??? ++(*count);

另外將過期時間從前一個過期時間向后延遲一秒.在原來基礎上定義新的過期時間,可以確保定時器標記的秒數不會由于處理函數執行而延時.

??? t->expires_at(t->expires_at() + boost::posix_time::seconds(1));

而后在timer上啟動一個新的異步等待.boost::bind()函數用來將回調函數與參數相關聯. deadline_timer::async_wait()函數希望的回調函數形式為void(const boost::system::error_code&).bind函數將回調函數print連同附加的參數轉換為這種正確的函數簽名.

更多Boost.Bind信息見Boost.Bind documentation.

本例中,boost::bind()的boost::asio::placeholders::error參數是傳遞給成了函數的錯誤對象名稱占位符.如果使用boost::bind()初始化異步操作,必須指定與句柄參數列表相一致的參數.在范例4中回調函數不需要這個參數會省略掉.

??? t->async_wait(boost::bind(print, ????????? boost::asio::placeholders::error, t, count)); ? } } ? int main() { ? boost::asio::io_service io;

添加一個新的count變量,以便于在timer觸發6次后結束程序運行.

? int count = 0; ? boost::asio::deadline_timer t(io, boost::posix_time::seconds(1));

如步驟4,在main函數中調用了deadline_timer::async_wait()時會向print函數傳遞附加參數.

? t.async_wait(boost::bind(print, ??????? boost::asio::placeholders::error, &t, &count)); ? ? io.run();

最后,驗證print句柄函數中的count變量,輸出其值.

? std::cout << "Final count is " << count << "\n"; ? ? return 0; }

定時器4 -使用成員函數作為處理器

本例演示如何將類的成員函數作為回調處理函數.程序功能與Timer3完全一樣.

#include <iostream> #include <boost/asio.hpp> #include <boost/bind.hpp> #include <boost/date_time/posix_time/posix_time.hpp>

上一個范例中使用print函數作為回調處理函數,本例中首先定義一個printer類.

class printer { public:

類的構造函數中有個io_service的引用,用來初始化timer_成員.關閉程序的計時器也聲明為類的成員.

? printer(boost::asio::io_service& io) ??? : timer_(io, boost::posix_time::seconds(1)), ????? count_(0) ? {

Boost::bind()函數也可用于處理類的成員函數.由于所有的非靜態類成員函數都有一個隱式的this參數,我們需要將this綁定到函數上.與Timer3范例一樣,使用boost::bind()轉換回調處理函數,將其處理為void(constboost::system::error_code&)形式的簽名.

注意這里boost::asio::placeholders::error占位符被忽略,成員函數print不在接收錯誤對象參數.

??? timer_.async_wait(boost::bind(&printer::print, this)); ? }

在類的析構函數輸出最終的計數器值.

? ~printer() ? { ??? std::cout << "Final count is " << count_ << "\n"; ? }

成員函數print與上例的print函數非常類似.由于計數器和timer都做為了類的成員,因此不必在進行參數傳遞了.

? void print() ? { ??? if (count_ < 5) ??? { ????? std::cout << count_ << "\n"; ????? ++count_; ? ????? timer_.expires_at(timer_.expires_at() + boost::posix_time::seconds(1)); ????? timer_.async_wait(boost::bind(&printer::print, this)); ??? } ? } ? private: ? boost::asio::deadline_timer timer_; ? int count_; };

Main函數與上例也很相似,現在聲明一個printer對象并運行io_service.

int main() { ? boost::asio::io_service io; ? printer p(io); ? io.run(); ? ? return 0; }

同步TCP daytime客戶端

本例展示如何使用asio實現一個TCP客戶端.

需要包含如下頭文件.

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

程序的目的是要訪問daytime服務器,因此需要用戶指定一個服務器.

using boost::asio::ip::tcp; ? int main(int argc, char* argv[]) { ? try ? { ??? if (argc != 2) ??? { ????? std::cerr << "Usage: client <host>" << std::endl; ????? return 1; ??? }

所有使用asio的程序都需要一個io_service對象.

??? boost::asio::io_service io_service;

我們需要將程序參數中指定的服務器名稱轉換為TCP端點,因此需要定義一個ip::tcp::resolver對象.

??? tcp::resolver resolver(io_service);

分析器使用一個查詢對象并獲取一個端點列表.使用服務器的名稱(參數argv[1])以及服務名稱(本例中是daytime)作為參數來構造查詢對象.

??? tcp::resolver::query query(argv[1], "daytime");

返回的端點列表為ip::tcp::resolver::iterator類型的迭代器.

??? tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);

現在創建并連接Socket.上述的端點列表可能包括IPv4或IPv6類型的端點,需要嘗試每種可能獲取可用的端點.這樣客戶端就獨立于IP版本號了. boost::asio::connect()自動完成這些功能.

??? tcp::socket socket(io_service); ??? boost::asio::connect(socket, endpoint_iterator);

連接已經打開.現在就可以從服務端讀取數據了.

使用boost::array 來接收數據. boost::asio::buffer()函數自動管理數組大小以防止緩沖區溢出.除了boost::array ,還可以使用char[]或std::vector.

??? for (;;) ??? { ????? boost::array<char, 128> buf; ????? boost::system::error_code error; ? ????? size_t len = socket.read_some(boost::asio::buffer(buf), error);

當服務端關閉了連接,ip::tcp::socket::read_some() 函數接收到boost::asio::error::eof 錯誤信息,退出客戶端循環.

????? 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; ? }

TCP daytime同步服務器

本例闡述如何使用asio實現TCP服務端應用程序.

#include <ctime> #include <iostream> #include <string> #include <boost/asio.hpp> ? using boost::asio::ip::tcp;

定義一個make_daytime_string()函數生成發送給客戶端的字符串.這個函數在所有daytime服務應用程序中重用.

std::string make_daytime_string() { ? using namespace std; // For time_t, time and ctime; ? time_t now = time(0); ? return ctime(&now); } ? int main() { ? try ? { ??? boost::asio::io_service io_service;

ip::tcp::acceptor對象用來偵聽新到的連接.這里初始化為使用IPv4協議來偵聽13端口.

??? tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 13));

這是個可迭代的服務端,即每次只能處理一個連接.對每個客戶端鏈接創建一個Socket,而后等待新到來的連接.

??? for (;;) ??? { ????? tcp::socket socket(io_service); ????? acceptor.accept(socket);

客戶端訪問我們服務端.當前的時間將傳遞給客戶端.

????? std::string message = make_daytime_string(); ? ????? boost::system::error_code ignored_error; ????? boost::asio::write(socket, boost::asio::buffer(message), ignored_error); ??? } ? }

最后處理異常.

? catch (std::exception& e) ? { ??? std::cerr << e.what() << std::endl; ? } ? ? return 0; }

異步TCP daytime服務端

main函數

int main() { ? try ? {

首先創建一個服務對象接收客戶端的連接. io_service對象提供IO服務,如socket就使用這個IO服務對象.

??? boost::asio::io_service io_service; ??? tcp_server server(io_service);

運行io_service對象使其執行異步操作.

??? io_service.run(); ? } ? catch (std::exception& e) ? { ??? std::cerr << e.what() << std::endl; ? } ? ? return 0; }

tcp_server 類

class tcp_server { public:

構造函數初始化接收器監聽TCP的13端口.

? tcp_server(boost::asio::io_service& io_service) ??? : acceptor_(io_service, tcp::endpoint(tcp::v4(), 13)) ? { ??? start_accept(); ? } ? private:

函數start_accept()創建一個Socket并初始化為異步接收操作,等待新的連接.

? 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)); ? }

由start_accept()函數初始化的異步接收操作完成后會調用handle_accept()函數.其響應客戶端的請求并再次調用start_accept()函數初始化下一次接收操作.

? void handle_accept(tcp_connection::pointer new_connection, ????? const boost::system::error_code& error) ? { ??? if (!error) ??? { ????? new_connection->start(); ??? } ? ??? start_accept(); ? }

Tcp連接類

使用shared_ptr和enable_shared_from_this保證tcp_connetion在有相應操作期間保持激活狀態.

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_; ? }

在函數start()中調用boost::asio::async_write()向客戶端寫數據.注意使用的是boost::asio::async_write()而不是ip::tcp::socket::async_write_some(),這樣可以確保發送全部的數據.

? void start() ? {

發送的數據存儲在類成員message_中,在異步操作完成前必須保證數據的有效性.

??? message_ = make_daytime_string();

初始化異步操作后,使用boost::bind()傳遞的參數必須與事件處理函數參數列表相匹配.本例中, boost::asio::placeholders::error 和 boost::asio::placeholders::bytes_transferred參數占位符都被去掉了,因為他們沒有在handle_write()中使用.

??? 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()負責.

? } ? private: ? tcp_connection(boost::asio::io_service& io_service) ??? : socket_(io_service) ? { ? } ? ? void handle_write(const boost::system::error_code& /*error*/, ????? size_t /*bytes_transferred*/) ? { ? } ? ? tcp::socket socket_; ? std::string message_; };

移除無用的事件處理函數的參數

你可能發現error和bytes_transferred參數在函數handle_write()中是無用的.如果參數不需要可將其移除:

? void handle_write() ? { ? }

boost::asio::async_write()的調用調整為如下形式:

? boost::asio::async_write(socket_, boost::asio::buffer(message_), ????? boost::bind(&tcp_connection::handle_write, shared_from_this()));

DDaytime4-同步UDP daytime客戶端

本范例程序展示如何使用asio來實現UPD客戶端程序.

#include/span> <iostream>

#include <boost/array.hpp>

#include <boost/asio.hpp>

?

using boost::asio::ip::udp;;

啟動程序的方式和TCP daytime客戶端相同.

int/span> main(int argc, char* argv[])

{

??try

? {

??? if (argc != 2)

??? {

????? std::cerr << "Usage: client <host>" << std::endl;

????? return 1;

??? }

?

??? boost::asio::io_service io_service;;

ip::udp::resolver傳遞主機和服務名稱獲取正確的遠程端點.查詢通過ip::udp::v4()參數限制使其返回一個IPv4協議的端點.

??? udp::resolver resolver(io_service);

??? udp::resolver::query query(udp::v4(), argv[1], "daytime"));

ip::udp::resolver::resolve()函數保證如果查詢成功的話會返回至少有一個端點的列表.因此可以安全的直接對返回值進行解引用.

???udp::endpoint receiver_endpoint = *resolver.resolve(query));

由于UDP是基于數據報的,沒有使用基于流的Socket.創建一個ip::udp::socket并使用遠程端點進行初始連接.

???udp::socket socket(io_service);

???socket.open(udp::v4());

???boost::array<char, 1> send_buf? = {{ 0 }};

???socket.send_to(boost::asio::buffer(send_buf), receiver_endpoint));

現在需要準備好接收服務端發送過來的數據.客戶端接收服務端響應的端點要通過ip::udp::socket::receive_from()指定.

???boost::array<char, 128> recv_buf;

???udp::endpoint sender_endpoint;

???size_t len = socket.receive_from(

???????boost::asio::buffer(recv_buf), sender_endpoint);

???std::cout.write(recv_buf.data(), len);

?}}

?

?catch (std/span>::exception& e)

?{

???std::cerr << e.what() << std::endl;

?}

?return 0;

}

Daytime5- daytime同步UDP服務端

本范例程序展示如何使用asio實現同步UDP服務程序.

int main() { ? try ? { ??? boost::asio::io_service io_service;

創建ip::udp::socket對象接收UDP 13端口上的請求.

??? udp::socket socket(io_service, udp::endpoint(udp::v4(), 13));

等待客戶端請求連接.remote_endpoint對象將傳入ip::udp::socket::receive_from()函數.

??? for (;;) ??? { ????? boost::array<char, 1> recv_buf; ????? udp::endpoint remote_endpoint; ????? boost::system::error_code error; ????? socket.receive_from(boost::asio::buffer(recv_buf), ????????? remote_endpoint, 0, error); ? ????? if (error && error != boost::asio::error::message_size) ??????? throw boost::system::system_error(error);

接著實現向客戶端發送數據.

????? std::string message = make_daytime_string();

向remote_endpoint發送響應.

????? boost::system::error_code ignored_error; ????? socket.send_to(boost::asio::buffer(message), ????????? remote_endpoint, 0, ignored_error); ??? } ? }

最后處理異常.

? catch (std::exception& e) ? { ??? std::cerr << e.what() << std::endl; ? } ? ? return 0; }

Daytime6- daytime異步UDP服務端

main()函數

int main() { ? try ? {

創建服務對象接收客戶端請求,并運行io_service對象.

??? boost::asio::io_service io_service; ??? udp_server server(io_service); ??? io_service.run(); ? } ? catch (std::exception& e) ? { ??? std::cerr << e.what() << std::endl; ? } ? ? return 0; }

udp_server類

class udp_server { public:

構造函數初始化socket并偵聽UDP的13端口.

? udp_server(boost::asio::io_service& io_service) ??? : socket_(io_service, udp::endpoint(udp::v4(), 13)) ? { ??? start_receive(); ? } ? private: ? void start_receive() ? {

ip::udp::socket::async_receive_from()函數使應用程序在后臺偵聽新的請求.當接收到請求,io_service對象使用兩個參數來調用handle_receive函數:一個描述操作成功失敗的boost::system::error_code類型參數,和一個size_t類型的bytes_transferred 指定接收到的字節數.

??? socket_.async_receive_from( ??????? boost::asio::buffer(recv_buffer_), remote_endpoint_, ??????? boost::bind(&udp_server::handle_receive, this, ????????? boost::asio::placeholders::error, ????????? boost::asio::placeholders::bytes_transferred)); ? }

handle_receive()函數處理客戶端請求.

? void handle_receive(const boost::system::error_code& error, ????? std::size_t /*bytes_transferred*/) ? {

error參數包含異步操作的結果.由于這里只提供了一個字節的recv_buffer_來存放客戶端請求,如果客戶端發送的數據過長則io_service會返回錯誤信息.如果發生錯誤則忽略.

??? if (!error || error == boost::asio::error::message_size) ??? {

生成發送給客戶端的數據.

????? boost::shared_ptr<std::string> message( ????????? new std::string(make_daytime_string()));

調用ip::udp::socket::async_send_to()函數將數據發送到客戶端.

????? socket_.async_send_to(boost::asio::buffer(*message), remote_endpoint_, ????????? boost::bind(&udp_server::handle_send, this, message, ??????????? boost::asio::placeholders::error, ??????????? boost::asio::placeholders::bytes_transferred));

當初始化異步操作時,如果使用boost::bind(),必須指定與回調函數相匹配的參數列表.本程序中,兩個參數占位符(boost::asio::placeholders::error 和 boost::asio::placeholders::bytes_transferred)應該被移除.

開始偵聽下一個客戶端請求.

????? start_receive();

對客戶請求的更多處理由handle_send()負責.

??? } ? }

handle_send()函數在服務請求結束后調用.

? void handle_send(boost::shared_ptr<std::string> /*message*/, ????? const boost::system::error_code& /*error*/, ????? std::size_t /*bytes_transferred*/) ? { ? } ? ? udp::socket socket_; ? udp::endpoint remote_endpoint_; ? boost::array<char, 1> recv_buffer_; };

Daytime7-TCP/UDP異步服務

本范例程序展示如何將已經寫過的兩個異步服務整合到一個服務程序中.

main()函數

int main() { ? try ? { ??? boost::asio::io_service io_service;

創建一個接收TCP客戶端連接的服務對象.

??? tcp_server server1(io_service);

創建一個接收UDP客戶端請求的服務對象.

??? udp_server server2(io_service);

已經創建了兩個基于io_service對象上的工作對象.

??? io_service.run(); ? } ? catch (std::exception& e) ? { ??? std::cerr << e.what() << std::endl; ? } ? ? return 0; }

tcp_connection 和 tcp_server 類

如下兩個類取自Daytime3范例.

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())); ? } ? private: ? tcp_connection(boost::asio::io_service& io_service) ??? : socket_(io_service) ? { ? } ? ? void handle_write() ? { ? } ? ? 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)) ? { ??? 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)); ? } ? ? void handle_accept(tcp_connection::pointer new_connection, ????? const boost::system::error_code& error) ? { ??? if (!error) ??? { ????? new_connection->start(); ??? } ? ??? start_accept(); ? } ? ? tcp::acceptor acceptor_; };

udp_server 類

同樣,下面的類取自上一個范例.

class udp_server { public: ? udp_server(boost::asio::io_service& io_service) ??? : socket_(io_service, udp::endpoint(udp::v4(), 13)) ? { ??? start_receive(); ? } ? private: ? void start_receive() ? { ??? socket_.async_receive_from( ??????? boost::asio::buffer(recv_buffer_), remote_endpoint_, ??????? boost::bind(&udp_server::handle_receive, this, ????????? boost::asio::placeholders::error)); ? } ? ? void handle_receive(const boost::system::error_code& error) ? { ??? if (!error || error == boost::asio::error::message_size) ??? { ????? boost::shared_ptr<std::string> message( ????????? new std::string(make_daytime_string())); ? ????? socket_.async_send_to(boost::asio::buffer(*message), remote_endpoint_, ????????? boost::bind(&udp_server::handle_send, this, message)); ? ????? start_receive(); ??? } ? } ? ? void handle_send(boost::shared_ptr<std::string> /*message*/) ? { ? } ? ? udp::socket socket_; ? udp::endpoint remote_endpoint_; ? boost::array<char, 1> recv_buffer_; };

范例

分配內存

本范例展示如何為異步操作分配必需的內存.

  • boost_asio/example/allocation/server.cpp

緩沖區

本范例展示如何為Socket讀寫操作創建有引用計數的緩沖區.

  • boost_asio/example/buffers/reference_counted.cpp

聊天程序

本范例實現了聊天程序的服務端和客戶端.這個程序使用具有6字節的消息頭和可變長消息體的自定義協議.

  • boost_asio/example/chat/chat_message.hpp
  • boost_asio/example/chat/chat_client.cpp
  • boost_asio/example/chat/chat_server.cpp

下面針對POSIX的聊天客戶端演示如何使用posix::stream_descriptor類執行控制臺輸入輸出.

  • boost_asio/example/chat/posix_chat_client.cpp

Echo

展示如何使用同步和異步操作實現一系列簡單的客戶端和服務端.

  • boost_asio/example/echo/async_tcp_echo_server.cpp
  • boost_asio/example/echo/async_udp_echo_server.cpp
  • boost_asio/example/echo/blocking_tcp_echo_client.cpp
  • boost_asio/example/echo/blocking_tcp_echo_server.cpp
  • boost_asio/example/echo/blocking_udp_echo_client.cpp
  • boost_asio/example/echo/blocking_udp_echo_server.cpp

fock

針對POSIX 的范例程序演示了如何使用Boost.Asio結合fork()系統調用.第一個范例闡述了如何啟動守護進程:

  • boost_asio/example/fork/daemon.cpp

第二個范例闡述了如何在完成句柄中啟動進程.

  • boost_asio/example/fork/process_per_connection.cpp

HTTP客戶端

范例程序簡單的實現了HTTP1.0客戶端.程序演示了如何使用read_until和async_read_until函數.

  • boost_asio/example/http/client/sync_client.cpp
  • boost_asio/example/http/client/async_client.cpp

HTTP服務

范例闡述了在單線程中使用asio實現HTTP1.0服務.演示了如何執行清除命令結束未完成的異步操作.

  • boost_asio/example/http/server/connection.cpp
  • boost_asio/example/http/server/connection.hpp
  • boost_asio/example/http/server/connection_manager.cpp
  • boost_asio/example/http/server/connection_manager.hpp
  • boost_asio/example/http/server/header.hpp
  • boost_asio/example/http/server/main.cpp
  • boost_asio/example/http/server/mime_types.cpp
  • boost_asio/example/http/server/mime_types.hpp
  • boost_asio/example/http/server/reply.cpp
  • boost_asio/example/http/server/reply.hpp
  • boost_asio/example/http/server/request.hpp
  • boost_asio/example/http/server/request_handler.cpp
  • boost_asio/example/http/server/request_handler.hpp
  • boost_asio/example/http/server/request_parser.cpp
  • boost_asio/example/http/server/request_parser.hpp
  • boost_asio/example/http/server/server.cpp
  • boost_asio/example/http/server/server.hpp

HTTP服務2

使用io_service-per-CPU 設計的HTTP服務.

  • boost_asio/example/http/server2/connection.cpp
  • boost_asio/example/http/server2/connection.hpp
  • boost_asio/example/http/server2/header.hpp
  • boost_asio/example/http/server2/io_service_pool.cpp
  • boost_asio/example/http/server2/io_service_pool.hpp
  • boost_asio/example/http/server2/main.cpp
  • boost_asio/example/http/server2/mime_types.cpp
  • boost_asio/example/http/server2/mime_types.hpp
  • boost_asio/example/http/server2/reply.cpp
  • boost_asio/example/http/server2/reply.hpp
  • boost_asio/example/http/server2/request.hpp
  • boost_asio/example/http/server2/request_handler.cpp
  • boost_asio/example/http/server2/request_handler.hpp
  • boost_asio/example/http/server2/request_parser.cpp
  • boost_asio/example/http/server2/request_parser.hpp
  • boost_asio/example/http/server2/server.cpp
  • boost_asio/example/http/server2/server.hpp

HTTP服務3

使用單個io_service并在線程池上調用io_service::run()的HTTP服務.

  • boost_asio/example/http/server3/connection.cpp
  • boost_asio/example/http/server3/connection.hpp
  • boost_asio/example/http/server3/header.hpp
  • boost_asio/example/http/server3/main.cpp
  • boost_asio/example/http/server3/mime_types.cpp
  • boost_asio/example/http/server3/mime_types.hpp
  • boost_asio/example/http/server3/reply.cpp
  • boost_asio/example/http/server3/reply.hpp
  • boost_asio/example/http/server3/request.hpp
  • boost_asio/example/http/server3/request_handler.cpp
  • boost_asio/example/http/server3/request_handler.hpp
  • boost_asio/example/http/server3/request_parser.cpp
  • boost_asio/example/http/server3/request_parser.hpp
  • boost_asio/example/http/server3/server.cpp
  • boost_asio/example/http/server3/server.hpp

HTTP服務4

使用無棧協同技術實現單線程HTTP服務.

  • boost_asio/example/http/server4/coroutine.hpp
  • boost_asio/example/http/server4/file_handler.cpp
  • boost_asio/example/http/server4/file_handler.hpp
  • boost_asio/example/http/server4/header.hpp
  • boost_asio/example/http/server4/main.cpp
  • boost_asio/example/http/server4/mime_types.cpp
  • boost_asio/example/http/server4/mime_types.hpp
  • boost_asio/example/http/server4/reply.cpp
  • boost_asio/example/http/server4/reply.hpp
  • boost_asio/example/http/server4/request.hpp
  • boost_asio/example/http/server4/request_parser.cpp
  • boost_asio/example/http/server4/request_parser.hpp
  • boost_asio/example/http/server4/server.cpp
  • boost_asio/example/http/server4/server.hpp
  • boost_asio/example/http/server4/unyield.hpp
  • boost_asio/example/http/server4/yield.hpp

ICMP

展示如何在ICMP上使用原生的Socket ping遠程主機.

  • boost_asio/example/icmp/ping.cpp
  • boost_asio/example/icmp/ipv4_header.hpp
  • boost_asio/example/icmp/icmp_header.hpp

調用

展示如何自定義處理函數調用.將完成句柄加入到一個優先級隊列而不是直接調用.

  • boost_asio/example/invocation/prioritised_handlers.cpp

iostream

展示如何使用ip::tcp::iostream.

  • boost_asio/example/iostreams/daytime_client.cpp
  • boost_asio/example/iostreams/daytime_server.cpp
  • boost_asio/example/iostreams/http_client.cpp

廣播

展示使用廣播向訂閱組傳輸包.

  • boost_asio/example/multicast/receiver.cpp
  • boost_asio/example/multicast/sender.cpp

序列化

展示如何在asio中使用Boost.Serialization序列號和反序列化結構體,從而實現在Socket上傳輸數據對象.

  • boost_asio/example/serialization/client.cpp
  • boost_asio/example/serialization/connection.hpp
  • boost_asio/example/serialization/server.cpp
  • boost_asio/example/serialization/stock.hpp

服務

展示如何向asio的io_service整合自定義功能(本例中是添加了日志功能),以及在basic_stream_socket<>上使用自定義服務.

  • boost_asio/example/services/basic_logger.hpp
  • boost_asio/example/services/daytime_client.cpp
  • boost_asio/example/services/logger.hpp
  • boost_asio/example/services/logger_service.cpp
  • boost_asio/example/services/logger_service.hpp
  • boost_asio/example/services/stream_socket_service.hpp

SOCKS4協議

范例客戶端程序實現了通過代理通信的SOCKS4協議.

  • boost_asio/example/socks4/sync_client.cpp
  • boost_asio/example/socks4/socks4.hpp

SSL

客戶端和服務端范例程序演示了在異步操作中使用ssl::stream<>模板.

  • boost_asio/example/ssl/client.cpp
  • boost_asio/example/ssl/server.cpp

超時設定

下面的一系列范例展示了如何在指定時間之后取消長時間運行的異步操作.

  • boost_asio/example/timeouts/async_tcp_client.cpp
  • boost_asio/example/timeouts/blocking_tcp_client.cpp
  • boost_asio/example/timeouts/blocking_udp_client.cpp
  • boost_asio/example/timeouts/server.cpp

定時器

范例演示了如何定制deadline_time實現不同類型的計時器.

  • boost_asio/example/timers/tick_count_timer.cpp
  • boost_asio/example/timers/time_t_timer.cpp

Porthopper

本例演示了混合同步和異步操作,及如何在Boost.Asio中使用Boost.Lambda.

  • boost_asio/example/porthopper/protocol.hpp
  • boost_asio/example/porthopper/client.cpp
  • boost_asio/example/porthopper/server.cpp

無阻塞

展示如何整合實現IO操作的第三方庫來實現Reactor風格的操作.

  • boost_asio/example/nonblocking/third_party_lib.cpp

UNIX領域的Socket

展示如何使用UNIX領域的Socket.

  • boost_asio/example/local/connect_pair.cpp
  • boost_asio/example/local/stream_server.cpp
  • boost_asio/example/local/stream_client.cpp

Windows

展示如何在Boost.Asio中使用Windows特有的TransmitFile函數.

  • boost_asio/example/windows/transmit_file.cpp

總結

以上是生活随笔為你收集整理的Boost.Asio 技术文档的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

97久久国产亚洲精品超碰热 | 久久人妻内射无码一区三区 | 妺妺窝人体色www婷婷 | 亚洲日韩乱码中文无码蜜桃臀网站 | 国产性生交xxxxx无码 | 又色又爽又黄的美女裸体网站 | 午夜精品久久久久久久久 | 熟妇人妻无乱码中文字幕 | 婷婷色婷婷开心五月四房播播 | 久久综合给合久久狠狠狠97色 | 久久久亚洲欧洲日产国码αv | 白嫩日本少妇做爰 | 骚片av蜜桃精品一区 | 久久人人爽人人爽人人片av高清 | 亚洲综合精品香蕉久久网 | 亚洲日韩一区二区 | 久久久久久久人妻无码中文字幕爆 | 无码成人精品区在线观看 | 日韩成人一区二区三区在线观看 | 久久精品女人天堂av免费观看 | 日韩精品一区二区av在线 | 日本熟妇浓毛 | 久久亚洲国产成人精品性色 | 欧美国产日韩亚洲中文 | 55夜色66夜色国产精品视频 | 精品国产乱码久久久久乱码 | 亚洲精品一区二区三区在线观看 | 真人与拘做受免费视频 | 亚洲中文字幕乱码av波多ji | 国产精品永久免费视频 | 国产亚洲精品久久久闺蜜 | 国产一区二区三区日韩精品 | 亚洲一区二区三区在线观看网站 | 色妞www精品免费视频 | 成人无码精品1区2区3区免费看 | 少妇无套内谢久久久久 | а√天堂www在线天堂小说 | 88国产精品欧美一区二区三区 | 国产人妻精品一区二区三区不卡 | 日韩精品成人一区二区三区 | 国产亚av手机在线观看 | 亚洲午夜久久久影院 | 一本色道久久综合亚洲精品不卡 | 日本一卡二卡不卡视频查询 | 大胆欧美熟妇xx | 色五月丁香五月综合五月 | 国产日产欧产精品精品app | 色偷偷av老熟女 久久精品人妻少妇一区二区三区 | 牛和人交xxxx欧美 | 国产疯狂伦交大片 | 综合网日日天干夜夜久久 | 成人亚洲精品久久久久 | 中文无码精品a∨在线观看不卡 | 亚洲精品国偷拍自产在线观看蜜桃 | 久久久久久a亚洲欧洲av冫 | 麻豆人妻少妇精品无码专区 | 无码人妻出轨黑人中文字幕 | 99精品无人区乱码1区2区3区 | 日韩无码专区 | 亚洲综合精品香蕉久久网 | 精品无人国产偷自产在线 | 欧美国产日韩久久mv | 天天拍夜夜添久久精品大 | 老太婆性杂交欧美肥老太 | 国产亚洲精品久久久久久国模美 | 人妻插b视频一区二区三区 | 久久久久99精品成人片 | 无码国产激情在线观看 | 亚洲精品www久久久 | 丰满少妇熟乱xxxxx视频 | a在线观看免费网站大全 | 欧美 日韩 亚洲 在线 | 欧美日韩综合一区二区三区 | 久激情内射婷内射蜜桃人妖 | 人妻少妇被猛烈进入中文字幕 | 成人精品视频一区二区 | 精品人妻人人做人人爽夜夜爽 | 亚洲精品一区二区三区在线观看 | 成人免费无码大片a毛片 | 欧美丰满熟妇xxxx | 天天摸天天透天天添 | 国産精品久久久久久久 | 国产亚洲美女精品久久久2020 | 久久亚洲日韩精品一区二区三区 | 精品国产麻豆免费人成网站 | 亚洲成色在线综合网站 | 乱码av麻豆丝袜熟女系列 | 亚洲日本在线电影 | 青青久在线视频免费观看 | 亚洲 高清 成人 动漫 | 麻豆av传媒蜜桃天美传媒 | 国内少妇偷人精品视频 | 国产亚洲日韩欧美另类第八页 | 99久久亚洲精品无码毛片 | 中文字幕人妻丝袜二区 | 国内精品久久毛片一区二区 | 亚洲精品久久久久avwww潮水 | 一本色道久久综合狠狠躁 | 亚洲午夜无码久久 | 无遮挡啪啪摇乳动态图 | a在线亚洲男人的天堂 | 成熟妇人a片免费看网站 | 啦啦啦www在线观看免费视频 | 国产精品久久久久久久影院 | 老熟妇乱子伦牲交视频 | 欧美成人午夜精品久久久 | www一区二区www免费 | 少女韩国电视剧在线观看完整 | 欧洲精品码一区二区三区免费看 | 思思久久99热只有频精品66 | 国产香蕉97碰碰久久人人 | 麻豆果冻传媒2021精品传媒一区下载 | 国产精品亚洲一区二区三区喷水 | 动漫av一区二区在线观看 | 亚洲国产精品美女久久久久 | 国产免费久久精品国产传媒 | 欧洲vodafone精品性 | 国产亚洲欧美在线专区 | 亚洲自偷自偷在线制服 | 又大又黄又粗又爽的免费视频 | 国产农村妇女aaaaa视频 撕开奶罩揉吮奶头视频 | 欧美日本精品一区二区三区 | 无码毛片视频一区二区本码 | 日本成熟视频免费视频 | 亚洲国产精品一区二区美利坚 | 国产高清不卡无码视频 | 精品夜夜澡人妻无码av蜜桃 | 狠狠色欧美亚洲狠狠色www | 午夜成人1000部免费视频 | 色噜噜亚洲男人的天堂 | 无码任你躁久久久久久久 | 亚洲一区二区三区偷拍女厕 | 国产成人一区二区三区别 | 精品乱码久久久久久久 | 欧美日本免费一区二区三区 | 2019午夜福利不卡片在线 | 99视频精品全部免费免费观看 | 国产舌乚八伦偷品w中 | 国产精品美女久久久久av爽李琼 | 亚洲一区二区三区偷拍女厕 | 天堂久久天堂av色综合 | 免费无码的av片在线观看 | 欧美日韩色另类综合 | 天堂亚洲2017在线观看 | 久久无码专区国产精品s | 国产成人无码av片在线观看不卡 | 国产人妻精品午夜福利免费 | ass日本丰满熟妇pics | 精品无码一区二区三区爱欲 | 人妻无码久久精品人妻 | 亚洲阿v天堂在线 | 亚洲欧洲日本综合aⅴ在线 | 日韩人妻无码中文字幕视频 | 国内精品九九久久久精品 | 国产精品久久久久影院嫩草 | 精品无人区无码乱码毛片国产 | v一区无码内射国产 | 又大又硬又爽免费视频 | 性欧美videos高清精品 | 亚洲精品一区二区三区在线观看 | 十八禁视频网站在线观看 | 亚洲欧美日韩综合久久久 | 久久亚洲国产成人精品性色 | 精品国偷自产在线视频 | 无码中文字幕色专区 | 中文字幕无线码免费人妻 | 中文字幕av无码一区二区三区电影 | 婷婷五月综合激情中文字幕 | 婷婷综合久久中文字幕蜜桃三电影 | 久久国内精品自在自线 | 99久久久无码国产aaa精品 | 久久这里只有精品视频9 | 精品久久久无码中文字幕 | 国产肉丝袜在线观看 | 国产精品18久久久久久麻辣 | 一二三四在线观看免费视频 | 亚洲精品综合五月久久小说 | 漂亮人妻洗澡被公强 日日躁 | 亚洲午夜无码久久 | 麻豆md0077饥渴少妇 | 中文久久乱码一区二区 | 水蜜桃亚洲一二三四在线 | 久久无码中文字幕免费影院蜜桃 | 欧美日韩亚洲国产精品 | 亚洲一区二区三区 | 国产av人人夜夜澡人人爽麻豆 | 日日躁夜夜躁狠狠躁 | 亚洲小说春色综合另类 | 天天摸天天透天天添 | 亚洲精品美女久久久久久久 | 麻豆精品国产精华精华液好用吗 | 无码人妻少妇伦在线电影 | 99久久久国产精品无码免费 | 女人被男人躁得好爽免费视频 | 亚洲综合精品香蕉久久网 | 天天摸天天透天天添 | 女高中生第一次破苞av | 2019nv天堂香蕉在线观看 | 精品偷自拍另类在线观看 | 亚洲高清偷拍一区二区三区 | 国产亚洲精品久久久ai换 | 3d动漫精品啪啪一区二区中 | 亚洲一区二区三区香蕉 | 国产激情综合五月久久 | 久青草影院在线观看国产 | 久久精品国产99精品亚洲 | 少妇无套内谢久久久久 | 四虎永久在线精品免费网址 | 国产成人无码午夜视频在线观看 | 亚洲成av人综合在线观看 | 国产成人精品一区二区在线小狼 | 无码毛片视频一区二区本码 | 麻豆精品国产精华精华液好用吗 | 亚洲爆乳无码专区 | 无码精品人妻一区二区三区av | 伊人久久大香线焦av综合影院 | 曰本女人与公拘交酡免费视频 | 中文字幕人成乱码熟女app | 国产偷国产偷精品高清尤物 | 中文字幕无码日韩欧毛 | 国产熟妇高潮叫床视频播放 | 六十路熟妇乱子伦 | 无码av最新清无码专区吞精 | 国产精品沙发午睡系列 | 蜜桃av抽搐高潮一区二区 | 亚洲精品国产品国语在线观看 | 亚洲人亚洲人成电影网站色 | 久久人妻内射无码一区三区 | 中文字幕无码免费久久99 | 国产成人av免费观看 | 97精品国产97久久久久久免费 | 18黄暴禁片在线观看 | 久久久无码中文字幕久... | 国产亚洲精品精品国产亚洲综合 | 亚洲精品国偷拍自产在线观看蜜桃 | 丝袜美腿亚洲一区二区 | 少妇人妻大乳在线视频 | 伊人久久大香线蕉亚洲 | 丰满肥臀大屁股熟妇激情视频 | 99久久婷婷国产综合精品青草免费 | 性啪啪chinese东北女人 | 又黄又爽又色的视频 | 欧美 丝袜 自拍 制服 另类 | 男女作爱免费网站 | 国产99久久精品一区二区 | 特黄特色大片免费播放器图片 | 国产免费无码一区二区视频 | 精品偷自拍另类在线观看 | 激情国产av做激情国产爱 | 国产 精品 自在自线 | 亚洲熟妇色xxxxx欧美老妇y | 精品久久久久久人妻无码中文字幕 | 妺妺窝人体色www在线小说 | 欧美激情综合亚洲一二区 | 久久国产自偷自偷免费一区调 | 伊人久久大香线蕉av一区二区 | 亚拍精品一区二区三区探花 | 一本久道久久综合狠狠爱 | 日产精品99久久久久久 | 麻豆av传媒蜜桃天美传媒 | 西西人体www44rt大胆高清 | 日本欧美一区二区三区乱码 | av香港经典三级级 在线 | 暴力强奷在线播放无码 | 青青青爽视频在线观看 | 久久午夜无码鲁丝片午夜精品 | 无码人妻少妇伦在线电影 | 亚洲狠狠色丁香婷婷综合 | 欧美人妻一区二区三区 | 国产莉萝无码av在线播放 | 一二三四在线观看免费视频 | 女人被男人躁得好爽免费视频 | 无遮无挡爽爽免费视频 | 亚洲中文字幕无码一久久区 | 国产网红无码精品视频 | 日本精品高清一区二区 | 日韩精品无码一本二本三本色 | 大地资源中文第3页 | 亚洲爆乳大丰满无码专区 | 黑森林福利视频导航 | 成人亚洲精品久久久久软件 | 日韩精品成人一区二区三区 | 国产亚洲欧美日韩亚洲中文色 | 精品国产麻豆免费人成网站 | 日日碰狠狠丁香久燥 | 欧美激情一区二区三区成人 | 无码国模国产在线观看 | 国产色视频一区二区三区 | 中文字幕无码人妻少妇免费 | 久久人人爽人人爽人人片av高清 | 欧美丰满熟妇xxxx | 成人片黄网站色大片免费观看 | 国产性生大片免费观看性 | 少妇无码一区二区二三区 | 一本大道久久东京热无码av | 久久久www成人免费毛片 | 熟女体下毛毛黑森林 | 波多野结衣av一区二区全免费观看 | 131美女爱做视频 | 日本一卡二卡不卡视频查询 | 色综合久久久无码网中文 | av在线亚洲欧洲日产一区二区 | 男人的天堂av网站 | 中文字幕无码人妻少妇免费 | 成人aaa片一区国产精品 | 亚洲国产精品无码久久久久高潮 | 国产莉萝无码av在线播放 | 色婷婷久久一区二区三区麻豆 | 色一情一乱一伦一区二区三欧美 | 波多野结衣高清一区二区三区 | 97无码免费人妻超级碰碰夜夜 | 国产精品亚洲一区二区三区喷水 | 日本在线高清不卡免费播放 | 国产精品亚洲lv粉色 | 久久人人97超碰a片精品 | 性欧美熟妇videofreesex | 亚洲色无码一区二区三区 | 欧美精品在线观看 | 中国女人内谢69xxxx | 性欧美videos高清精品 | 久久久精品欧美一区二区免费 | 久久久久免费精品国产 | 熟妇人妻无码xxx视频 | av无码电影一区二区三区 | 夜先锋av资源网站 | 欧美 丝袜 自拍 制服 另类 | 国产在线无码精品电影网 | 97夜夜澡人人双人人人喊 | 国产偷自视频区视频 | 久青草影院在线观看国产 | 成熟妇人a片免费看网站 | 色欲人妻aaaaaaa无码 | 88国产精品欧美一区二区三区 | 中文字幕 人妻熟女 | 在线视频网站www色 | 欧美日韩视频无码一区二区三 | 亚洲 激情 小说 另类 欧美 | 好男人www社区 | 人人超人人超碰超国产 | 亚洲一区二区三区无码久久 | 亚洲色成人中文字幕网站 | 中文毛片无遮挡高清免费 | 午夜福利一区二区三区在线观看 | 国产精品美女久久久久av爽李琼 | 日韩无套无码精品 | 色欲久久久天天天综合网精品 | 色综合久久久久综合一本到桃花网 | 日韩亚洲欧美精品综合 | 成人免费视频在线观看 | 国产内射爽爽大片视频社区在线 | 人人妻人人澡人人爽人人精品浪潮 | 熟女少妇人妻中文字幕 | 国产精品鲁鲁鲁 | 少妇无码av无码专区在线观看 | 中文无码成人免费视频在线观看 | 一二三四在线观看免费视频 | 18黄暴禁片在线观看 | 日欧一片内射va在线影院 | 精品久久综合1区2区3区激情 | 999久久久国产精品消防器材 | 日本成熟视频免费视频 | 97夜夜澡人人双人人人喊 | 精品人人妻人人澡人人爽人人 | 纯爱无遮挡h肉动漫在线播放 | 国产亚av手机在线观看 | 国产在线无码精品电影网 | 久久人人爽人人爽人人片ⅴ | a国产一区二区免费入口 | 丰满人妻一区二区三区免费视频 | 曰韩少妇内射免费播放 | 欧美人与动性行为视频 | 强伦人妻一区二区三区视频18 | 日韩无套无码精品 | 亚洲 高清 成人 动漫 | 国产精品资源一区二区 | 丰满诱人的人妻3 | 国产无av码在线观看 | 东京一本一道一二三区 | 亚洲综合另类小说色区 | 精品久久综合1区2区3区激情 | 一个人免费观看的www视频 | 夜夜高潮次次欢爽av女 | 午夜精品久久久内射近拍高清 | 亚洲自偷自拍另类第1页 | 久久精品国产日本波多野结衣 | 丝袜 中出 制服 人妻 美腿 | 国产精品久久久久9999小说 | 草草网站影院白丝内射 | 亚洲国产精品一区二区美利坚 | 无码人妻av免费一区二区三区 | 午夜性刺激在线视频免费 | 国产做国产爱免费视频 | 久久久久久久久蜜桃 | 欧美老人巨大xxxx做受 | 九九综合va免费看 | 成人试看120秒体验区 | 高清不卡一区二区三区 | 欧美丰满老熟妇xxxxx性 | 精品无码一区二区三区的天堂 | 男女作爱免费网站 | 日韩欧美群交p片內射中文 | 亚洲国产av美女网站 | 国产精品久久久久久久影院 | 99视频精品全部免费免费观看 | 国产一精品一av一免费 | 蜜臀av在线观看 在线欧美精品一区二区三区 | 六十路熟妇乱子伦 | 日本一本二本三区免费 | 爱做久久久久久 | 麻豆国产97在线 | 欧洲 | 日本肉体xxxx裸交 | 性啪啪chinese东北女人 | 欧美真人作爱免费视频 | 久久久精品456亚洲影院 | 狠狠色噜噜狠狠狠7777奇米 | 乌克兰少妇性做爰 | 国产美女精品一区二区三区 | 国产suv精品一区二区五 | 亚洲欧洲无卡二区视頻 | 麻豆成人精品国产免费 | 国产精品久久久久9999小说 | 狂野欧美性猛交免费视频 | 久久久国产一区二区三区 | 天天av天天av天天透 | 女人被男人爽到呻吟的视频 | 樱花草在线社区www | 牲欲强的熟妇农村老妇女视频 | 亚洲aⅴ无码成人网站国产app | 国产一区二区三区影院 | 国产三级久久久精品麻豆三级 | 久久成人a毛片免费观看网站 | 激情内射亚州一区二区三区爱妻 | 欧美肥老太牲交大战 | 亚洲人成网站在线播放942 | 最新国产乱人伦偷精品免费网站 | 国产精品无码永久免费888 | 奇米综合四色77777久久 东京无码熟妇人妻av在线网址 | 亚洲国产午夜精品理论片 | 人妻有码中文字幕在线 | 无人区乱码一区二区三区 | 麻豆果冻传媒2021精品传媒一区下载 | 久久人妻内射无码一区三区 | 午夜精品一区二区三区的区别 | 日本大乳高潮视频在线观看 | 最新版天堂资源中文官网 | av香港经典三级级 在线 | 午夜精品一区二区三区在线观看 | 亚洲欧美国产精品久久 | 无码帝国www无码专区色综合 | 国产偷国产偷精品高清尤物 | 无套内谢老熟女 | 奇米影视7777久久精品 | 精品午夜福利在线观看 | 欧美丰满熟妇xxxx性ppx人交 | 久久久中文久久久无码 | 国产极品美女高潮无套在线观看 | 亚洲成av人片在线观看无码不卡 | 色窝窝无码一区二区三区色欲 | 国产精品无码一区二区桃花视频 | 亚洲一区二区三区香蕉 | 性色欲情网站iwww九文堂 | 色噜噜亚洲男人的天堂 | 国产精品多人p群无码 | 午夜福利试看120秒体验区 | 日韩欧美中文字幕公布 | 俺去俺来也www色官网 | 国产农村妇女aaaaa视频 撕开奶罩揉吮奶头视频 | 日本大香伊一区二区三区 | а√天堂www在线天堂小说 | 久久亚洲日韩精品一区二区三区 | 国产超碰人人爽人人做人人添 | 亚洲毛片av日韩av无码 | 久久精品人人做人人综合 | 国产电影无码午夜在线播放 | 色窝窝无码一区二区三区色欲 | 色偷偷人人澡人人爽人人模 | 老子影院午夜精品无码 | 东北女人啪啪对白 | 成 人 网 站国产免费观看 | 爱做久久久久久 | 精品亚洲韩国一区二区三区 | 欧美国产亚洲日韩在线二区 | 男女性色大片免费网站 | 少妇太爽了在线观看 | 色婷婷综合激情综在线播放 | 亚洲色无码一区二区三区 | aⅴ亚洲 日韩 色 图网站 播放 | 一个人看的www免费视频在线观看 | 日产精品高潮呻吟av久久 | 精品日本一区二区三区在线观看 | 无码人妻av免费一区二区三区 | 成人毛片一区二区 | 国产无av码在线观看 | 亚洲国产欧美日韩精品一区二区三区 | 爽爽影院免费观看 | 精品久久久中文字幕人妻 | 国产精品亚洲lv粉色 | 给我免费的视频在线观看 | 欧美色就是色 | 免费观看黄网站 | 久久久久久av无码免费看大片 | 高潮毛片无遮挡高清免费 | 日本乱人伦片中文三区 | 国产亚洲美女精品久久久2020 | 亚洲中文字幕av在天堂 | 亚洲伊人久久精品影院 | 国产真实夫妇视频 | 99精品国产综合久久久久五月天 | 四虎国产精品免费久久 | 99国产欧美久久久精品 | 亚洲日韩乱码中文无码蜜桃臀网站 | 老子影院午夜伦不卡 | 成人动漫在线观看 | 亚洲另类伦春色综合小说 | 精品少妇爆乳无码av无码专区 | yw尤物av无码国产在线观看 | 久久99精品久久久久久动态图 | 免费看男女做好爽好硬视频 | 国产三级精品三级男人的天堂 | 国产精品人人爽人人做我的可爱 | 亚洲欧美综合区丁香五月小说 | 2020久久香蕉国产线看观看 | 综合激情五月综合激情五月激情1 | 天天av天天av天天透 | 亚洲精品www久久久 | 国产后入清纯学生妹 | 两性色午夜免费视频 | 国内少妇偷人精品视频 | 内射白嫩少妇超碰 | 激情五月综合色婷婷一区二区 | 国产精品亚洲综合色区韩国 | 日韩 欧美 动漫 国产 制服 | 免费观看的无遮挡av | 色婷婷香蕉在线一区二区 | 四虎国产精品一区二区 | 荫蒂添的好舒服视频囗交 | 欧美熟妇另类久久久久久不卡 | 人妻插b视频一区二区三区 | 成年美女黄网站色大免费视频 | 欧美日韩久久久精品a片 | 女人被男人躁得好爽免费视频 | 男女猛烈xx00免费视频试看 | 亚洲精品综合五月久久小说 | 人人爽人人爽人人片av亚洲 | 无码任你躁久久久久久久 | 狠狠色丁香久久婷婷综合五月 | 久久婷婷五月综合色国产香蕉 | 性欧美牲交在线视频 | 国产精品亚洲专区无码不卡 | 国产suv精品一区二区五 | 国产激情精品一区二区三区 | 中文字幕无码视频专区 | 澳门永久av免费网站 | 欧美老人巨大xxxx做受 | 日本精品久久久久中文字幕 | 少妇被黑人到高潮喷出白浆 | 少妇激情av一区二区 | 亚洲日本一区二区三区在线 | av人摸人人人澡人人超碰下载 | 亚洲色大成网站www | 精品久久久久久亚洲精品 | 2019午夜福利不卡片在线 | 99精品久久毛片a片 | 久久久久成人精品免费播放动漫 | 图片区 小说区 区 亚洲五月 | 国产三级久久久精品麻豆三级 | 人妻熟女一区 | 国产成人一区二区三区在线观看 | 天天燥日日燥 | 国产va免费精品观看 | 亚洲精品一区国产 | 亚洲欧美日韩综合久久久 | 亚洲欧洲日本无在线码 | yw尤物av无码国产在线观看 | 精品久久久久香蕉网 | 欧美熟妇另类久久久久久多毛 | 久久亚洲国产成人精品性色 | 久久久www成人免费毛片 | 99国产精品白浆在线观看免费 | 领导边摸边吃奶边做爽在线观看 | av无码久久久久不卡免费网站 | 精品无人区无码乱码毛片国产 | 18黄暴禁片在线观看 | 东京一本一道一二三区 | 女人和拘做爰正片视频 | 丰满人妻被黑人猛烈进入 | 无码精品国产va在线观看dvd | 亚洲综合色区中文字幕 | 亚洲熟妇色xxxxx亚洲 | 国产在线无码精品电影网 | 日本大香伊一区二区三区 | 亚洲国产精品成人久久蜜臀 | 亚洲国产成人a精品不卡在线 | 中文字幕乱码中文乱码51精品 | 亚洲综合无码久久精品综合 | 人妻aⅴ无码一区二区三区 | 亚洲男人av香蕉爽爽爽爽 | 澳门永久av免费网站 | 国产精品亚洲lv粉色 | 色欲久久久天天天综合网精品 | 亚洲精品国产品国语在线观看 | 日韩人妻无码中文字幕视频 | 夜夜夜高潮夜夜爽夜夜爰爰 | 久久久久久九九精品久 | 久久久国产精品无码免费专区 | 在线天堂新版最新版在线8 | 无码人妻少妇伦在线电影 | 又色又爽又黄的美女裸体网站 | 亚洲熟悉妇女xxx妇女av | 少妇愉情理伦片bd | 欧美高清在线精品一区 | 久久99精品国产麻豆蜜芽 | 男人扒开女人内裤强吻桶进去 | 1000部啪啪未满十八勿入下载 | 欧美激情综合亚洲一二区 | 亚洲精品无码国产 | 国产三级精品三级男人的天堂 | 亚洲色在线无码国产精品不卡 | 精品成在人线av无码免费看 | 日本肉体xxxx裸交 | 免费无码午夜福利片69 | 国产精品无码一区二区三区不卡 | 日日碰狠狠躁久久躁蜜桃 | 欧美老妇交乱视频在线观看 | 熟女体下毛毛黑森林 | 久久久久免费精品国产 | 国产亚洲日韩欧美另类第八页 | 国产成人综合色在线观看网站 | 亚洲精品国产精品乱码视色 | 国产乱人伦偷精品视频 | 亚洲色无码一区二区三区 | 亚洲狠狠色丁香婷婷综合 | 国产精品久久久久久亚洲毛片 | 亚洲人成人无码网www国产 | 亚洲色大成网站www | 精品aⅴ一区二区三区 | 香蕉久久久久久av成人 | 日本一卡二卡不卡视频查询 | 真人与拘做受免费视频一 | 18无码粉嫩小泬无套在线观看 | 人人爽人人澡人人高潮 | 国产精品18久久久久久麻辣 | 国产成人av免费观看 | 国产熟女一区二区三区四区五区 | 永久免费观看国产裸体美女 | 天堂а√在线中文在线 | 一本色道久久综合狠狠躁 | 精品久久综合1区2区3区激情 | 国产一区二区三区四区五区加勒比 | 国产另类ts人妖一区二区 | 欧美午夜特黄aaaaaa片 | 国产亚洲精品久久久ai换 | 精品久久久久久人妻无码中文字幕 | 国产一精品一av一免费 | 妺妺窝人体色www在线小说 | 免费男性肉肉影院 | 亚洲成av人影院在线观看 | 无码纯肉视频在线观看 | 噜噜噜亚洲色成人网站 | 丰满人妻一区二区三区免费视频 | 成人免费视频在线观看 | 久久99精品久久久久婷婷 | 欧美肥老太牲交大战 | 大地资源网第二页免费观看 | 色综合久久中文娱乐网 | 内射后入在线观看一区 | 国产精品无码mv在线观看 | 国产亚洲日韩欧美另类第八页 | 亚洲国产欧美日韩精品一区二区三区 | 一本精品99久久精品77 | 牲欲强的熟妇农村老妇女视频 | 国产成人综合色在线观看网站 | 亚洲中文字幕成人无码 | 亚洲精品一区二区三区婷婷月 | 青青久在线视频免费观看 | 久久精品国产亚洲精品 | 人人澡人摸人人添 | 澳门永久av免费网站 | 强开小婷嫩苞又嫩又紧视频 | 青草青草久热国产精品 | 99久久精品日本一区二区免费 | 国产手机在线αⅴ片无码观看 | 香港三级日本三级妇三级 | 99久久99久久免费精品蜜桃 | 亚洲男女内射在线播放 | 久久精品国产精品国产精品污 | 内射爽无广熟女亚洲 | 亚洲 欧美 激情 小说 另类 | 扒开双腿吃奶呻吟做受视频 | 久久久久久av无码免费看大片 | 熟女少妇在线视频播放 | 精品久久8x国产免费观看 | 日本护士xxxxhd少妇 | 亚洲日本va中文字幕 | 亚洲色www成人永久网址 | 色诱久久久久综合网ywww | 亚洲精品成人av在线 | 久久综合色之久久综合 | 久久精品国产亚洲精品 | 亚洲乱码中文字幕在线 | 亚洲中文字幕无码中文字在线 | 国产真实乱对白精彩久久 | 国产亚洲精品久久久ai换 | 色婷婷av一区二区三区之红樱桃 | 蜜臀av在线观看 在线欧美精品一区二区三区 | 99久久久无码国产aaa精品 | 精品久久久无码人妻字幂 | 日韩 欧美 动漫 国产 制服 | 免费观看又污又黄的网站 | 国产免费久久精品国产传媒 | 动漫av一区二区在线观看 | www国产精品内射老师 | 国产精品永久免费视频 | 国产无遮挡又黄又爽免费视频 | 欧美成人免费全部网站 | 亚洲精品综合五月久久小说 | 狂野欧美性猛xxxx乱大交 | 国产成人精品一区二区在线小狼 | 国产日产欧产精品精品app | 风流少妇按摩来高潮 | 精品久久久久久人妻无码中文字幕 | 欧美午夜特黄aaaaaa片 | 久久99热只有频精品8 | 欧美三级a做爰在线观看 | 国产精品对白交换视频 | 男女爱爱好爽视频免费看 | 无码人妻精品一区二区三区下载 | 狂野欧美激情性xxxx | 国产尤物精品视频 | 中文字幕无线码 | 成 人影片 免费观看 | 亚洲精品一区二区三区大桥未久 | 精品无码国产自产拍在线观看蜜 | 小sao货水好多真紧h无码视频 | 国产精品无码一区二区桃花视频 | 中文无码成人免费视频在线观看 | 爽爽影院免费观看 | 中文字幕乱码人妻二区三区 | 荫蒂被男人添的好舒服爽免费视频 | 久久综合给合久久狠狠狠97色 | 精品人妻人人做人人爽 | 宝宝好涨水快流出来免费视频 | 狠狠色噜噜狠狠狠狠7777米奇 | 最近免费中文字幕中文高清百度 | 亚洲综合伊人久久大杳蕉 | 日本一区二区三区免费播放 | 国产激情综合五月久久 | 亚洲欧洲日本综合aⅴ在线 | 久久久www成人免费毛片 | 亚洲国产精品无码一区二区三区 | 奇米影视7777久久精品人人爽 | 女人和拘做爰正片视频 | 人妻人人添人妻人人爱 | 国产精品久久久久久久影院 | 日日摸天天摸爽爽狠狠97 | 久久人妻内射无码一区三区 | 强辱丰满人妻hd中文字幕 | 久久婷婷五月综合色国产香蕉 | 亚洲国产日韩a在线播放 | 国产av无码专区亚洲awww | 国产一区二区三区四区五区加勒比 | 一本色道久久综合亚洲精品不卡 | 精品日本一区二区三区在线观看 | 欧美人与禽猛交狂配 | 无码av最新清无码专区吞精 | 粉嫩少妇内射浓精videos | 鲁鲁鲁爽爽爽在线视频观看 | 亚洲精品成人福利网站 | 欧美熟妇另类久久久久久不卡 | 久久精品中文闷骚内射 | 免费国产黄网站在线观看 | 欧美成人午夜精品久久久 | 麻豆成人精品国产免费 | 国产国语老龄妇女a片 | 亚洲熟妇色xxxxx亚洲 | 亚洲中文字幕va福利 | 2020最新国产自产精品 | 人妻人人添人妻人人爱 | 国产免费无码一区二区视频 | 久久精品国产99精品亚洲 | 亚洲色偷偷男人的天堂 | 丰满护士巨好爽好大乳 | 九九热爱视频精品 | 亚洲国产av美女网站 | 丰满诱人的人妻3 | 思思久久99热只有频精品66 | 97久久国产亚洲精品超碰热 | 300部国产真实乱 | 久久亚洲a片com人成 | 中文字幕av日韩精品一区二区 | 久久久久av无码免费网 | 狠狠色噜噜狠狠狠狠7777米奇 | 国产精品亚洲а∨无码播放麻豆 | 综合激情五月综合激情五月激情1 | 国产精品视频免费播放 | 国产精品人人爽人人做我的可爱 | 99国产欧美久久久精品 | 欧美亚洲国产一区二区三区 | 天海翼激烈高潮到腰振不止 | 亚洲爆乳精品无码一区二区三区 | 一本久久a久久精品亚洲 | 国产成人无码a区在线观看视频app | 中文字幕人妻无码一区二区三区 | 色一情一乱一伦一视频免费看 | 日韩精品无码一区二区中文字幕 | 国产莉萝无码av在线播放 | 精品偷自拍另类在线观看 | 丰满妇女强制高潮18xxxx | 国产熟妇另类久久久久 | 无码一区二区三区在线 | 国产精品久久精品三级 | 欧美丰满熟妇xxxx性ppx人交 | 蜜桃无码一区二区三区 | 丰满肥臀大屁股熟妇激情视频 | 国产香蕉97碰碰久久人人 | 日韩精品久久久肉伦网站 | 国语自产偷拍精品视频偷 | 帮老师解开蕾丝奶罩吸乳网站 | 亚洲国产精华液网站w | 日韩少妇白浆无码系列 | 97色伦图片97综合影院 | 久久精品中文字幕大胸 | 少妇高潮喷潮久久久影院 | av人摸人人人澡人人超碰下载 | 天堂а√在线中文在线 | 高潮毛片无遮挡高清免费视频 | 色综合久久久久综合一本到桃花网 | 久久99精品国产.久久久久 | 国产精品嫩草久久久久 | 亚洲欧美精品伊人久久 | 国产亚洲美女精品久久久2020 | 小sao货水好多真紧h无码视频 | 国产精品亚洲综合色区韩国 | 中文字幕无码免费久久9一区9 | 红桃av一区二区三区在线无码av | 99久久久国产精品无码免费 | 亚洲国产精品一区二区第一页 | 国产成人无码区免费内射一片色欲 | 久久久久久国产精品无码下载 | 中文字幕无码免费久久9一区9 | 久久综合给合久久狠狠狠97色 | 亚洲s码欧洲m码国产av | 在线成人www免费观看视频 | 久久精品女人天堂av免费观看 | 福利一区二区三区视频在线观看 | 1000部啪啪未满十八勿入下载 | 少妇激情av一区二区 | 欧美真人作爱免费视频 | 国产香蕉97碰碰久久人人 | 乱人伦中文视频在线观看 | www成人国产高清内射 | 日本欧美一区二区三区乱码 | 中文字幕无线码 | 免费国产黄网站在线观看 | 国产在线精品一区二区三区直播 | 国产精品二区一区二区aⅴ污介绍 | 97无码免费人妻超级碰碰夜夜 | 国产色在线 | 国产 | 中文字幕无码av激情不卡 | 丰满少妇女裸体bbw | 人人爽人人爽人人片av亚洲 | 国产在线一区二区三区四区五区 | 特大黑人娇小亚洲女 | 学生妹亚洲一区二区 | а√资源新版在线天堂 | 精品无码国产一区二区三区av | 亚洲日韩av一区二区三区四区 | 国产一区二区三区精品视频 | 夜夜躁日日躁狠狠久久av | 中国大陆精品视频xxxx | 国产精品久久久久久久影院 | 亚洲一区二区三区在线观看网站 | 亚洲国产日韩a在线播放 | 成人亚洲精品久久久久 | 欧美高清在线精品一区 | 俺去俺来也www色官网 | 成熟女人特级毛片www免费 | 无码人妻丰满熟妇区毛片18 | 国产午夜手机精彩视频 | 欧美日韩视频无码一区二区三 | 夜夜夜高潮夜夜爽夜夜爰爰 | 男人扒开女人内裤强吻桶进去 | 在线播放免费人成毛片乱码 | 亚洲の无码国产の无码影院 | 国内少妇偷人精品视频免费 | 黑人巨大精品欧美黑寡妇 | 久久精品中文字幕大胸 | 亚洲精品一区国产 | 成人欧美一区二区三区 | 亚洲性无码av中文字幕 | 中文字幕 亚洲精品 第1页 | 日本又色又爽又黄的a片18禁 | 国产特级毛片aaaaaaa高清 | 日韩成人一区二区三区在线观看 | 久久人妻内射无码一区三区 | 国产成人无码午夜视频在线观看 | av在线亚洲欧洲日产一区二区 | 国语精品一区二区三区 | 国产亚洲日韩欧美另类第八页 | 亚洲小说春色综合另类 | 国产精品无码永久免费888 | 人妻尝试又大又粗久久 | 免费人成在线视频无码 | 久久aⅴ免费观看 | 99久久精品国产一区二区蜜芽 | 日韩无套无码精品 | 亲嘴扒胸摸屁股激烈网站 | 九九综合va免费看 | 久久亚洲精品成人无码 | 最近的中文字幕在线看视频 | 帮老师解开蕾丝奶罩吸乳网站 | 国产9 9在线 | 中文 | 国产乡下妇女做爰 | 色综合久久久无码中文字幕 | 国产亚洲视频中文字幕97精品 | 国产亚洲日韩欧美另类第八页 | 欧美日韩一区二区免费视频 | 国产香蕉尹人综合在线观看 | 中文字幕乱码人妻无码久久 | 精品乱码久久久久久久 | 日产精品高潮呻吟av久久 | 欧美日韩久久久精品a片 | 人妻无码久久精品人妻 | 99久久久无码国产aaa精品 | 任你躁国产自任一区二区三区 | 97精品人妻一区二区三区香蕉 | 18精品久久久无码午夜福利 | 久久久久se色偷偷亚洲精品av | 久久久精品456亚洲影院 | 大胆欧美熟妇xx | 未满小14洗澡无码视频网站 | 成人亚洲精品久久久久软件 | 国产精品成人av在线观看 | 国产激情一区二区三区 | 久久午夜夜伦鲁鲁片无码免费 | 成年美女黄网站色大免费全看 | 欧美xxxxx精品 | 亚洲国产精品毛片av不卡在线 | 伊人久久大香线蕉亚洲 | 国产午夜福利100集发布 | 国产熟女一区二区三区四区五区 | 欧美成人家庭影院 | 亚洲欧美日韩成人高清在线一区 | 中文字幕无码视频专区 | 东京无码熟妇人妻av在线网址 | 亚洲日韩一区二区三区 | 香港三级日本三级妇三级 | 国产亚洲精品久久久久久国模美 | 国产两女互慰高潮视频在线观看 | 亚洲s码欧洲m码国产av | 桃花色综合影院 | 成 人 网 站国产免费观看 | 国产亚洲人成a在线v网站 | 最近中文2019字幕第二页 | 超碰97人人做人人爱少妇 | 久久97精品久久久久久久不卡 | 人妻少妇精品视频专区 | 亚洲国产av美女网站 | 国产激情综合五月久久 | 亚洲性无码av中文字幕 | 日韩亚洲欧美中文高清在线 | 无码国模国产在线观看 | 亚洲成a人片在线观看无码 | 又粗又大又硬毛片免费看 | 无码国产激情在线观看 | 小sao货水好多真紧h无码视频 | 野狼第一精品社区 | 国产内射老熟女aaaa | 久久久精品456亚洲影院 | 精品欧洲av无码一区二区三区 | 久久久精品欧美一区二区免费 | 亚洲国产欧美日韩精品一区二区三区 | 免费国产成人高清在线观看网站 | 亚洲高清偷拍一区二区三区 | 亚洲性无码av中文字幕 | 51国偷自产一区二区三区 | 亚洲中文字幕乱码av波多ji | 久久久久成人精品免费播放动漫 | 97夜夜澡人人爽人人喊中国片 | 国产电影无码午夜在线播放 | 三级4级全黄60分钟 | 欧美日韩一区二区三区自拍 | 久久www免费人成人片 | 欧美三级不卡在线观看 | 伊人久久大香线蕉av一区二区 | 精品无码成人片一区二区98 | 国产97人人超碰caoprom | 欧美人与禽zoz0性伦交 | 在线视频网站www色 | www一区二区www免费 | 性欧美疯狂xxxxbbbb | 婷婷综合久久中文字幕蜜桃三电影 | 成人女人看片免费视频放人 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 久久久久亚洲精品男人的天堂 | 无码人妻出轨黑人中文字幕 | 在线精品国产一区二区三区 | 亚洲自偷精品视频自拍 | 偷窥村妇洗澡毛毛多 | 天天拍夜夜添久久精品大 | 国产精品久免费的黄网站 | 人人妻人人澡人人爽精品欧美 | 精品久久综合1区2区3区激情 | 九九热爱视频精品 | 国产精品第一区揄拍无码 | 激情五月综合色婷婷一区二区 | 最近的中文字幕在线看视频 | 午夜福利电影 | 中文字幕无码免费久久9一区9 | 男人和女人高潮免费网站 | 国产又粗又硬又大爽黄老大爷视 | 无人区乱码一区二区三区 | 国产精品亚洲lv粉色 | 亚洲精品久久久久中文第一幕 | 美女毛片一区二区三区四区 | 欧美丰满少妇xxxx性 | 西西人体www44rt大胆高清 | 国产片av国语在线观看 | 中文字幕人成乱码熟女app | 亚洲熟悉妇女xxx妇女av | 无人区乱码一区二区三区 | 狠狠亚洲超碰狼人久久 | 亚洲综合无码久久精品综合 | 永久免费观看美女裸体的网站 | 两性色午夜视频免费播放 | 精品偷拍一区二区三区在线看 | 妺妺窝人体色www在线小说 | 久久国产精品萌白酱免费 | 日韩欧美中文字幕在线三区 | 国产9 9在线 | 中文 | 成人欧美一区二区三区黑人免费 | 乱人伦人妻中文字幕无码 | 国产亲子乱弄免费视频 | 久久精品人人做人人综合试看 | 又粗又大又硬毛片免费看 | 亚洲一区二区三区 | 人妻中文无码久热丝袜 | а√天堂www在线天堂小说 | 成年女人永久免费看片 | 亚洲熟妇色xxxxx欧美老妇y | 88国产精品欧美一区二区三区 | 亚洲无人区午夜福利码高清完整版 | 精品无码一区二区三区的天堂 | 欧洲精品码一区二区三区免费看 | 在线欧美精品一区二区三区 | 久久久精品人妻久久影视 | 精品日本一区二区三区在线观看 | 国产女主播喷水视频在线观看 | 黑人大群体交免费视频 | 亚洲天堂2017无码 | 人妻aⅴ无码一区二区三区 | 欧美日韩在线亚洲综合国产人 | 在线播放免费人成毛片乱码 | 亚洲国产成人a精品不卡在线 | 丰腴饱满的极品熟妇 | 99久久精品午夜一区二区 | 久久久久久国产精品无码下载 | 3d动漫精品啪啪一区二区中 | 99久久久无码国产aaa精品 | 狂野欧美性猛交免费视频 | 精品偷拍一区二区三区在线看 | 亚洲成av人在线观看网址 | 国产香蕉尹人综合在线观看 | 午夜精品一区二区三区的区别 | 久久综合给合久久狠狠狠97色 | 无码精品国产va在线观看dvd | 亚洲精品一区国产 | 中国大陆精品视频xxxx | 成 人 免费观看网站 | 国产一区二区三区日韩精品 | 欧美性黑人极品hd | 亚洲 激情 小说 另类 欧美 | 精品国产乱码久久久久乱码 | 久久精品中文闷骚内射 | 一区二区传媒有限公司 | 精品无人国产偷自产在线 | www成人国产高清内射 | 国产在线精品一区二区三区直播 | 国产精品无码一区二区三区不卡 | 亚洲成a人片在线观看无码 | 无码av最新清无码专区吞精 | 日韩无码专区 | 青青草原综合久久大伊人精品 | 精品久久久久久人妻无码中文字幕 | 久久国产自偷自偷免费一区调 | 国内精品九九久久久精品 | 国产精品人人爽人人做我的可爱 | 18黄暴禁片在线观看 | 中文字幕人妻无码一区二区三区 | 久久午夜无码鲁丝片午夜精品 | 久久成人a毛片免费观看网站 | 国产香蕉尹人综合在线观看 | 四虎4hu永久免费 | 国内精品一区二区三区不卡 | 免费无码午夜福利片69 | 国产成人无码区免费内射一片色欲 | 88国产精品欧美一区二区三区 | 精品国产青草久久久久福利 | 无码中文字幕色专区 | 久久亚洲a片com人成 | 国产成人精品无码播放 | 国产猛烈高潮尖叫视频免费 | 国内精品九九久久久精品 | 国内少妇偷人精品视频免费 | 精品国产一区二区三区四区在线看 | 亚洲色在线无码国产精品不卡 | 国产肉丝袜在线观看 | 曰本女人与公拘交酡免费视频 | 熟妇人妻无码xxx视频 | 免费人成在线观看网站 | 亚洲无人区午夜福利码高清完整版 | 久久天天躁狠狠躁夜夜免费观看 | 伊在人天堂亚洲香蕉精品区 | 亚拍精品一区二区三区探花 | 2020久久香蕉国产线看观看 | √8天堂资源地址中文在线 | 又色又爽又黄的美女裸体网站 | 国产亚洲欧美在线专区 | 国产热a欧美热a在线视频 | 亚洲色在线无码国产精品不卡 | 国产精品沙发午睡系列 | 国产av久久久久精东av | 无码午夜成人1000部免费视频 | 午夜精品一区二区三区在线观看 | 久久久久免费看成人影片 | 丰满护士巨好爽好大乳 | 波多野结衣高清一区二区三区 | 99riav国产精品视频 | 色偷偷人人澡人人爽人人模 | 扒开双腿疯狂进出爽爽爽视频 | 国产无套内射久久久国产 | 免费观看黄网站 | 久久国产精品偷任你爽任你 | 奇米影视888欧美在线观看 | 99久久婷婷国产综合精品青草免费 | 婷婷六月久久综合丁香 | 永久免费观看美女裸体的网站 | 午夜精品一区二区三区在线观看 | 最新国产乱人伦偷精品免费网站 | 蜜桃无码一区二区三区 | 国产亚洲精品久久久久久久久动漫 | 又大又紧又粉嫩18p少妇 | 九月婷婷人人澡人人添人人爽 | 欧美日韩色另类综合 | 领导边摸边吃奶边做爽在线观看 | 精品人妻人人做人人爽 | 日产精品高潮呻吟av久久 | 人妻无码久久精品人妻 | 国产黑色丝袜在线播放 | 精品国产一区二区三区四区 | 免费人成在线观看网站 | aⅴ亚洲 日韩 色 图网站 播放 | 中文久久乱码一区二区 | 成熟妇人a片免费看网站 | 天天拍夜夜添久久精品 | 国产亚洲精品久久久久久国模美 | а√资源新版在线天堂 | 中文字幕无线码 | 精品成在人线av无码免费看 | 国产熟妇另类久久久久 | 99久久99久久免费精品蜜桃 | 麻豆国产97在线 | 欧洲 | 无码任你躁久久久久久久 | 麻豆国产97在线 | 欧洲 | 国内揄拍国内精品少妇国语 | 精品久久久久久人妻无码中文字幕 | 精品国产乱码久久久久乱码 | 日本肉体xxxx裸交 | 精品国产av色一区二区深夜久久 | 免费网站看v片在线18禁无码 | 无遮挡国产高潮视频免费观看 | 久久午夜无码鲁丝片秋霞 | 国产电影无码午夜在线播放 | 无码午夜成人1000部免费视频 | 无码国模国产在线观看 | 久久亚洲中文字幕精品一区 | 国产高潮视频在线观看 | 欧美国产亚洲日韩在线二区 | 夜夜夜高潮夜夜爽夜夜爰爰 | 暴力强奷在线播放无码 | 帮老师解开蕾丝奶罩吸乳网站 | 欧美黑人巨大xxxxx | 亚洲精品欧美二区三区中文字幕 | 人妻少妇被猛烈进入中文字幕 | 国产va免费精品观看 | 女人被男人躁得好爽免费视频 | 沈阳熟女露脸对白视频 | 日韩精品无码免费一区二区三区 | 亚洲精品久久久久久久久久久 | 亚洲日本va中文字幕 | 亚洲欧美色中文字幕在线 | 国产女主播喷水视频在线观看 | 欧美国产日韩久久mv | 日日鲁鲁鲁夜夜爽爽狠狠 | 国产精品亚洲一区二区三区喷水 | 综合网日日天干夜夜久久 | 日日躁夜夜躁狠狠躁 | 一本加勒比波多野结衣 | 色婷婷久久一区二区三区麻豆 | 99精品无人区乱码1区2区3区 | 久久精品99久久香蕉国产色戒 | 国产熟妇高潮叫床视频播放 | 人人妻在人人 | a片免费视频在线观看 | 国产亚洲欧美在线专区 | 亚洲a无码综合a国产av中文 | av无码久久久久不卡免费网站 | 中文字幕中文有码在线 | 黑森林福利视频导航 | 久久精品中文字幕大胸 | 国产精品二区一区二区aⅴ污介绍 | 日本精品高清一区二区 | 精品人妻人人做人人爽夜夜爽 | 亚洲国产av美女网站 | 在教室伦流澡到高潮hnp视频 | 亚洲七七久久桃花影院 | 亚洲色www成人永久网址 | 国产精品久久久久无码av色戒 | 宝宝好涨水快流出来免费视频 | 日产精品99久久久久久 | 日日橹狠狠爱欧美视频 | 国产69精品久久久久app下载 | 好男人www社区 | 在线欧美精品一区二区三区 | 久久久久免费精品国产 | 成熟妇人a片免费看网站 | 性欧美疯狂xxxxbbbb | 中文字幕无线码 | 久久伊人色av天堂九九小黄鸭 | 欧洲极品少妇 | 18无码粉嫩小泬无套在线观看 | 国产精品久久精品三级 | 欧美 日韩 人妻 高清 中文 | 久久午夜无码鲁丝片午夜精品 | 国产偷抇久久精品a片69 | 日日麻批免费40分钟无码 | 亚洲成av人综合在线观看 | 成熟妇人a片免费看网站 | 最近免费中文字幕中文高清百度 | 亚洲精品一区三区三区在线观看 | 给我免费的视频在线观看 | 久久人人爽人人人人片 | 男女作爱免费网站 | 青青青手机频在线观看 | 精品亚洲韩国一区二区三区 | 伊人久久大香线焦av综合影院 | 狠狠色噜噜狠狠狠狠7777米奇 | 国产农村妇女高潮大叫 | 精品久久综合1区2区3区激情 | 亚洲熟妇自偷自拍另类 | 色综合久久久无码中文字幕 | 国产成人精品三级麻豆 | 国产猛烈高潮尖叫视频免费 | 国产农村妇女aaaaa视频 撕开奶罩揉吮奶头视频 | 国产精品99久久精品爆乳 | 天海翼激烈高潮到腰振不止 | 久久久av男人的天堂 | 国产精品美女久久久久av爽李琼 | 性生交大片免费看女人按摩摩 | 国精品人妻无码一区二区三区蜜柚 | 好屌草这里只有精品 | 免费人成在线视频无码 | 久久久久久久久蜜桃 | 综合网日日天干夜夜久久 | 夜夜躁日日躁狠狠久久av | 天天av天天av天天透 | 麻豆国产人妻欲求不满谁演的 | 中文字幕av日韩精品一区二区 | 性色欲网站人妻丰满中文久久不卡 | 欧美第一黄网免费网站 | 一本无码人妻在中文字幕免费 | 少妇无码av无码专区在线观看 | 又大又黄又粗又爽的免费视频 | 国产suv精品一区二区五 | 国产精品久久久午夜夜伦鲁鲁 | 窝窝午夜理论片影院 | 超碰97人人射妻 | 久久视频在线观看精品 | 免费人成在线视频无码 | 国产精华av午夜在线观看 | 久久亚洲国产成人精品性色 | 无码人妻出轨黑人中文字幕 | 国产精华av午夜在线观看 | 丰满少妇人妻久久久久久 | 性生交大片免费看女人按摩摩 | 7777奇米四色成人眼影 | 性史性农村dvd毛片 | 亚洲乱码日产精品bd | 丝袜足控一区二区三区 | 亚洲国产欧美在线成人 | 精品无码av一区二区三区 | 欧美丰满熟妇xxxx | 亚洲欧美国产精品专区久久 | 天海翼激烈高潮到腰振不止 | 中文毛片无遮挡高清免费 | 真人与拘做受免费视频 | 少妇邻居内射在线 | 亚洲日韩av一区二区三区中文 | 国精产品一区二区三区 | 伊人色综合久久天天小片 | 亚洲经典千人经典日产 | 熟女少妇在线视频播放 | 亚洲精品成人福利网站 | 无人区乱码一区二区三区 | 帮老师解开蕾丝奶罩吸乳网站 | 伊人久久大香线蕉午夜 | 国内精品久久毛片一区二区 | 在线亚洲高清揄拍自拍一品区 | 2020久久超碰国产精品最新 | av在线亚洲欧洲日产一区二区 | 日韩精品无码一区二区中文字幕 | 久久国产劲爆∧v内射 | 欧美阿v高清资源不卡在线播放 | 99久久精品国产一区二区蜜芽 | 熟女俱乐部五十路六十路av | 国产在线一区二区三区四区五区 | 亚洲成a人片在线观看无码 | 草草网站影院白丝内射 | 精品国偷自产在线视频 | 亚洲国产精品无码一区二区三区 | 国产精品.xx视频.xxtv | 国产无遮挡又黄又爽免费视频 | 亚洲欧美国产精品专区久久 | 狠狠色欧美亚洲狠狠色www | 午夜不卡av免费 一本久久a久久精品vr综合 | 狠狠噜狠狠狠狠丁香五月 | 好男人社区资源 | 国产人妻精品一区二区三区 | 少妇久久久久久人妻无码 | 国产精品爱久久久久久久 | 亚洲人成人无码网www国产 | 无码人妻精品一区二区三区不卡 | 亚洲aⅴ无码成人网站国产app | 日韩人妻无码中文字幕视频 | 人人妻人人藻人人爽欧美一区 | 色 综合 欧美 亚洲 国产 | 国产精品无码mv在线观看 | 丝袜美腿亚洲一区二区 | 麻豆国产人妻欲求不满 | 国产av无码专区亚洲a∨毛片 | 无遮挡啪啪摇乳动态图 | 色窝窝无码一区二区三区色欲 | 亚洲小说图区综合在线 | 亚洲精品一区二区三区婷婷月 | 成人欧美一区二区三区 | 无码av中文字幕免费放 | 麻豆国产97在线 | 欧洲 | 人人妻人人澡人人爽欧美精品 | 久久久久se色偷偷亚洲精品av | 国产精品igao视频网 | 久久久亚洲欧洲日产国码αv | 国产亚洲精品久久久久久大师 | 国产av人人夜夜澡人人爽麻豆 | 内射后入在线观看一区 | 亚洲欧洲中文日韩av乱码 | 亚洲一区二区三区香蕉 | 永久免费观看国产裸体美女 | 国产精品亚洲专区无码不卡 | 免费无码的av片在线观看 | 高中生自慰www网站 | 久久久国产精品无码免费专区 | 欧美激情一区二区三区成人 | 草草网站影院白丝内射 | 精品人妻人人做人人爽夜夜爽 | 国产精品久久久久7777 | yw尤物av无码国产在线观看 | 无套内谢老熟女 | 亚洲欧美日韩综合久久久 | 97人妻精品一区二区三区 | 在线а√天堂中文官网 | 免费人成在线视频无码 | 久久精品人人做人人综合试看 | 中文字幕乱妇无码av在线 | 丰满岳乱妇在线观看中字无码 | 欧美人与动性行为视频 | 综合激情五月综合激情五月激情1 | 亚无码乱人伦一区二区 | 精品乱子伦一区二区三区 | 六十路熟妇乱子伦 | 欧美三级a做爰在线观看 | 色综合久久88色综合天天 | 亚洲精品成人福利网站 | 久久天天躁夜夜躁狠狠 | 蜜桃无码一区二区三区 | 麻豆国产97在线 | 欧洲 | 黑人粗大猛烈进出高潮视频 | 国产舌乚八伦偷品w中 | 国产成人久久精品流白浆 | 亚洲综合在线一区二区三区 | 婷婷综合久久中文字幕蜜桃三电影 | 久久久精品国产sm最大网站 | 日本又色又爽又黄的a片18禁 | 强开小婷嫩苞又嫩又紧视频 | 狠狠色丁香久久婷婷综合五月 | 亚洲人成网站色7799 | 亚洲狠狠婷婷综合久久 | 国产熟妇另类久久久久 | 无码人妻丰满熟妇区毛片18 | 国产乱人伦av在线无码 | 精品一二三区久久aaa片 | 性欧美大战久久久久久久 | 久久久久久久久888 | 一本色道婷婷久久欧美 | 精品国产精品久久一区免费式 | 最新版天堂资源中文官网 | 久久综合九色综合97网 | 青草视频在线播放 | 亚洲国产精品成人久久蜜臀 | 成人女人看片免费视频放人 | 国产免费无码一区二区视频 | 亚洲中文字幕在线无码一区二区 | 亚洲综合色区中文字幕 | 精品久久久久香蕉网 | 久久zyz资源站无码中文动漫 | 久久人妻内射无码一区三区 | 国语自产偷拍精品视频偷 | 国产香蕉尹人综合在线观看 | 国产人妖乱国产精品人妖 | 四虎国产精品免费久久 | 麻豆国产97在线 | 欧洲 | 女人色极品影院 | 国产亚洲精品久久久久久 | 亚洲熟妇自偷自拍另类 | 一本色道久久综合亚洲精品不卡 | 麻豆md0077饥渴少妇 | 欧美日韩视频无码一区二区三 | 日日橹狠狠爱欧美视频 | 女人被爽到呻吟gif动态图视看 | 欧美熟妇另类久久久久久多毛 | 国产熟女一区二区三区四区五区 | 影音先锋中文字幕无码 | 大肉大捧一进一出视频出来呀 | 成人无码精品1区2区3区免费看 | 日本va欧美va欧美va精品 | 麻豆蜜桃av蜜臀av色欲av | 久久国产精品精品国产色婷婷 | 漂亮人妻洗澡被公强 日日躁 | 初尝人妻少妇中文字幕 | 国产区女主播在线观看 | 色诱久久久久综合网ywww | 亚洲综合伊人久久大杳蕉 | 久久zyz资源站无码中文动漫 | 久久人人97超碰a片精品 | 蜜臀av在线观看 在线欧美精品一区二区三区 | 亚洲国产精品一区二区美利坚 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 中文无码成人免费视频在线观看 | 国产麻豆精品一区二区三区v视界 | 国产精品美女久久久 | 欧美精品免费观看二区 | 人妻少妇被猛烈进入中文字幕 | 国内精品人妻无码久久久影院 | 国产农村乱对白刺激视频 | 国产在线一区二区三区四区五区 | 国产深夜福利视频在线 | 亚洲熟妇色xxxxx亚洲 | 亚洲欧美色中文字幕在线 | 精品aⅴ一区二区三区 | 呦交小u女精品视频 | 亚洲一区二区三区四区 | 久精品国产欧美亚洲色aⅴ大片 | 麻豆果冻传媒2021精品传媒一区下载 | 亚洲精品国产精品乱码视色 | 日日麻批免费40分钟无码 | 亚洲精品国产精品乱码视色 | 国产xxx69麻豆国语对白 | 麻豆国产人妻欲求不满谁演的 | 无码福利日韩神码福利片 | 亚洲精品无码人妻无码 | 国产莉萝无码av在线播放 | 亚洲精品无码国产 | 亚洲精品一区二区三区大桥未久 | 300部国产真实乱 | 99久久久国产精品无码免费 | 丰满护士巨好爽好大乳 | 无码国模国产在线观看 | 亚洲成色www久久网站 | 天天拍夜夜添久久精品 | 亚洲一区二区观看播放 | 国产乱人偷精品人妻a片 | 欧美老妇交乱视频在线观看 | 亚洲а∨天堂久久精品2021 | 日韩人妻无码一区二区三区久久99 | 亚洲日韩av一区二区三区四区 | 亚洲一区av无码专区在线观看 | 成人三级无码视频在线观看 | 亚洲精品国产精品乱码不卡 | 亚洲精品国产第一综合99久久 | 国产精品无码成人午夜电影 | 亚洲成av人片天堂网无码】 | 麻豆国产人妻欲求不满谁演的 | 成在人线av无码免费 | 亚洲熟女一区二区三区 | 成人一在线视频日韩国产 | 成人三级无码视频在线观看 | 欧美成人高清在线播放 | 西西人体www44rt大胆高清 | 成人三级无码视频在线观看 | 伊人色综合久久天天小片 | 久久天天躁夜夜躁狠狠 | 精品久久久无码人妻字幂 | 日日橹狠狠爱欧美视频 | 免费国产成人高清在线观看网站 | 内射欧美老妇wbb | 九九久久精品国产免费看小说 | 日韩精品无码免费一区二区三区 | 国产97色在线 | 免 | 久久成人a毛片免费观看网站 | 国产麻豆精品精东影业av网站 | 免费看少妇作爱视频 | 亚洲国产一区二区三区在线观看 | 国产人妻精品午夜福利免费 | 国产精品理论片在线观看 | 久久精品99久久香蕉国产色戒 | 日韩欧美成人免费观看 | 久久综合香蕉国产蜜臀av | 97夜夜澡人人双人人人喊 | 成人aaa片一区国产精品 | 国产猛烈高潮尖叫视频免费 | 无码午夜成人1000部免费视频 | 日韩无套无码精品 | 男女超爽视频免费播放 | 亚洲男女内射在线播放 | 国产乡下妇女做爰 | 99久久99久久免费精品蜜桃 | 中文无码精品a∨在线观看不卡 | 国产成人综合在线女婷五月99播放 | 欧美亚洲国产一区二区三区 | 丁香花在线影院观看在线播放 | 日韩人妻无码中文字幕视频 | 99国产精品白浆在线观看免费 | 国产女主播喷水视频在线观看 | 国内精品人妻无码久久久影院 | 久久久久久久女国产乱让韩 | 国产精品99久久精品爆乳 | 成人欧美一区二区三区 | a国产一区二区免费入口 | 久久综合激激的五月天 | 久久伊人色av天堂九九小黄鸭 | 青春草在线视频免费观看 | 高潮毛片无遮挡高清免费视频 | 妺妺窝人体色www在线小说 | 久久久精品成人免费观看 | 国产精品国产自线拍免费软件 | 国产午夜视频在线观看 | 人妻无码久久精品人妻 | 内射后入在线观看一区 | 2020最新国产自产精品 | 大乳丰满人妻中文字幕日本 | 九九综合va免费看 | 久久精品国产99精品亚洲 | 中文精品无码中文字幕无码专区 | 亚洲精品国产精品乱码不卡 | 少妇的肉体aa片免费 | 亚洲熟悉妇女xxx妇女av | 亚洲精品久久久久久一区二区 | 亚洲精品国偷拍自产在线麻豆 | 精品人人妻人人澡人人爽人人 | 人妻体内射精一区二区三四 | 亚洲精品无码国产 | 国产精品久久久久久久9999 | 秋霞成人午夜鲁丝一区二区三区 | 亚洲成在人网站无码天堂 | 激情五月综合色婷婷一区二区 | 伊人久久大香线焦av综合影院 | 国产av无码专区亚洲awww | 国内精品人妻无码久久久影院蜜桃 | 黑森林福利视频导航 | 成人片黄网站色大片免费观看 | 亚洲无人区午夜福利码高清完整版 | 粗大的内捧猛烈进出视频 | 成人精品天堂一区二区三区 | 久久久久亚洲精品中文字幕 | 丰满诱人的人妻3 | 国产成人亚洲综合无码 | 国产精品亚洲а∨无码播放麻豆 | 国产无遮挡吃胸膜奶免费看 | 乌克兰少妇性做爰 | 狠狠cao日日穞夜夜穞av | 麻豆md0077饥渴少妇 | 精品一区二区三区波多野结衣 | 正在播放老肥熟妇露脸 | 东京热男人av天堂 | 久久精品国产99精品亚洲 | 无码人妻精品一区二区三区不卡 | 成人精品一区二区三区中文字幕 | 国产无遮挡又黄又爽又色 | 精品国产aⅴ无码一区二区 | 少妇被黑人到高潮喷出白浆 | 久久综合久久自在自线精品自 | 伊人久久婷婷五月综合97色 | 久久国产自偷自偷免费一区调 | 久在线观看福利视频 | 国产又爽又黄又刺激的视频 | 玩弄人妻少妇500系列视频 | 精品欧洲av无码一区二区三区 | 午夜精品一区二区三区在线观看 | 精品日本一区二区三区在线观看 | 亚洲精品国产精品乱码不卡 | 一本色道久久综合狠狠躁 | 在线播放免费人成毛片乱码 | 国产色视频一区二区三区 | 亚洲日本va午夜在线电影 | 国产两女互慰高潮视频在线观看 | 亚洲精品国产a久久久久久 | 亚洲aⅴ无码成人网站国产app | 丰满人妻一区二区三区免费视频 | 桃花色综合影院 | 久久99精品国产麻豆 | 国产精品人人妻人人爽 | 国产激情综合五月久久 | 丰满少妇弄高潮了www | 国产精品99爱免费视频 | 国产偷抇久久精品a片69 | 真人与拘做受免费视频一 | 久久精品人妻少妇一区二区三区 | 精品成人av一区二区三区 | 国产无av码在线观看 | 亚洲午夜久久久影院 | 久久综合激激的五月天 | 亚洲精品一区二区三区在线观看 | 蜜臀aⅴ国产精品久久久国产老师 | 欧洲熟妇色 欧美 | 在线观看免费人成视频 | 天海翼激烈高潮到腰振不止 | 啦啦啦www在线观看免费视频 | 久久无码中文字幕免费影院蜜桃 | 少妇激情av一区二区 | 激情内射亚州一区二区三区爱妻 | 天天燥日日燥 | 乱人伦人妻中文字幕无码 | 久久久久久九九精品久 | 国产三级精品三级男人的天堂 | 国产午夜福利100集发布 | 亚洲aⅴ无码成人网站国产app | 天天综合网天天综合色 | 大肉大捧一进一出好爽视频 | 免费观看黄网站 | 国产在线无码精品电影网 | 中文字幕乱码人妻无码久久 | 亚洲精品午夜国产va久久成人 | 中文无码精品a∨在线观看不卡 | 麻花豆传媒剧国产免费mv在线 | 久久国产精品精品国产色婷婷 | 国产精品高潮呻吟av久久4虎 | 日韩精品无码一本二本三本色 | 美女扒开屁股让男人桶 | 99视频精品全部免费免费观看 | 久久99精品久久久久久 | 97se亚洲精品一区 | 亚洲精品午夜无码电影网 | 人妻互换免费中文字幕 | 成人免费无码大片a毛片 | 久久久久亚洲精品中文字幕 | 内射巨臀欧美在线视频 | av无码久久久久不卡免费网站 | 无码国内精品人妻少妇 | 成熟妇人a片免费看网站 | 熟妇人妻激情偷爽文 | 人人妻人人藻人人爽欧美一区 | 中文字幕中文有码在线 | 欧美性猛交内射兽交老熟妇 | 久久婷婷五月综合色国产香蕉 | 97se亚洲精品一区 | 欧美丰满老熟妇xxxxx性 | 野外少妇愉情中文字幕 | ass日本丰满熟妇pics | 国内少妇偷人精品视频免费 | 18无码粉嫩小泬无套在线观看 | 男人的天堂av网站 | 大胆欧美熟妇xx | 国产亚洲视频中文字幕97精品 | 中文字幕av无码一区二区三区电影 | 伦伦影院午夜理论片 | 中国女人内谢69xxxx | 老太婆性杂交欧美肥老太 |