• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            陳碩的Blog

            學(xué)之者生,用之者死——ACE歷史與簡(jiǎn)評(píng)

            學(xué)之者生,用之者死——ACE歷史與簡(jiǎn)評(píng)

            陳碩 (giantchen_AT_gmail)

            Blog.csdn.net/Solstice

            2010 March 10

            ACE 是現(xiàn)代面向?qū)ο缶W(wǎng)絡(luò)編程的鼻祖,確立了許多重要模式,如 Reactor、Acceptor 等,重要到我們甚至覺(jué)得網(wǎng)絡(luò)編程就應(yīng)該是那樣的。但為什么 ACE 叫好不叫座?大名鼎鼎卻使用者寥寥?本文談?wù)勎业膫€(gè)人觀點(diǎn)。

            ACE 是一套重量級(jí)的 C++ 網(wǎng)絡(luò)庫(kù),早期版本由 Douglas Schmidt 獨(dú)自開發(fā),后來(lái)有 40 余名學(xué)生與工作人員也貢獻(xiàn)了大量代碼。作者 Douglas Schmidt 憑借它發(fā)表了 30 余篇學(xué)術(shù)論文。ACE 的一大特點(diǎn)是融合了 Douglas Schmidt 提出的很多面向?qū)ο?a >網(wǎng)絡(luò)編程的設(shè)計(jì)模式,并且具有不可思議的跨平臺(tái)能力

            1 ACE 歷史

            先說(shuō)說(shuō) ACE 之父 Douglas Schmidt 的個(gè)人經(jīng)歷

            我相信 ACE 是 Douglas 在讀博期間的主要工作,ACE 這個(gè)名字最早出現(xiàn)在 1993 年 12 月的一篇會(huì)議論文上,Douglas 的這篇文章獲得了“最佳學(xué)生論文”獎(jiǎng)。在此之前,Douglas 已經(jīng)用 ASX 等其他名字發(fā)表了內(nèi)容相近的文章。

            我能下載到的最早的 ACE 版本是 4.0.32,有大約 86,000 行 C++ 代碼,代碼的時(shí)間戳是 1998 年 10 月 22 日。早期 ACE 由 Douglas Schmidt 個(gè)人獨(dú)立開發(fā),從 ChangeLog 得知,1993 年 11 月 ACE 的版本號(hào)是 2.12。到了 1995 年 9 月,才有第一次出現(xiàn)其他開發(fā)者。在 1993~1996 年間的 684 次改動(dòng)中,Douglas 一個(gè)人貢獻(xiàn)了 529 次,另外幾個(gè)主要開發(fā)者以及他們的修改次數(shù)分別是 Prashant Jain (58)、Tim Harrison (42)、David Levine (28)、Irfan Pyarali (20)、Jesper S. M|ller (5)。

            從整個(gè) ChangeLog 看,從 1993 年到 2010 年 3 月有 19,000 余次改動(dòng)。有超過(guò) 200 人修改過(guò)代碼,其中 23 個(gè)人的 check-in 次數(shù)大于 100,排名前 12 的代碼修改者為:

               3635  Johnny Willemsen (活躍年份:2001~今)

               2586  Douglas C. Schmidt(原作者,活躍年份:1993~今)

               1861  Steve Huston (活躍年份:1997~今)

               1197  David L. Levine  (活躍年份:1996~2000)

                962  Nanbor Wang  (活躍年份:1998~2003)

                907  Ossama Othman (活躍年份:1999~2005)

                865  Chad Elliott (活躍年份:2000~今)

                823  Bala Natarajan (活躍年份:1999~2004)

                708  Carlos O'Ryan (活躍年份:1997~2001)

                544  J.T. Conklin (活躍年份:2004~2008)

                479  Irfan Pyarali (活躍年份:1996~2003)

                368  Darrell Brunsch (活躍年份:1997~2001)

            看到這些“活躍年份”,你的第一反應(yīng)是什么?我想到的是,這些人會(huì)不會(huì)多半是 Douglas 指導(dǎo)的研究生?我猜他們?cè)谧x研期間參與改進(jìn) ACE,把工作內(nèi)容寫成論文發(fā)表,然后畢業(yè)走人。或許這能解釋 ACE 代碼風(fēng)格的多樣性。

            在瀏覽代碼歷史的過(guò)程中,我還發(fā)現(xiàn)一個(gè)很有意思的現(xiàn)象,在 2008 年 3 月 4 日,某人不小心把整個(gè) ACE 的源代碼樹刪除了:

            https://svn.dre.vanderbilt.edu/viewvc/Middleware?view=revision&revision=80824

            隨后又很快恢復(fù):

            https://svn.dre.vanderbilt.edu/viewvc/Middleware?view=revision&revision=80826

            干這件事情的老兄在 2005~2009 這幾年里一共 check in 了 120 余次。你對(duì)這件事情怎么看?你們的開發(fā)團(tuán)隊(duì)里有這樣的人嗎?

            2 事實(shí)與思考

            1. 除了 Douglas Schmidt 和 Stephen Huston 寫的三本書籍之外,沒(méi)有其他專著講 ACE。

            究竟是 ACE 太好用了,以至于無(wú)需其他書來(lái)講解,還是太難用了,講也講不明白?抑或根本就沒(méi)人在乎?

            C++ 網(wǎng)絡(luò)編程 第1卷》《C++ 網(wǎng)絡(luò)編程 第2卷》《ACE 程序員指南》這三本書先后于 2001、2002、2003 年出版,之后再無(wú)更新。在同一時(shí)期,同樣在網(wǎng)絡(luò)編程領(lǐng)域,盡管 W. Richard Stevens 在 1999 年去世,他的 UNP 和 APUE 仍然由別人續(xù)寫了新版。講 C 語(yǔ)言 Sockets API 的書尚且不斷更新,上層封裝的 C++ 居然無(wú)動(dòng)于衷?真的是封裝到位了,屏蔽了這些變化?

            UNP 的可操作性很強(qiáng),讀前面幾章,就能上手編寫簡(jiǎn)單的網(wǎng)絡(luò)程序,看完大半本書,網(wǎng)絡(luò)編程基本就算入門了,能編寫一般應(yīng)用的網(wǎng)絡(luò)程序。相反,讀完 ACE 那幾本書,對(duì)于簡(jiǎn)單的網(wǎng)絡(luò)編程任務(wù)還是感覺(jué)無(wú)從下手,這是因?yàn)闀鴮懙貌缓茫€是 ACE 本身不好用?

            2. ACE 很難用,非常容易用錯(cuò)

            我不止聽到一個(gè)人對(duì)我說(shuō),他們?cè)陧?xiàng)目里嘗試過(guò) ACE,不是中途放棄,因?yàn)槌隽藛?wèn)題無(wú)法解決;就是勉強(qiáng)交差,并且從下一個(gè)項(xiàng)目起堅(jiān)決不用。我聽到的另一個(gè)說(shuō)法是,ACE 教程的例子必須原封不動(dòng)地抄下來(lái),改一點(diǎn)點(diǎn)就會(huì)出漏子。不巧的是,ACE 的例子舉來(lái)舉去就是個(gè) Logging 服務(wù)器,讓人想照貓畫虎也無(wú)從下手。在最近的《代碼之美》一書中,Douglas Schmidt 再次拿它為例,說(shuō)明他真的很喜歡這個(gè)例子。

            用 ACE 編程如履薄冰,生怕在陰溝里翻船,不知道它背后玩了什么把戲。相反,用 10 來(lái)個(gè) Sockets 系統(tǒng)調(diào)用就能搞定網(wǎng)絡(luò)編程,我感覺(jué)比使用 ACE 難度要小。為什么“高級(jí)”工具反而沒(méi)有低級(jí)工具順手呢?

            不好用的直接后果是少有人用,放眼望去,目前涉及網(wǎng)絡(luò)的 C++ 開源項(xiàng)目里邊,鮮有用 ACE 作為通信平臺(tái)的(我知道的只有 Mangos)。相反,libevent 這個(gè)輕量級(jí)的 IO multiplexing 庫(kù)有 memcached 這樣的著名用戶。

            3. ACE 代碼質(zhì)量不高,更像是一個(gè)研究項(xiàng)目,而不是工業(yè)界的產(chǎn)品

            讀 ACE 現(xiàn)在的代碼,一股學(xué)生氣撲面而來(lái),感覺(jué)像在讀實(shí)習(xí)生寫的代碼。拋開編碼風(fēng)格不談,這里舉三個(gè)“硬傷”:

            • sleep < 2ms

            在某些早期的 Linux 內(nèi)核上,如果 select/poll 的等待時(shí)間小于 2ms,內(nèi)核會(huì)采用 busy-waiting。這是極大的 CPU 資源浪費(fèi),而 ACE 似乎沒(méi)有考慮避免這一點(diǎn)。

            • Linux TCP self-connection

            Linux 的 TCP 實(shí)現(xiàn)有一個(gè)特殊“行為”,在某些特殊情況下會(huì)發(fā)起自連接。而 Linux 網(wǎng)絡(luò)協(xié)議棧的維護(hù)者認(rèn)為這是一個(gè) feature,不是 bug,拒絕修復(fù)。通常網(wǎng)絡(luò)應(yīng)用程序不希望出現(xiàn)這種情況,我見過(guò)的好的網(wǎng)絡(luò)庫(kù)會(huì)有意識(shí)地檢查并斷開這種連接,然而 ACE 漠然視之。

            • timeval on 64-bit

            ACE_Time_Value 類直接以 struct timeval 為成員變量,保存從 Epoch 開始的微秒數(shù)。這在 32-bit 下沒(méi)問(wèn)題,對(duì)象大小是 8 字節(jié)。到了 LP64 模式的 64-bit 平臺(tái),比如 Linux,對(duì)象大小變?yōu)?16 字節(jié),這么做就不夠好了。我們可以直接用 int64_t 來(lái)保存這個(gè)以微秒為單位的時(shí)間,64-bit 整數(shù)能存下上下 30 萬(wàn)年,足夠用了。減小對(duì)象大小并不是為了節(jié)約幾個(gè)字節(jié)的內(nèi)存,而是方便函數(shù)參數(shù)傳遞。在 x86-64 上,這種 8 字節(jié)的結(jié)構(gòu)體可以用 64-bit 寄存器直接傳參,也就是說(shuō) pass by value 會(huì)比 pass by reference 更快。對(duì)于一般的應(yīng)用程序而言,要不要這么做值得商榷。對(duì)于底層的 C++ 網(wǎng)絡(luò)庫(kù),不加區(qū)分地使用 pass by reference 會(huì)讓人懷疑作者知其然不知其所以然。

            對(duì)于以上幾點(diǎn)情況,我懷疑 ACE 根本沒(méi)用在 Linux 大規(guī)模生產(chǎn)環(huán)境下使用過(guò),我只能期望它在別的平臺(tái)表現(xiàn)好一些了。ACE 的作者們似乎更注重驗(yàn)證新想法,然后發(fā)論文,而不是把它放到工業(yè)環(huán)境中反復(fù)錘煉,打造為靠得住的產(chǎn)品。(類似 Minix 與 Linux 的關(guān)系。)

            4. 移植性很好,支持我知道的和不知道的很多平臺(tái)

            ACE 的意義在于讓我們明白了C++代碼可以做到可移植,并展示了這么做會(huì)付出多么巨大的代價(jià)。不細(xì)說(shuō)了,讀過(guò) ACE 代碼的人都明白。

            從代碼質(zhì)量上看,ACE 做到了能在這些平臺(tái)上運(yùn)行,但似乎沒(méi)有在哪個(gè)平臺(tái)占據(jù)主導(dǎo)地位。有沒(méi)有哪個(gè)平臺(tái)的網(wǎng)絡(luò)編程首選 ACE?

            出現(xiàn)這一狀況的原因是,跨平臺(tái)和高性能是矛盾的。跨平臺(tái)意味著要抽象出多個(gè)平臺(tái)的共性,以最 general 的方式編寫上層代碼。而高性能則要求充分發(fā)揮平臺(tái)的特性,劍走偏鋒,用盡平臺(tái)能提供的一切加速手段,哪怕與其他平臺(tái)不兼容。網(wǎng)絡(luò)編程對(duì)此尤為敏感。

            我不知道 ACE 的性能如何,因?yàn)樵诟黜?xiàng)性能評(píng)測(cè)榜上基本看不到它的名字(c10k 里就沒(méi)有 ACE 的身影)。另外,Buffer class 的好壞直接反應(yīng)了網(wǎng)絡(luò)庫(kù)對(duì)性能的追求,ACE 提供了比 std::deque<uint8_t> 更好的輸入輸出 Buffer 嗎?(我不是說(shuō) deque 有多好,它基本是 fail-safe 的選擇而已。)

            5. ACE 過(guò)于復(fù)雜,甚至比它試圖封裝的對(duì)象更復(fù)雜。

            (這里的代碼行數(shù)均為 wc 命令的粗略估計(jì)。)

            ACE 5.7 自身(不含 TAO 和 CIAO)有 30 萬(wàn)行 C++ 代碼(Douglas 自己給出的數(shù)據(jù)是 25 萬(wàn)行,可能指的是略早的版本),這是一個(gè)什么概念呢?我們來(lái)看 TCP/IP 協(xié)議棧本身的實(shí)現(xiàn)有多少行:(均不含 IPv6)

            • TCPv2 列出的 BSD4.4-Lite 完整 TCP/IP 協(xié)議棧代碼有 15,000 行,其中 4,500 行 TCP 協(xié)議,800 行 UDP 協(xié)議,2,500 行 IP 協(xié)議  
            • Linux 1.2.13 完整的 TCP/IP 協(xié)議棧有 2 萬(wàn)多行 (net/inet)  
            • Linux 2.6.32.9 的 TCP/IP 協(xié)議棧有 6 萬(wàn)多行 (net/ipv4)  
            • FreeBSD 8.0 的 TCP/IP 協(xié)議棧有 5 萬(wàn)多行 (sys/netinet, 不含 sctp)

            換句話說(shuō),ACE 用 30 萬(wàn)行 C++ 代碼“封裝”了不到 10 萬(wàn)行 C 代碼(且不論 C++ 代碼的信息密度比 C 大),這是不是頭重腳輕呢?我理解的“封裝”是把復(fù)雜的東西變簡(jiǎn)單,但 ACE 好像走向了另一個(gè)方向,把不那么復(fù)雜的東西變復(fù)雜了。

            這個(gè)對(duì)比數(shù)字可能不太準(zhǔn)確,因?yàn)?ACE 還封裝了很多其他東西,請(qǐng)看。http://www.dre.vanderbilt.edu/Doxygen/5.7.7/html/ace/inherits.htmlhttp://www.dre.vanderbilt.edu/Doxygen/5.7.7/html/ace/hierarchy.html

            以下兩張類的繼承關(guān)系圖片請(qǐng)?jiān)谛麓翱诖蜷_:

            http://www.dre.vanderbilt.edu/Doxygen/5.7.7/html/ace/a06178.png

            http://www.dre.vanderbilt.edu/Doxygen/5.7.7/html/ace/a06347.png

            Douglas 說(shuō) ACE 包含了 40 人年的工作量,對(duì)此我毫不懷疑。但是,網(wǎng)絡(luò)編程真的需要這么復(fù)雜嗎?TCP/IP 協(xié)議棧的實(shí)現(xiàn)也沒(méi)這么多工作量嘛。或許只有 CORBA 這樣的應(yīng)用才會(huì)用到這么復(fù)雜的東西?那么為什么 ICE 在重新實(shí)現(xiàn) CORBA 的時(shí)候沒(méi)有基于 ACE 呢?是不是因?yàn)?ACE 架子拉得大,底子并不牢?

            3 ACE 的意義

            ACE 對(duì)于面向?qū)ο蟆⒃O(shè)計(jì)模式和網(wǎng)絡(luò)編程具有重大歷史和現(xiàn)實(shí)意義。

            ACE 誕生之時(shí),正是 90 年代初期面向?qū)ο蠹夹g(shù)的高速發(fā)展期,ACE 一定程度上是作為面向?qū)ο蠹夹g(shù)的成功案例來(lái)宣傳的。

            在 1994 年前后,Unix 分為兩個(gè)陣營(yíng),AT&T 的 SVR4 與 BSD 的 BSD4.x,這兩家的 IO multiplexing 不完全兼容。比如 SVR4 提供 poll 調(diào)用,而 BSD 提供 select 調(diào)用。ACE 當(dāng)時(shí)的宣傳點(diǎn)之一是用面向?qū)ο蠹夹g(shù)屏蔽了兩個(gè)平臺(tái)的差異,提供了統(tǒng)一的 Reactor 接口。

            【接下來(lái),poll 在 1996 年 9 月 7 號(hào)加入 NetBSD,并隨 NetBSD 1.3 于 1998 年 1 月 4 號(hào)發(fā)布。隨后 FreeBSD 3.0 也支持 poll,1998 年 10 月發(fā)布。Linux 很早就支持 select,從 2.1.23 內(nèi)核起支持 poll,發(fā)布日期為 1997 年 1 月 26 號(hào)。也就是說(shuō),到了 1998 年,平臺(tái)差異被暫時(shí)抹平了。隨后 epoll、/dev/poll、kqueue 以性能為名,再次擴(kuò)大了平臺(tái)差異。當(dāng)然,Windows 至今不支持 poll。】

            ACE 的設(shè)計(jì)似乎過(guò)于強(qiáng)調(diào)面向?qū)ο蟮撵`活性,一些不該使用虛函數(shù)的地方也提供了定制點(diǎn),比如 ACE_Timer_Queue 就應(yīng)是個(gè)具體類,而不是允許用戶 override schedule/cancel/expire 之類的操作。面向?qū)ο笾校?#8220;繼承”的目的是為了被復(fù)用,而不是去復(fù)用基類的代碼。

            查其文獻(xiàn),Reactor 在 1993 年登上《C++ Report》雜志的時(shí)候,文章標(biāo)題還比較樸素,掛著“面向?qū)ο?#8221;的旗號(hào):

            轉(zhuǎn)眼到了 1994 年,也就是《設(shè)計(jì)模式》成書的那一年,Douglas 開始寫文章言必稱 pattern:

            似乎 "pattern" 這個(gè)字樣成了發(fā)文章的通行證,這股風(fēng)氣直到 2000 左右才剎住。之后這些論文集結(jié)出版,以《Pattern-Oriented Software Architecture》為名出了好幾本書,ACE 的內(nèi)容主要集中在第二卷。(請(qǐng)留意,原來(lái)的提法是 Object-Oriented,現(xiàn)在變成了 Pattern-Oriented,似乎軟件開發(fā)就應(yīng)該像糖果廠生產(chǎn)綠豆糕,用模子一個(gè)個(gè)印出來(lái)完事。)

            ACE 就像一個(gè) pattern 大觀園,保守估計(jì)有 10 來(lái)種 patterns 藏身其中,形成了一套模式語(yǔ)言(《Applying a Pattern Language to Develop Application-level Gateways》),這還不包括 GoF 定義的一般意義下的 OO pattern。

            通過(guò) ACE 來(lái)學(xué)習(xí)網(wǎng)絡(luò)編程,那是本末倒置,因?yàn)樗滩涣四闳魏?UNP 以外的知識(shí)。(Windows 網(wǎng)絡(luò)編程?)

            然而,如果要用面向?qū)ο蟮姆绞絹?lái)搞網(wǎng)絡(luò)編程,那么 ACE 的思想(而不是代碼)是值得效仿的,畢竟它飽含了 Douglas Schmidt 等學(xué)者的心血與智慧。學(xué)得好的例子有 Apache Mina、JBoss Netty、Python Twisted、Perl POE 等等。

            這就是我說(shuō)“學(xué)之者生,用之者死”的含義。

            4 ACE 文獻(xiàn)導(dǎo)讀

            Douglas Schmidt 寫了很多 ACE 的文章,其中不乏內(nèi)容相近的作品。讀他的文章,首選發(fā)表在技術(shù)雜志上的文章(比如 C++ Report),而不是發(fā)表在學(xué)術(shù)期刊或會(huì)議上的論文。前者的寫作目的是教會(huì)讀者技術(shù),后者則往往是展示作者的新思路新想法,技術(shù)文章比學(xué)術(shù)論文要好讀得多。

            由于當(dāng)時(shí)面向?qū)ο蠹夹g(shù)尚在發(fā)展,Douglas 文章里的圖形很有特色,不是現(xiàn)在規(guī)范的 UML 圖(那會(huì)兒 UML 還沒(méi)定型呢),而是像變形蟲一樣的類圖(經(jīng) pinxue 指出,這種圖是 Grady Booch 發(fā)明的),放在一堆文獻(xiàn)里也很容易認(rèn)出來(lái)。

            如果要用 ACE 的代碼來(lái)驗(yàn)證文章的思路,我建議閱讀和文章同時(shí)期的 4.0 版本代碼,代碼風(fēng)格比較統(tǒng)一,代碼量也不大,便于理解。

            下面介紹幾篇有代表性的論文。

            以上兩篇文章實(shí)際上內(nèi)容基本相同,都是對(duì) ACE 的概要介紹,看第二篇即可,第一次沒(méi)看懂也沒(méi)關(guān)系。

            剩下要看的是一篇 Socket OO 封裝、四篇 Reactor、三篇 Acceptor-Connector、一篇 Proactor。這些文章前面大多都給了鏈接,其余的這里補(bǔ)充一下:

            不想看這 10 篇論文的話,讀中譯本《C++ 網(wǎng)絡(luò)編程 第1卷》《C++ 網(wǎng)絡(luò)編程 第2卷》《ACE 程序員指南》也行,翻譯質(zhì)量都不錯(cuò)。

            5 設(shè)想中的 C++ 網(wǎng)絡(luò)庫(kù)

            與文章主旨無(wú)關(guān),略。

            我覺(jué)得網(wǎng)絡(luò)庫(kù)要解決現(xiàn)實(shí)的問(wèn)題,滿足現(xiàn)實(shí)的需要,而不是把 features/patterns 堆在那里等別人來(lái)用。應(yīng)該先有應(yīng)用,再提煉出庫(kù)。而不是先造庫(kù),然后尋求應(yīng)用。

            posted on 2010-03-11 20:34 陳碩 閱讀(6647) 評(píng)論(4)  編輯 收藏 引用

            評(píng)論

            # re: 學(xué)之者生,用之者死——ACE歷史與簡(jiǎn)評(píng) 2010-03-11 21:29 空明流轉(zhuǎn)

            寫的相當(dāng)好。  回復(fù)  更多評(píng)論   

            # re: 學(xué)之者生,用之者死——ACE歷史與簡(jiǎn)評(píng) 2010-03-12 16:37 hdqqq

            用協(xié)議棧代碼和ace代碼對(duì)比欠妥,基礎(chǔ)層要提供的接口和要實(shí)現(xiàn)的功能相對(duì)固定,而在應(yīng)用層上,要復(fù)雜很多。  回復(fù)  更多評(píng)論   

            # re: 學(xué)之者生,用之者死——ACE歷史與簡(jiǎn)評(píng) 2010-03-12 16:44 chentan

            "應(yīng)該先有應(yīng)用,再提煉出庫(kù)。而不是先造庫(kù),然后尋求應(yīng)用。"


            這句話非常好,也是我一直的信條


              回復(fù)  更多評(píng)論   

            # re: 學(xué)之者生,用之者死——ACE歷史與簡(jiǎn)評(píng) 2010-03-12 19:36 陳昱(CY)

            "應(yīng)該先有應(yīng)用,再提煉出庫(kù)。而不是先造庫(kù),然后尋求應(yīng)用。"

            應(yīng)該先有游戲,再提煉出引擎,而不是先造引擎,然后尋求游戲

            看來(lái)我找到失敗的原因了  回復(fù)  更多評(píng)論   


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            隨筆分類

            隨筆檔案

            相冊(cè)

            搜索

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            99久久婷婷国产一区二区| 国产A三级久久精品| 亚洲精品无码成人片久久| 亚洲国产天堂久久久久久| 久久影院久久香蕉国产线看观看| 久久精品国产99国产电影网 | 久久久久99精品成人片| 久久精品国产亚洲沈樵| 成人免费网站久久久| 久久精品国产免费| 狠狠色丁香婷婷综合久久来来去| 久久久久国产一区二区| 欧美亚洲国产精品久久| 色婷婷综合久久久久中文 | 日韩av无码久久精品免费| 久久久女人与动物群交毛片| 国产精品久久久久久福利漫画| 久久不射电影网| 久久精品综合网| 精品精品国产自在久久高清| 久久人人爽人人爽人人片AV麻豆 | 色婷婷综合久久久久中文字幕| 日韩精品久久久久久久电影| 午夜精品久久久久久久| 久久青青草原综合伊人| 香蕉aa三级久久毛片| 国产V综合V亚洲欧美久久| 久久国产精品偷99| 亚洲中文字幕久久精品无码APP| 99久久超碰中文字幕伊人| 欧美久久久久久午夜精品| 久久er99热精品一区二区| 久久久久久无码国产精品中文字幕| AV无码久久久久不卡蜜桃| 大美女久久久久久j久久| 一本一本久久A久久综合精品| 91超碰碰碰碰久久久久久综合| 久久精品国产亚洲αv忘忧草| 国产L精品国产亚洲区久久 | 国产精品99精品久久免费| 久久久久久精品免费看SSS|