精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

深入Go語(yǔ)言網(wǎng)絡(luò)庫(kù)的基礎(chǔ)實(shí)現(xiàn)

開(kāi)發(fā) 前端 開(kāi)發(fā)工具
目前很多高性能的基礎(chǔ)網(wǎng)絡(luò)服務(wù)器都是采用的C語(yǔ)言開(kāi)發(fā)的,比如:Nginx、Redis、memcached等,它們都是基于”事件驅(qū)動(dòng) + 事件回掉函數(shù)”的方式實(shí)現(xiàn),也就是采用epoll等作為網(wǎng)絡(luò)收發(fā)數(shù)據(jù)包的核心驅(qū)動(dòng)。

Go語(yǔ)言的出現(xiàn),讓我見(jiàn)到了一門(mén)語(yǔ)言把網(wǎng)絡(luò)編程這件事情給做“正確”了,當(dāng)然,除了Go語(yǔ)言以外,還有很多語(yǔ)言也把這件事情做”正確”了。我一直堅(jiān)持著這樣的理念——要做"正確"的事情,而不是"高性能"的事情;很多時(shí)候,我們?cè)谧鱿到y(tǒng)設(shè)計(jì)、技術(shù)選型的時(shí)候,都被“高性能”這三個(gè)字給綁架了,當(dāng)然不是說(shuō)性能不重要,你懂的。

目前很多高性能的基礎(chǔ)網(wǎng)絡(luò)服務(wù)器都是采用的C語(yǔ)言開(kāi)發(fā)的,比如:Nginx、Redis、memcached等,它們都是基于”事件驅(qū)動(dòng) + 事件回掉函數(shù)”的方式實(shí)現(xiàn),也就是采用epoll等作為網(wǎng)絡(luò)收發(fā)數(shù)據(jù)包的核心驅(qū)動(dòng)。不少人(包括我自己)都認(rèn)為“事件驅(qū)動(dòng) + 事件回掉函數(shù)”的編程方法是“反人類(lèi)”的;因?yàn)榇蠖鄶?shù)人都更習(xí)慣線(xiàn)性的處理一件事情,做完***件事情再做第二件事情,并不習(xí)慣在N件事情之間頻繁的切換干 活。為了解決程序員在開(kāi)發(fā)服務(wù)器時(shí)需要自己的大腦不斷的“上下文切換”的問(wèn)題,Go語(yǔ)言引入了一種用戶(hù)態(tài)線(xiàn)程goroutine來(lái)取代編寫(xiě)異步的事件回掉 函數(shù),從而重新回歸到多線(xiàn)程并發(fā)模型的線(xiàn)性、同步的編程方式上。

