精品欧美一区二区三区在线观看 _久久久久国色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)

蜜桃无码一区二区三区| 国产凹凸在线观看一区二区| 东方欧美亚洲色图在线| 日韩精品视频在线观看网址| 国产精品女视频| 久久久久亚洲av片无码v| 无码精品视频一区二区三区 | 成人在线电影在线观看视频| 亚洲激情校园春色| 热99精品里视频精品| 日韩欧美中文在线视频| jizz在线免费观看| 99久久这里有精品| 在线观看成人毛片| 神马久久久久| 自拍偷拍欧美专区| 在线看不卡av| 国产日韩精品久久| 国产美女久久久久久| 日韩精品麻豆| 久久久久久久久久久久久女国产乱| 久久国产精品免费视频| 我看黄色一级片| 蜜桃久久一区二区三区| 亚洲一级毛片| 亚洲欧美日韩另类| 免费一级特黄毛片| 午夜精品久久久久久久爽 | 精品日韩在线观看| 亚洲免费av网| 色香蕉在线视频| 欧美成人高清在线| 宅男噜噜噜66一区二区| 制服.丝袜.亚洲.中文.综合| 日韩高清专区| 西西44rtwww国产精品| 99精品国产高清一区二区麻豆| 亚洲视频在线观看三级| 国产欧美精品一区二区三区-老狼 国产欧美精品一区二区三区介绍 国产欧美精品一区二区 | 亚洲精品一区二区三区婷婷月| 女人帮男人橹视频播放| www.国产黄色| 国产福利在线| 国产激情小视频在线| 免费在线看成人av| 在线观看欧美视频| 好男人www社区| av片在线免费观看| 国产一区日韩二区欧美三区| 理论片在线不卡免费观看| aaaaaaaa毛片| 国产成人77亚洲精品www| 中文字幕永久在线不卡| 91香蕉嫩草影院入口| 欧美三根一起进三p| 日韩欧美精品一区| 日韩欧美国产综合一区| 久艹视频在线免费观看| h片在线播放| 成人免费在线播放视频| 国产精品嫩草在线观看| 制服.丝袜.亚洲.中文.综合懂色| 欧美成人tv| 日韩激情第一页| 性色av蜜臀av浪潮av老女人| 欧美大片高清| 国产精品久久久久三级| 91免费观看| 在线观看中文字幕视频| 精品电影一区| 亚洲男人的天堂在线| 欧美视频自拍偷拍| 国产人妖在线观看| 四虎在线免费观看| 成人精品国产免费网站| 日本一欧美一欧美一亚洲视频| 国产精品久久免费观看| 精品视频在线播放一区二区三区 | 欧美性videos| 18涩涩午夜精品.www| 四虎精品欧美一区二区免费| 亚洲乱熟女一区二区| 亚洲一区二区三区高清不卡| 精品国内亚洲在观看18黄| 日韩无码精品一区二区| 久久夜色电影| 亚洲超碰精品一区二区| 性刺激综合网| 少妇av在线播放| 91社区在线播放| 超碰97人人在线| 伊人色综合久久久| 好看的亚洲午夜视频在线| 日韩一二三区| 夜夜嗨av一区二区三区| 欧美激情论坛| 不卡的日韩av| www亚洲视频| 欧美xx视频| 在线免费不卡视频| 手机av在线网站| 日韩欧美一区二区三区免费观看| 亚洲一区二区在线播放| 欧美极品jizzhd欧美仙踪林| 婷婷综合六月| 欧美久久久影院| 男女无套免费视频网站动漫| 欧美日韩国产观看视频| 亚洲黄色免费电影| www.com毛片| 日韩123区| 亚洲欧美日韩在线不卡| 国产91xxx| 国产福利在线| 亚洲一区二区三区视频在线播放| 国产成人成网站在线播放青青| 国产有码在线观看| 奇米888四色在线精品| 欧美亚洲另类在线| 国产精品免费av一区二区| 欧美黄片一区二区三区| 欧美aⅴ99久久黑人专区| 欧美中文字幕在线| 蜜桃色一区二区三区| 日本黄色录像片| 久久av电影| 亚洲欧美国内爽妇网| 顶臀精品视频www| 亚洲福利天堂| 91麻豆精品一区二区三区| 日韩精品久久久毛片一区二区| 欧洲性视频在线播放| 国产精品视频观看| 黄页网站在线观看视频| 欧美极品在线| 欧美精品在欧美一区二区少妇| 一级黄色片毛片| 久久在线视频免费观看| xvideos国产精品| 亚洲色图27p| 色综合五月天| 国产99视频精品免视看7| 亚洲国产精品久久久久爰性色 | 四虎成人永久免费视频| 国产成人亚洲精品狼色在线 | 亚洲免费视频播放| 宅男在线观看免费高清网站| 亚洲一二三四在线| 成人免费播放视频| 色综合天天爱| 国产日韩精品电影| 亚洲国产福利视频| 成人免费在线播放视频| 国产精品区在线| 欧美a在线观看| 色噜噜狠狠狠综合曰曰曰| 久久精品黄色片| 久久成人av少妇免费| 亚洲最大av网| 麻豆视频在线观看免费网站| 欧美优质美女网站| 久久精品三级视频| 久久国产精品一区二区| 一区二区在线观看网站| 白浆在线视频| 欧美日韩国产综合一区二区| 性鲍视频在线观看| 亚洲精品极品少妇16p| 97人人做人人爱| 亚洲精品一区二区二区| 国产·精品毛片| 日本黄大片在线观看| 日韩影片中文字幕| 曰本色欧美视频在线| 中文字幕第三页| 亚洲欧美偷拍卡通变态| 无码人妻一区二区三区免费n鬼沢 久久久无码人妻精品无码 | 欧美一区二区日韩| 白嫩情侣偷拍呻吟刺激| 日韩午夜免费视频| 欧美激情论坛| 自拍偷拍欧美日韩| 欧美第一页在线| 中文字幕观看视频| 91福利在线免费| 亚洲最大的成人av| 亚洲精品激情视频| 久久这里有精品15一区二区三区| 天堂影院一区二区| 国内外成人免费激情在线视频网站| 亚洲国产av一区二区三区| 精品在线你懂的| 天堂а√在线中文在线| www.精品国产| 久久的精品视频| 中文字幕日韩高清| 男人天堂手机在线视频| 国产精品午夜av| 久久成人18免费观看| 色综合久久久888| 九九热只有精品| 久久婷婷一区| 欧美日韩精品免费观看| 天堂久久一区| 亚洲欧洲免费视频| 国产网友自拍视频| 久久99精品久久久久婷婷| 国产a级黄色大片| 国产一区2区| 日本一区二区在线播放| 国产三区视频在线观看| 欧美视频在线不卡| 久久精品国产亚洲av高清色欲 | www.偷拍.com| 日本午夜精品一区二区三区电影| 女人床在线观看| 欧美伦理在线视频| 国产成人一区二区三区小说| 黄色小网站91| 99成人精品视频| 亚洲男同性恋视频| 毛片毛片毛片毛| 欧美aaaa视频| 久久免费99精品久久久久久| jizzjizz中国精品麻豆| 中文字幕精品久久久久| 人妻丰满熟妇av无码区hd| 欧美精品久久99久久在免费线| 少妇太紧太爽又黄又硬又爽| 国产盗摄一区二区三区| 97视频在线免费播放| 亚洲区小说区图片区qvod按摩| 成人日韩av在线| 日本中文字幕中出在线| 宅男66日本亚洲欧美视频| 亚洲av成人无码久久精品老人| 日韩欧美在线影院| av漫画在线观看| 精品一区二区免费在线观看| 韩国日本美国免费毛片| 亚洲一区国产一区| 日日躁夜夜躁aaaabbbb| 欧美99在线视频观看| 亚洲欧洲国产精品久久| 日本午夜免费一区二区| 全球成人中文在线| 欧产日产国产精品视频| 97在线观看视频国产| 女子免费在线观看视频www| 超碰97人人做人人爱少妇| a级片一区二区| 神马香蕉久久| 国产成人精品视| 三级在线看中文字幕完整版| 日韩理论片av| 日韩免费av在线| 国产高清不卡| 中文在线不卡视频| porn亚洲| 波霸ol色综合久久| 国产一二区在线| 久久99亚洲热视| av电影免费在线看| 91av在线免费观看| √天堂资源地址在线官网| 一区二区av在线| 色的视频在线免费看| 欧美tk—视频vk| 欧美综合视频在线| 日韩精品在线观| 国产理论电影在线观看| 日韩在线精品视频| 丝袜美腿av在线| 97在线看免费观看视频在线观看| 日韩脚交footjobhd| 国产va免费精品高清在线| 全球最大av网站久久| 成人激情视频网| 中文字幕一区二区三区四区久久| 人妖精品videosex性欧美| 色婷婷综合久久久中字幕精品久久| 国产精品九九久久久久久久| 乱插在线www| 91chinesevideo永久地址| 免费电影日韩网站| 国产日本欧美一区二区三区在线| 亚洲网址在线观看| 麻豆传媒一区二区| av动漫精品一区二区| 国产专区一区二区| 久久福利影院| 国产va亚洲va在线va| 久久综合五月| 一级片免费在线观看视频| 91在线国产福利| 美女伦理水蜜桃4| 久久先锋影音av| 日本japanese极品少妇| 国产成人aaa| 久久久久久九九九九九| 99精品久久99久久久久| 日韩一级片在线免费观看| 亚洲精品国产a久久久久久| 亚洲欧美综合自拍| 91精品国产综合久久久久| 四虎影视在线观看2413| 不卡中文字幕av| jizz内谢中国亚洲jizz| 91精品视频免费观看| 五月激激激综合网色播| 日本一二三区视频在线| 日韩精品一区第一页| 无码无遮挡又大又爽又黄的视频| 欧美日韩亚洲国产精品| 国产传媒久久久| 日本成人中文字幕| 亚洲欧美高清在线| 成人欧美一区二区三区白人| 日韩在线 中文字幕| 精品国产污网站| 狠狠综合久久av一区二区| 日韩中文字幕在线精品| 高潮一区二区| 久久精品国产一区二区三区日韩| 影音先锋日韩精品| 精品999在线观看| 888久久久| 黄色免费网址大全| 91在线视频18| 日本一级黄色大片| 蜜桃网站成人| 国产一区网站| 久久综合九色综合88i| 国产老女人精品毛片久久| 五月天婷婷激情网| 国产婷婷色综合av蜜臀av| 69视频在线| 日韩av成人在线| 久久av国产紧身裤| 国产在线观看欧美| 国产一区视频导航| 日韩欧美国产成人精品免费| 欧美性色黄大片手机版| 国产福利在线视频| 7777kkkk成人观看| 欧美日韩一本| 99热手机在线| 国产丶欧美丶日本不卡视频| 一本色道久久88| 精品国产乱码久久久久久果冻传媒 | 成人av资源| 亚洲精品一区二区妖精| 亚洲人成在线观看网站高清| 中文字幕在线播放网址| 3d动漫精品啪啪一区二区三区免费 | 日韩欧美一级片| 女同一区二区免费aⅴ| 国产精品对白一区二区三区| 在线观看日韩av电影| 又黄又爽的网站| 天天综合网天天综合色| 国产精品免费精品一区| 日韩精品极品在线观看| 亚洲优女在线| 亚洲一区二区三区乱码aⅴ蜜桃女| 99精品网站| av天堂永久资源网| 久久久久久久久久久电影| 香蕉污视频在线观看| 日韩欧美成人一区二区| 日本电影在线观看| 极品日韩久久| 日韩成人一区二区| 91视频青青草| 欧美精品一区二区三区高清aⅴ | 欧美性猛交xx| 亚洲国产成人porn| 91国产免费视频| 久国内精品在线| 韩国女主播一区二区三区| 成人免费观看视频在线观看| 国产欧美日本一区二区三区| 99久久综合狠狠综合久久止| 欧洲一区av| 亚洲最大中文字幕| 久久亚洲资源中文字| 国产精品8888| 91农村精品一区二区在线| 姑娘第5集在线观看免费好剧| 精品国内产的精品视频在线观看| 风间由美中文字幕在线看视频国产欧美| 国产日产欧美视频| 成人欧美一区二区三区| 午夜性色福利影院| 国产在线一区二区三区| 99亚洲一区二区| 精品女人久久久| 日韩电影中文 亚洲精品乱码| 日本国产亚洲| 国产精品无码av在线播放|