用Go語(yǔ)言寫(xiě)一個(gè)最簡(jiǎn)單的echo服務(wù)器:

  1. package main 
  2.  
  3. import ( 
  4.     "log" 
  5.     "net" 
  6.  
  7. func main() { 
  8.     ln, err := net.Listen("tcp"":8080"
  9.     if err != nil { 
  10.             log.Println(err) 
  11.             return 
  12.     } 
  13.     for { 
  14.             conn, err := ln.Accept() 
  15.             if err != nil { 
  16.                 log.Println(err) 
  17.                 continue 
  18.             } 
  19.  
  20.             go echoFunc(conn) 
  21.     } 
  22.  
  23. func echoFunc(c net.Conn) { 
  24.     buf := make([]byte1024
  25.  
  26.     for { 
  27.             n, err := c.Read(buf) 
  28.             if err != nil { 
  29.                 log.Println(err) 
  30.                 return 
  31.             } 
  32.  
  33.             c.Write(buf[:n]) 
  34.     } 

main函數(shù)的過(guò)程就是首先創(chuàng)建一個(gè)監(jiān)聽(tīng)套接字,然后用一個(gè)for循環(huán)不斷的從監(jiān)聽(tīng)套接字上Accept新的連接,***調(diào)用echoFunc函數(shù)在建立的連接上干活。關(guān)鍵代碼是:

  1. go echoFunc(conn) 

每收到一個(gè)新的連接,就創(chuàng)建一個(gè)“線(xiàn)程”去服務(wù)這個(gè)連接,因此所有的業(yè)務(wù)邏輯都可以同步、順序的編寫(xiě)到echoFunc函數(shù)中,再也不用去關(guān)心網(wǎng)絡(luò) IO是否會(huì)阻塞的問(wèn)題。不管業(yè)務(wù)多復(fù)雜,Go語(yǔ)言的并發(fā)服務(wù)器的編程模型都是長(zhǎng)這個(gè)樣子。可以肯定的是,在linux上Go語(yǔ)言寫(xiě)的網(wǎng)絡(luò)服務(wù)器也是采用的 epoll作為***層的數(shù)據(jù)收發(fā)驅(qū)動(dòng),Go語(yǔ)言網(wǎng)絡(luò)的底層實(shí)現(xiàn)中同樣存在“上下文切換”的工作,只是這個(gè)切換工作由runtime的調(diào)度器來(lái)做了,減少了 程序員的負(fù)擔(dān)。

弄明白網(wǎng)絡(luò)庫(kù)的底層實(shí)現(xiàn),貌似只要弄清楚echo服務(wù)器中的Listen、Accept、Read、Write四個(gè)函數(shù)的底層實(shí)現(xiàn)關(guān)系就可以了。本文將采用自底向上的方式來(lái)介紹,也就是從***層到上層的方式,這也是我閱讀源碼的方式。底層實(shí)現(xiàn)涉及到的核心源碼文件主要有:
net/fd_unix.go
net/fd_poll_runtime.go
runtime/netpoll.goc
runtime/netpoll_epoll.c
runtime/proc.c (調(diào)度器)

netpoll_epoll.c文件是Linux平臺(tái)使用epoll作為網(wǎng)絡(luò)IO多路復(fù)用的實(shí)現(xiàn)代碼,這份代碼可以了解到epoll相關(guān)的操作(比 如:添加fd到epoll、從epoll刪除fd等),只有4個(gè)函數(shù),分別是runtime·netpollinit、 runtime·netpollopen、runtime·netpollclose和runtime·netpoll。init函數(shù)就是創(chuàng)建epoll 對(duì)象,open函數(shù)就是添加一個(gè)fd到epoll中,close函數(shù)就是從epoll刪除一個(gè)fd,netpoll函數(shù)就是從epoll wait得到所有發(fā)生事件的fd,并將每個(gè)fd對(duì)應(yīng)的goroutine(用戶(hù)態(tài)線(xiàn)程)通過(guò)鏈表返回。用epoll寫(xiě)過(guò)程序的人應(yīng)該都能理解這份代碼,沒(méi) 什么特別之處。

  1. void 
  2. runtime·netpollinit(void
  3.     epfd = runtime·epollcreate1(EPOLL_CLOEXEC); 
  4.     if(epfd >= 0
  5.         return
  6.     epfd = runtime·epollcreate(1024); 
  7.     if(epfd >= 0) { 
  8.         runtime·closeonexec(epfd); 
  9.         return
  10.     } 
  11.     runtime·printf("netpollinit: failed to create descriptor (%d)\n", -epfd); 
  12.     runtime·throw("netpollinit: failed to create descriptor"); 

runtime·netpollinit函數(shù)首先使用runtime·epollcreate1創(chuàng)建epoll實(shí)例,如果沒(méi)有創(chuàng)建成功,就換用 runtime·epollcreate再創(chuàng)建一次。這兩個(gè)create函數(shù)分別等價(jià)于glibc的epoll_create1和 epoll_create函數(shù)。只是因?yàn)镚o語(yǔ)言并沒(méi)有直接使用glibc,而是自己封裝的系統(tǒng)調(diào)用,但功能是等價(jià)于glibc的。可以通過(guò)man手冊(cè)查 看這兩個(gè)create的詳細(xì)信息。

  1. int32 
  2. runtime·netpollopen(uintptr fd, PollDesc *pd) 
  3.     EpollEvent ev; 
  4.     int32 res; 
  5.      
  6.     ev.events = EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET; 
  7.     ev.data = (uint64)pd; 
  8.     res = runtime·epollctl(epfd, EPOLL_CTL_ADD, (int32)fd, &ev); 
  9.     return -res; 

添加fd到epoll中的runtime·netpollopen函數(shù)可以看到每個(gè)fd一開(kāi)始都關(guān)注了讀寫(xiě)事件,并且采用的是邊緣觸發(fā),除此之外還關(guān)注了一個(gè)不常見(jiàn)的新事件EPOLLRDHUP,這個(gè)事件是在較新的內(nèi)核版本添加的,目的是解決對(duì)端socket關(guān)閉,epoll本身并不能直接感知到這個(gè)關(guān)閉動(dòng)作的問(wèn)題。注意任何一個(gè)fd在添加到epoll中的時(shí)候就關(guān)注了EPOLLOUT事件的話(huà),就立馬產(chǎn)生一次寫(xiě)事件,這次事件可能是多余浪費(fèi)的。

#p#

epoll操作的相關(guān)函數(shù)都會(huì)在事件驅(qū)動(dòng)的抽象層中去調(diào)用,為什么需要這個(gè)抽象層呢?原因很簡(jiǎn)單,因?yàn)镚o語(yǔ)言需要跑在不同的平臺(tái)上,有Linux、Unix、Mac OS X和Windows等,所以需要靠事件驅(qū)動(dòng)的抽象層來(lái)為網(wǎng)絡(luò)庫(kù)提供一致的接口,從而屏蔽事件驅(qū)動(dòng)的具體平臺(tái)依賴(lài)實(shí)現(xiàn)。runtime/netpoll.goc源文件就是整個(gè)事件驅(qū)動(dòng)抽象層的實(shí)現(xiàn),抽象層的核心數(shù)據(jù)結(jié)構(gòu)是:

  1. struct PollDesc 
  2.     PollDesc* link; // in pollcache, protected by pollcache.Lock 
  3.     Lock;       // protectes the following fields 
  4.     uintptr fd; 
  5.     bool    closing; 
  6.     uintptr seq;    // protects from stale timers and ready notifications 
  7.     G*  rg; // G waiting for read or READY (binary semaphore) 
  8.     Timer   rt; // read deadline timer (set if rt.fv != nil) 
  9.     int64   rd; // read deadline 
  10.     G*  wg; // the same for writes 
  11.     Timer   wt; 
  12.     int64   wd; 
  13. }; 

每個(gè)添加到epoll中的fd都對(duì)應(yīng)了一個(gè)PollDesc結(jié)構(gòu)實(shí)例,PollDesc維護(hù)了讀寫(xiě)此fd的goroutine這一非常重要的信息。可以大膽的推測(cè)一下,網(wǎng)絡(luò)IO讀寫(xiě)操作的實(shí)現(xiàn)應(yīng)該是:當(dāng)在一個(gè)fd上讀寫(xiě)遇到EAGAIN錯(cuò)誤的時(shí)候,就將當(dāng)前goroutine存儲(chǔ)到這個(gè)fd對(duì)應(yīng)的PollDesc中,同時(shí)將goroutine給park住,直到這個(gè)fd上再此發(fā)生了讀寫(xiě)事件后,再將此goroutine給ready激活重新運(yùn)行。事實(shí)上的實(shí)現(xiàn)大概也是這個(gè)樣子的。

事件驅(qū)動(dòng)抽象層主要干的事情就是將具體的事件驅(qū)動(dòng)實(shí)現(xiàn)(比如: epoll)通過(guò)統(tǒng)一的接口封裝成Go接口供net庫(kù)使用,主要的接口也是:創(chuàng)建事件驅(qū)動(dòng)實(shí)例、添加fd、刪除fd、等待事件以及設(shè)置DeadLine。runtime_pollServerInit負(fù)責(zé)創(chuàng)建事件驅(qū)動(dòng)實(shí)例,runtime_pollOpen將分配一個(gè)PollDesc實(shí)例和fd綁定起來(lái),然后將fd添加到epoll中,runtime_pollClose就是將fd從epoll中刪除,同時(shí)將刪除的fd綁定的PollDesc實(shí)例刪除,runtime_pollWait接口是至關(guān)重要的,這個(gè)接口一般是在非阻塞讀寫(xiě)發(fā)生EAGAIN錯(cuò)誤的時(shí)候調(diào)用,作用就是park當(dāng)前讀寫(xiě)的goroutine。

runtime中的epoll事件驅(qū)動(dòng)抽象層其實(shí)在進(jìn)入net庫(kù)后,又被封裝了一次,這一次封裝從代碼上看主要是為了方便在純Go語(yǔ)言環(huán)境進(jìn)行操作,net庫(kù)中的這次封裝實(shí)現(xiàn)在net/fd_poll_runtime.go文件中,主要是通過(guò)pollDesc對(duì)象來(lái)實(shí)現(xiàn)的:

  1. type pollDesc struct { 
  2.     runtimeCtx uintptr 

 注意:此處的pollDesc對(duì)象不是上文提到的runtime中的PollDesc,相反此處pollDesc對(duì)象的runtimeCtx成員才是指向的runtime的PollDesc實(shí)例。pollDesc對(duì)象主要就是將runtime的事件驅(qū)動(dòng)抽象層給再封裝了一次,供網(wǎng)絡(luò)fd對(duì)象使用。

  1. var serverInit sync.Once 
  2.  
  3. func (pd *pollDesc) Init(fd *netFD) error { 
  4.     serverInit.Do(runtime_pollServerInit) 
  5.     ctx, errno := runtime_pollOpen(uintptr(fd.sysfd)) 
  6.     if errno != 0 { 
  7.         return syscall.Errno(errno) 
  8.     } 
  9.     pd.runtimeCtx = ctx 
  10.     return nil 

pollDesc對(duì)象最需要關(guān)注的就是其Init方法,這個(gè)方法通過(guò)一個(gè)sync.Once變量來(lái)調(diào)用了runtime_pollServerInit函數(shù),也就是創(chuàng)建epoll實(shí)例的函數(shù)。意思就是runtime_pollServerInit函數(shù)在整個(gè)進(jìn)程生命周期內(nèi)只會(huì)被調(diào)用一次,也就是只會(huì)創(chuàng)建一次epoll實(shí)例。epoll實(shí)例被創(chuàng)建后,會(huì)調(diào)用runtime_pollOpen函數(shù)將fd添加到epoll中。

網(wǎng)絡(luò)編程中的所有socket fd都是通過(guò)netFD對(duì)象實(shí)現(xiàn)的,netFD是對(duì)網(wǎng)絡(luò)IO操作的抽象,linux的實(shí)現(xiàn)在文件net/fd_unix.go中。netFD對(duì)象實(shí)現(xiàn)有自己的init方法,還有完成基本IO操作的Read和Write方法,當(dāng)然除了這三個(gè)方法以外,還有很多非常有用的方法供用戶(hù)使用。

  1. // Network file descriptor. 
  2. type netFD struct { 
  3.     // locking/lifetime of sysfd + serialize access to Read and Write methods 
  4.     fdmu fdMutex 
  5.  
  6.     // immutable until Close 
  7.     sysfd       int 
  8.     family      int 
  9.     sotype      int 
  10.     isConnected bool 
  11.     net         string 
  12.     laddr       Addr 
  13.     raddr       Addr 
  14.  
  15.     // wait server 
  16.     pd pollDesc 

通過(guò)netFD對(duì)象的定義可以看到每個(gè)fd都關(guān)聯(lián)了一個(gè)pollDesc實(shí)例,通過(guò)上文我們知道pollDesc對(duì)象最終是對(duì)epoll的封裝。

  1. func (fd *netFD) init() error { 
  2.     if err := fd.pd.Init(fd); err != nil { 
  3.         return err 
  4.     } 
  5.     return nil 

netFD對(duì)象的init函數(shù)僅僅是調(diào)用了pollDesc實(shí)例的Init函數(shù),作用就是將fd添加到epoll中,如果這個(gè)fd是***個(gè)網(wǎng)絡(luò)socket fd的話(huà),這一次init還會(huì)擔(dān)任創(chuàng)建epoll實(shí)例的任務(wù)。要知道在Go進(jìn)程里,只會(huì)有一個(gè)epoll實(shí)例來(lái)管理所有的網(wǎng)絡(luò)socket fd,這個(gè)epoll實(shí)例也就是在***個(gè)網(wǎng)絡(luò)socket fd被創(chuàng)建的時(shí)候所創(chuàng)建。

  1. for { 
  2.     n, err = syscall.Read(int(fd.sysfd), p) 
  3.     if err != nil { 
  4.         n = 0 
  5.         if err == syscall.EAGAIN { 
  6.             if err = fd.pd.WaitRead(); err == nil { 
  7.                 continue 
  8.             } 
  9.         } 
  10.     } 
  11.     err = chkReadErr(n, err, fd) 
  12.     break 

上面代碼段是從netFD的Read方法中摘取,重點(diǎn)關(guān)注這個(gè)for循環(huán)中的syscall.Read調(diào)用的錯(cuò)誤處理。當(dāng)有錯(cuò)誤發(fā)生的時(shí)候,會(huì)檢查這個(gè)錯(cuò)誤是否是syscall.EAGAIN,如果是,則調(diào)用WaitRead將當(dāng)前讀這個(gè)fd的goroutine給park住,直到這個(gè)fd上的讀事件再次發(fā)生為止。當(dāng)這個(gè)socket上有新數(shù)據(jù)到來(lái)的時(shí)候,WaitRead調(diào)用返回,繼續(xù)for循環(huán)的執(zhí)行。這樣的實(shí)現(xiàn),就讓調(diào)用netFD的Read的地方變成了同步“阻塞”方式編程,不再是異步非阻塞的編程方式了。netFD的Write方法和Read的實(shí)現(xiàn)原理是一樣的,都是在碰到EAGAIN錯(cuò)誤的時(shí)候?qū)?dāng)前goroutine給park住直到socket再次可寫(xiě)為止。

本文只是將網(wǎng)絡(luò)庫(kù)的底層實(shí)現(xiàn)給大體上引導(dǎo)了一遍,知道底層代碼大概實(shí)現(xiàn)在什么地方,方便結(jié)合源碼深入理解。Go語(yǔ)言中的高并發(fā)、同步阻塞方式編程的關(guān)鍵其實(shí)是”goroutine和調(diào)度器”,針對(duì)網(wǎng)絡(luò)IO的時(shí)候,我們需要知道EAGAIN這個(gè)非常關(guān)鍵的調(diào)度點(diǎn),掌握了這個(gè)調(diào)度點(diǎn),即使沒(méi)有調(diào)度器,自己也可以在epoll的基礎(chǔ)上配合協(xié)程等用戶(hù)態(tài)線(xiàn)程實(shí)現(xiàn)網(wǎng)絡(luò)IO操作的調(diào)度,達(dá)到同步阻塞編程的目的。

***,為什么需要同步阻塞的方式編程?只有看多、寫(xiě)多了異步非阻塞代碼的時(shí)候才能夠深切體會(huì)到這個(gè)問(wèn)題。真正的高大上絕對(duì)不是——“別人不會(huì),我會(huì);別人寫(xiě)不出來(lái),我寫(xiě)得出來(lái)。”

原文鏈接:http://skoo.me/go/2014/04/21/go-net-core/

責(zé)任編輯:林師授 來(lái)源: skoo's notes
相關(guān)推薦

2023-12-30 10:22:57

Go語(yǔ)言函數(shù)開(kāi)發(fā)

2023-11-30 08:09:02

Go語(yǔ)言

2022-10-24 00:48:58

Go語(yǔ)言errgroup

2023-11-01 08:08:50

Go語(yǔ)言傳遞請(qǐng)求

2021-10-16 17:53:35

Go函數(shù)編程

2024-03-25 07:22:50

GolangMySQL數(shù)據(jù)庫(kù)

2023-11-06 13:32:38

Go編程

2021-01-23 12:47:19

MySQL數(shù)據(jù)庫(kù)Go語(yǔ)言

2024-01-07 19:54:51

2022-05-09 10:36:05

PythonPyScript開(kāi)發(fā)者

2017-08-31 11:28:47

Slice底層實(shí)現(xiàn)

2023-01-30 08:16:39

Go語(yǔ)言Map

2024-03-26 00:17:51

Go語(yǔ)言IO

2024-05-29 08:05:15

Go協(xié)程通信

2021-06-09 09:06:52

Go語(yǔ)言算法

2021-02-06 18:19:54

TimeGo語(yǔ)言

2024-03-29 09:12:43

Go語(yǔ)言工具

2024-04-07 00:04:00

Go語(yǔ)言Map

2025-11-05 03:00:55

2024-02-26 19:38:20

GitHubGo庫(kù)Golang
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

国产十六处破外女视频| 色七七在线观看| 欧美性受xxxx狂喷水| 亚洲裸体俱乐部裸体舞表演av| 亚洲另类图片色| 狠狠干狠狠操视频| aa级大片免费在线观看| 久久久久国产精品麻豆ai换脸 | 99久久久无码国产精品性| 精品裸体bbb| 亚洲精品一卡二卡| 欧美日韩精品久久| 国产手机视频在线| 久久婷婷丁香| 另类少妇人与禽zozz0性伦| 大尺度做爰床戏呻吟舒畅| 高清电影一区| 亚洲成人手机在线| 在线视频一区观看| 三级在线播放| 国产激情视频一区二区三区欧美| 国产97在线|亚洲| 青青青在线视频| av一区二区在线播放| 亚洲精品一线二线三线无人区| 欧美三级理论片| 日产福利视频在线观看| 亚洲婷婷在线视频| 亚洲高清视频在线观看| 亚洲欧美自偷自拍| 高清视频一区二区| 成人国产亚洲精品a区天堂华泰| 国产午夜精品无码| 欧美不卡视频| 久久精品一偷一偷国产| 白白色免费视频| 久久99精品国产自在现线| 欧美一区二区三区不卡| 在线免费观看av的网站| 欧美大片1688| 精品女同一区二区三区在线播放| 粉嫩av一区二区三区天美传媒| 婷婷激情在线| 日本一区二区三区免费乱视频| 狠狠色综合一区二区| 国产成人精品无码高潮| 国产一区二区在线观看视频| 国产精品日日做人人爱| 日韩在线播放中文字幕| 亚洲一区二区三区免费在线观看 | 欧美成人vps| 中文字幕成人免费视频| 另类一区二区| 欧美日韩综合在线免费观看| 国产精品拍拍拍| 日韩欧美另类一区二区| 欧美性猛交xxxx富婆| 91视频最新入口| 黄色18在线观看| 午夜一区二区三区在线观看| 久久亚洲国产成人精品无码区| 成人区精品一区二区不卡| 国产日韩成人精品| 亚洲啪啪av| 欧美日韩xx| 椎名由奈av一区二区三区| 中文字幕中文字幕在线中一区高清 | 狠狠综合久久av| 天堂√在线中文官网在线| 94色蜜桃网一区二区三区| 欧美二区在线看| 欧美高清电影在线| 中文字幕第一区综合| 亚洲一二三区精品| 欧美日韩色网| 欧美日韩激情网| 亚洲人成无码www久久久| 久久91导航| 欧美日韩精品一区二区天天拍小说| 国产91色在线观看| 久久久久毛片免费观看| 精品国产免费人成电影在线观看四季 | 户外露出一区二区三区| 欧美熟乱第一页| 国产精品探花在线播放| www.国产精品一区| 精品夜色国产国偷在线| 极品尤物一区二区| 国内精品美女在线观看| 青草成人免费视频| 国产一区二区自拍视频| 波多野结衣中文字幕一区二区三区 | 国内精品免费| 一区二区欧美亚洲| 男人av资源站| 国产视频一区三区| 国产欧美一区二区白浆黑人| 亚洲精品911| 国产亚洲欧美日韩在线一区| 久久视频免费在线| 中文字幕在线免费观看视频| 欧美美女一区二区| 风间由美一二三区av片| 97人人精品| 91av福利视频| 99久久99久久久精品棕色圆| 99re视频精品| 精品少妇人妻av一区二区| 欧亚av在线| 日韩一区二区在线免费观看| 欧洲女同同性吃奶| 欧美午夜a级限制福利片| 日本91av在线播放| 亚洲av无码一区二区乱子伦| 久久九九久久九九| 18禁裸男晨勃露j毛免费观看| 桃花岛成人影院| 日韩免费在线观看| 蜜桃av免费观看| 亚洲少妇自拍| 5566av亚洲| 视频一区二区三区不卡| 福利一区福利二区微拍刺激| 巨乳女教师的诱惑| 视频在线不卡免费观看| 日本欧美精品在线| 色香蕉在线视频| 亚洲卡通动漫在线| 国产原创精品在线| 国产伦一区二区三区| 久久久久久网站| www.黄色国产| 亚洲视频网在线直播| 中文字幕一区二区三区四区在线视频| 极品尤物一区| 欧美精品aaa| 国产婷婷在线视频| 综合电影一区二区三区 | 国产在线综合网| 韩国av一区二区三区在线观看| 欧美日韩在线不卡一区| 在线人成日本视频| 日韩电视剧免费观看网站| 久久久精品视频在线| 国产高清精品网站| 成人免费看片视频在线观看| 四虎影视国产精品| 日韩在线观看网站| 欧美性受xxx黑人xyx性爽| 久久蜜桃av一区精品变态类天堂| 国内外成人激情视频| 亚洲第一福利社区| 国产成人高潮免费观看精品| 麻豆导航在线观看| 欧美综合欧美视频| 调教驯服丰满美艳麻麻在线视频| 日本美女一区二区| 一区二区日本伦理| 国产亚洲高清一区| 久久久久久久国产| 日韩中文字幕免费在线观看| 亚洲一区二区美女| 少妇毛片一区二区三区| 国产一区二区精品| 日韩电影免费观看高清完整| 精品欧美日韩精品| 久久精品国产亚洲7777| 99热精品在线播放| 亚洲成a人片综合在线| 男男做爰猛烈叫床爽爽小说| 久久精品日韩欧美| 亚洲成人精品电影在线观看| 亚洲精品大片| 欧美极品少妇全裸体| 青青草在线免费观看| 在线看日本不卡| 伊人久久久久久久久久久久久久| 国产成人亚洲综合a∨婷婷| 国产激情片在线观看| 2023国产精华国产精品| 91av在线免费观看视频| 91精品国产综合久久久久久豆腐| 在线播放91灌醉迷j高跟美女 | 午夜精品av| 精品欧美一区二区久久久伦| 久久久人成影片一区二区三区在哪下载 | 天天插综合网| 国产精品二区二区三区| 国产精品迅雷| 欧美成人免费小视频| 午夜福利一区二区三区| 欧美久久一二区| 国产午夜福利一区二区| 欧美激情在线免费观看| 黄色片子免费看| 可以看av的网站久久看| 佐佐木明希av| 欧美综合另类| 国产日本一区二区三区| 成人国产激情| 91精品国产一区| 老司机午夜在线| 亚洲欧美另类在线观看| 国产超碰人人模人人爽人人添| 色婷婷狠狠综合| 久久国产精品二区| 国产精品欧美一区二区三区| 亚洲少妇一区二区| 日韩高清在线一区| 色噜噜一区二区| 国产精品nxnn| 91精品久久久久| 欧洲亚洲两性| 色综合天天狠天天透天天伊人| 欧美日韩免费做爰大片| 日韩一区国产二区欧美三区| 日本三级一区二区三区| 亚洲国产日韩在线一区模特| 亚洲精品国产熟女久久久| 精品一区二区三区在线观看国产 | 一出一进一爽一粗一大视频| 国产一区二区三区av电影| 伊人成色综合网| 亚洲色图二区| 亚洲精品国产精品国自产| 欧美日韩另类图片| 国产高清精品一区二区三区| 久久亚洲国产精品尤物| 欧美亚洲视频在线观看| 色婷婷av在线| www.午夜精品| 日本黄色片在线观看| 亚洲欧美国产精品| 亚洲精品综合网| 日韩视频中午一区| 影音先锋国产资源| 色欧美88888久久久久久影院| 久久久国产精品黄毛片| 一区二区三区影院| 影音先锋男人资源在线观看| 久久人人爽爽爽人久久久| japanese在线观看| 国产一区高清在线| 中文字幕国产免费| 视频一区二区三区中文字幕| 久久久免费视频网站| 亚洲另类视频| 久久男人资源站| 国产综合自拍| 国产在线拍揄自揄拍无码| 日韩一区二区三区免费播放| 奇米视频888战线精品播放| 九九久久婷婷| 欧美亚洲国产免费| 伊人久久大香线蕉综合网站| 欧美日韩一区二区视频在线| 日韩激情网站| 国产一区喷水| 久久影视三级福利片| 精品一区久久久| 欧美三级电影在线| 激情五月综合色婷婷一区二区| 麻豆一区一区三区四区| 韩国成人动漫在线观看| 牛牛影视一区二区三区免费看| 国产aⅴ精品一区二区三区黄| 国产区精品视频在线观看豆花| 2019国产精品视频| 亚洲一级大片| 高清国产在线一区| 免费欧美视频| 日韩欧美精品一区二区三区经典| 国产欧美亚洲精品a| 亚洲一区尤物| 欧美高清不卡| 亚洲 欧美 综合 另类 中字| 午夜在线视频观看日韩17c| 97超碰青青草| 日韩不卡在线观看日韩不卡视频| 国产美女三级视频| 另类人妖一区二区av| 五月天激情播播| 国产成人在线免费| 亚洲人成人无码网www国产| 日本一区二区三区在线不卡| 午夜剧场免费在线观看| 午夜电影一区二区三区| 中文字幕亚洲乱码熟女1区2区| 欧美在线免费观看亚洲| 最近中文字幕av| 精品国产一区二区三区忘忧草 | 亚洲欧洲精品一区二区三区波多野1战4| 欧美手机视频| 999一区二区三区| 蘑菇福利视频一区播放| 91制片厂毛片| 99久久婷婷国产综合精品电影| a级大片在线观看| 国产精品电影一区二区| 欧美不卡视频在线观看| 在线观看91精品国产入口| 99久久国产免费| 日韩精品免费在线观看| 99免在线观看免费视频高清| 欧美成人免费全部观看天天性色| 污视频在线免费观看网站| 国产成人一区二区三区小说| av日韩久久| 美女被啪啪一区二区| 欧美激情视频一区二区三区在线播放| 国产99久久九九精品无码| 国产最新精品免费| 亚洲欧美va天堂人熟伦 | 日韩乱码一区二区| 91精品午夜视频| 日本精品专区| 欧美精品激情在线| 国内精品伊人| 国产精品推荐精品| 日韩av大片| 久久99久久99精品| 国模一区二区三区白浆| 一区二区精品免费| 狠狠色狠狠色综合日日小说| 888奇米影视| 亚洲欧美综合精品久久成人| 不卡的av影片| 亚洲va欧美va在线观看| 国产传媒欧美日韩成人精品大片| 国内自拍中文字幕| 美女视频网站黄色亚洲| 精品少妇一区二区三区免费观| 亚洲成人在线免费| 精品国产伦一区二区三区| 中文字幕精品一区二区精品| 色老太综合网| 国内精品久久国产| 欧美黄色免费| 91欧美一区二区三区| 国产精品久久久久久久久搜平片| 99久热在线精品996热是什么| 精品久久一二三区| 成a人片在线观看| 国产欧美一区二区白浆黑人| 免费国产自久久久久三四区久久| 久艹视频在线免费观看| 国产成人久久精品77777最新版本 国产成人鲁色资源国产91色综 | 亚洲wwww| 欧美一区少妇| 欧美一级专区| 国产精品无码永久免费不卡| 午夜精品免费在线| 丰满人妻一区二区三区无码av | 欧美午夜视频网站| 精品美女视频在线观看免费软件| 97成人超碰免| 夜夜春成人影院| 免费高清在线观看免费| 波多野洁衣一区| 中文字幕一区在线播放| 国产婷婷97碰碰久久人人蜜臀| 白浆在线视频| 久久久久久久久久久久久久久久av | 国产福利一区二区三区视频| 青青青在线免费观看| 91精品国产乱| 成人免费高清观看| 国产伦精品一区二区三区在线 | 日本资源在线| av激情久久| 免费亚洲一区| 免费成人深夜天涯网站| 欧美日韩免费一区二区三区视频| 麻豆网站在线免费观看| 亚洲一区二区三| 亚洲精品极品少妇16p| 国产伦理在线观看| 欧美日韩国产一区在线| 五月婷婷在线观看视频| 欧亚精品中文字幕| av亚洲免费| 午夜性福利视频| 欧美午夜无遮挡| www.91在线| 国产精品一区二区三区四区五区| 亚洲视频成人| 成人无码av片在线观看| 欧美剧情片在线观看| 国产盗摄精品一区二区酒店| 欧美高清一区二区| 麻豆国产欧美日韩综合精品二区 | 77777少妇光屁股久久一区| 国产亚洲一区二区三区啪| 亚洲视频一二三四| 一区二区三区免费看视频| 男人天堂综合| 成人有码视频在线播放| 日韩视频在线一区二区三区| 青青草华人在线视频| 精品盗摄一区二区三区|