亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁(yè) > 服務(wù)器 > Linux服務(wù)器 > 正文

linux epoll機(jī)制詳解

2024-09-05 23:04:35
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

在linux/142382.html">linux/199397.html">linux 沒(méi)有實(shí)現(xiàn)epoll事件驅(qū)動(dòng)機(jī)制之前,我們一般選擇用select或者poll等IO多路復(fù)用的方法來(lái)實(shí)現(xiàn)并發(fā)服務(wù)程序。在linux新的內(nèi)核中,有了一種替換它的機(jī)制,就是epoll。

select()和poll() IO多路復(fù)用模型

select的缺點(diǎn):

1.單個(gè)進(jìn)程能夠監(jiān)視的文件描述符的數(shù)量存在最大限制,通常是1024,當(dāng)然可以更改數(shù)量,但由于select采用輪詢的方式掃描文件描述符,文件描述符數(shù)量越多,性能越差;(在linux內(nèi)核頭文件中,有這樣的定義:#define __FD_SETSIZE 1024)
2.內(nèi)核 / 用戶空間內(nèi)存拷貝問(wèn)題,select需要復(fù)制大量的句柄數(shù)據(jù)結(jié)構(gòu),產(chǎn)生巨大的開銷;
3.select返回的是含有整個(gè)句柄的數(shù)組,應(yīng)用程序需要遍歷整個(gè)數(shù)組才能發(fā)現(xiàn)哪些句柄發(fā)生了事件;
4.select的觸發(fā)方式是水平觸發(fā),應(yīng)用程序如果沒(méi)有完成對(duì)一個(gè)已經(jīng)就緒的文件描述符進(jìn)行IO操作,那么之后每次select調(diào)用還是會(huì)將這些文件描述符通知進(jìn)程。

相比select模型,poll使用鏈表保存文件描述符,因此沒(méi)有了監(jiān)視文件數(shù)量的限制,但其他三個(gè)缺點(diǎn)依然存在。

假設(shè)我們的服務(wù)器需要支持100萬(wàn)的并發(fā)連接,則在__FD_SETSIZE 為1024的情況下,則我們至少需要開辟1k個(gè)進(jìn)程才能實(shí)現(xiàn)100萬(wàn)的并發(fā)連接。除了進(jìn)程間上下文切換的時(shí)間消耗外,從內(nèi)核/用戶空間大量的無(wú)腦內(nèi)存拷貝、數(shù)組輪詢等,是系統(tǒng)難以承受的。因此,基于select模型的服務(wù)器程序,要達(dá)到10萬(wàn)級(jí)別的并發(fā)訪問(wèn),是一個(gè)很難完成的任務(wù)。

epoll IO多路復(fù)用模型實(shí)現(xiàn)機(jī)制

由于epoll的實(shí)現(xiàn)機(jī)制與select/poll機(jī)制完全不同,上面所說(shuō)的 select的缺點(diǎn)在epoll上不復(fù)存在。

設(shè)想一下如下場(chǎng)景:有100萬(wàn)個(gè)客戶端同時(shí)與一個(gè)服務(wù)器進(jìn)程保持著TCP連接。而每一時(shí)刻,通常只有幾百上千個(gè)TCP連接是活躍的(事實(shí)上大部分場(chǎng)景都是這種情況)。如何實(shí)現(xiàn)這樣的高并發(fā)?

在select/poll時(shí)代,服務(wù)器進(jìn)程每次都把這100萬(wàn)個(gè)連接告訴操作系統(tǒng)(從用戶態(tài)復(fù)制句柄數(shù)據(jù)結(jié)構(gòu)到內(nèi)核態(tài)),讓操作系統(tǒng)內(nèi)核去查詢這些套接字上是否有事件發(fā)生,輪詢完后,再將句柄數(shù)據(jù)復(fù)制到用戶態(tài),讓服務(wù)器應(yīng)用程序輪詢處理已發(fā)生的網(wǎng)絡(luò)事件,這一過(guò)程資源消耗較大,因此,select/poll一般只能處理幾千的并發(fā)連接。

epoll的設(shè)計(jì)和實(shí)現(xiàn)與select完全不同。epoll通過(guò)在Linux內(nèi)核中申請(qǐng)一個(gè)簡(jiǎn)易的文件系統(tǒng)(文件系統(tǒng)一般用什么數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)?B+樹)。把原先的select/poll調(diào)用分成了3個(gè)部分:

1)調(diào)用epoll_create()建立一個(gè)epoll對(duì)象(在epoll文件系統(tǒng)中為這個(gè)句柄對(duì)象分配資源)

2)調(diào)用epoll_ctl向epoll對(duì)象中添加這100萬(wàn)個(gè)連接的套接字

3)調(diào)用epoll_wait收集發(fā)生的事件的連接

如此一來(lái),要實(shí)現(xiàn)上面說(shuō)是的場(chǎng)景,只需要在進(jìn)程啟動(dòng)時(shí)建立一個(gè)epoll對(duì)象,然后在需要的時(shí)候向這個(gè)epoll對(duì)象中添加或者刪除連接。同時(shí),epoll_wait的效率也非常高,因?yàn)檎{(diào)用epoll_wait時(shí),并沒(méi)有一股腦的向操作系統(tǒng)復(fù)制這100萬(wàn)個(gè)連接的句柄數(shù)據(jù),內(nèi)核也不需要去遍歷全部的連接。

epoll實(shí)現(xiàn)機(jī)制

當(dāng)某一進(jìn)程調(diào)用epoll_create方法時(shí),Linux內(nèi)核會(huì)創(chuàng)建一個(gè)eventpoll結(jié)構(gòu)體,這個(gè)結(jié)構(gòu)體中有兩個(gè)成員與epoll的使用方式密切相關(guān)。eventpoll結(jié)構(gòu)體如下所示:

struct eventpoll{ .... /*紅黑樹的根節(jié)點(diǎn),這顆樹中存儲(chǔ)著所有添加到epoll中的需要監(jiān)控的事件*/ struct rb_root rbr; /*雙鏈表中則存放著將要通過(guò)epoll_wait返回給用戶的滿足條件的事件*/ struct list_head rdlist; ....};

每一個(gè)epoll對(duì)象都有一個(gè)獨(dú)立的eventpoll結(jié)構(gòu)體,用于存放通過(guò)epoll_ctl方法向epoll對(duì)象中添加進(jìn)來(lái)的事件。這些事件都會(huì)掛載在紅黑樹中,如此,重復(fù)添加的事件就可以通過(guò)紅黑樹而高效的識(shí)別出來(lái)(紅黑樹的插入時(shí)間效率是lgn,其中n為樹的高度)。

而所有添加到epoll中的事件都會(huì)與設(shè)備(網(wǎng)卡)驅(qū)動(dòng)程序建立回調(diào)關(guān)系,也就是說(shuō),當(dāng)相應(yīng)的事件發(fā)生時(shí)會(huì)調(diào)用這個(gè)回調(diào)方法。這個(gè)回調(diào)方法在內(nèi)核中叫ep_poll_callback,它會(huì)將發(fā)生的事件添加到rdlist雙鏈表中。

在epoll中,對(duì)于每一個(gè)事件,都會(huì)建立一個(gè)epitem結(jié)構(gòu)體,如下所示:

struct epitem{ struct rb_node rbn;//紅黑樹節(jié)點(diǎn) struct list_head rdllink;//雙向鏈表節(jié)點(diǎn) struct epoll_filefd ffd; //事件句柄信息 struct eventpoll *ep; //指向其所屬的eventpoll對(duì)象 struct epoll_event event; //期待發(fā)生的事件類型}

當(dāng)調(diào)用epoll_wait檢查是否有事件發(fā)生時(shí),只需要檢查eventpoll對(duì)象中的rdlist雙鏈表中是否有epitem元素即可。如果rdlist不為空,則把發(fā)生的事件復(fù)制到用戶態(tài),同時(shí)將事件數(shù)量返回給用戶。

linux,epoll機(jī)制,linux的epoll機(jī)制,pipe,消息機(jī)制,epoll,使用

通過(guò)紅黑樹和雙鏈表數(shù)據(jù)結(jié)構(gòu),并結(jié)合回調(diào)機(jī)制,造就了epoll的高效。

epoll的接口

1.epoll_create

創(chuàng)建epoll句柄
函數(shù)聲明:int epoll_create(int size)

參數(shù):size用來(lái)告訴內(nèi)核這個(gè)監(jiān)聽的數(shù)目一共有多大。
返回值:返回創(chuàng)建了的epoll句柄。
當(dāng)創(chuàng)建好epoll句柄后,它就是會(huì)占用一個(gè)fd值,在linux下如果查看/proc/進(jìn)程id/fd/,是能夠看到這個(gè)fd的,所以在使用完epoll后,必須調(diào)用close()關(guān)閉,否則可能導(dǎo)致fd被耗盡。

2.epoll_ctl

將被監(jiān)聽的描述符添加到epoll句柄或從epool句柄中刪除或者對(duì)監(jiān)聽事件進(jìn)行修改。
函數(shù)申明:int epoll_ctl(int epfd, int op, int fd, struct epoll_event*event);

參數(shù):
epfd: epoll_create()的返回值
op:表示要進(jìn)行的操作,其值分別為:
EPOLL_CTL_ADD: 注冊(cè)新的fd到epfd中;
EPOLL_CTL_MOD: 修改已經(jīng)注冊(cè)的fd的監(jiān)聽事件;
EPOLL_CTL_DEL: 從epfd中刪除一個(gè)fd;
fd:需要操作/監(jiān)聽的文件句柄
event:是告訴內(nèi)核需要監(jiān)聽什么事件,struct epoll_event如下:

typedef union epoll_data { void *ptr; int fd; __uint32_t u32; __uint64_t u64; } epoll_data_t; struct epoll_event { __uint32_t events; /* Epoll events */ epoll_data_t data; /* User data variable */ }; 

events可以是以下幾個(gè)宏的集合:

EPOLLIN:觸發(fā)該事件,表示對(duì)應(yīng)的文件描述符上有可讀數(shù)據(jù)。(包括對(duì)端SOCKET正常關(guān)閉);
EPOLLOUT:觸發(fā)該事件,表示對(duì)應(yīng)的文件描述符上可以寫數(shù)據(jù);
EPOLLPRI:表示對(duì)應(yīng)的文件描述符有緊急的數(shù)據(jù)可讀(這里應(yīng)該表示有帶外數(shù)據(jù)到來(lái));
EPOLLERR:表示對(duì)應(yīng)的文件描述符發(fā)生錯(cuò)誤;
EPOLLHUP: 表示對(duì)應(yīng)的文件描述符被掛斷;
EPOLLET:將EPOLL設(shè)為邊緣觸發(fā)(EdgeTriggered)模式,這是相對(duì)于水平觸發(fā)(Level Triggered)來(lái)說(shuō)的。
EPOLLONESHOT: 只監(jiān)聽一次事件,當(dāng)監(jiān)聽完這次事件之后,如果還需要繼續(xù)監(jiān)聽這個(gè)socket的話,需要再次把這個(gè)socket加入到EPOLL隊(duì)列里。

示例:

struct epoll_event ev;//設(shè)置與要處理的事件相關(guān)的文件描述符ev.data.fd=listenfd;//設(shè)置要處理的事件類型ev.events=EPOLLIN|EPOLLET;//注冊(cè)epoll事件epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev);

1.epoll_wait

等侍注冊(cè)在epfd上的socket fd的事件的發(fā)生,如果發(fā)生則將發(fā)生的sokct fd和事件類型放入到events數(shù)組中。
函數(shù)原型:int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);

參數(shù):
epfd:由epoll_create 生成的epoll文件描述符
events:用于回傳代處理事件的數(shù)組
maxevents:每次能處理的最大事件數(shù)
timeout:等待I/O事件發(fā)生的超時(shí)毫秒數(shù),-1相當(dāng)于阻塞,0相當(dāng)于非阻塞。一般用-1即可

epoll的工作模式

ET(EdgeTriggered):高速工作模式,只支持no_block(非阻塞模式)。在此模式下,當(dāng)描述符從未就緒變?yōu)榫途w時(shí),內(nèi)核通過(guò)epoll告知。然后它會(huì)假設(shè)用戶知道文件描述符已經(jīng)就緒,并且不會(huì)再為那個(gè)文件描述符發(fā)送更多的就緒通知,直到某些操作導(dǎo)致那個(gè)文件描述符不再為就緒狀態(tài)了。(觸發(fā)模式只在數(shù)據(jù)就緒時(shí)通知一次,若數(shù)據(jù)沒(méi)有讀完,下一次不會(huì)通知,直到有新的就緒數(shù)據(jù))

LT(LevelTriggered):缺省工作方式,支持blocksocket和no_blocksocket。在LT模式下內(nèi)核會(huì)告知一個(gè)文件描述符是否就緒了,然后可以對(duì)這個(gè)就緒的fd進(jìn)行IO操作。如果不作任何操作,內(nèi)核還是會(huì)繼續(xù)通知!若數(shù)據(jù)沒(méi)有讀完,內(nèi)核也會(huì)繼續(xù)通知,直至設(shè)備數(shù)據(jù)為空為止!

示例說(shuō)明:

1.我們已經(jīng)把一個(gè)用來(lái)從管道中讀取數(shù)據(jù)的文件句柄(RFD)添加到epoll描述符
2. 這個(gè)時(shí)候從管道的另一端被寫入了2KB的數(shù)據(jù)
3. 調(diào)用epoll_wait(2),并且它會(huì)返回RFD,說(shuō)明它已經(jīng)準(zhǔn)備好讀取操作
4. 然后我們讀取了1KB的數(shù)據(jù)
5. 調(diào)用epoll_wait(2)……

ET工作模式:

如果我們?cè)诘?步將RFD添加到epoll描述符的時(shí)候使用了EPOLLET標(biāo)志,在第2步執(zhí)行了一個(gè)寫操作,第三步epoll_wait會(huì)返回同時(shí)通知的事件會(huì)銷毀。因?yàn)榈?步的讀取操作沒(méi)有讀空文件輸入緩沖區(qū)內(nèi)的數(shù)據(jù),因此我們?cè)诘?步調(diào)用epoll_wait(2)完成后,是否掛起是不確定的。epoll工作在ET模式的時(shí)候,必須使用非阻塞套接口,以避免由于一個(gè)文件句柄的阻塞讀/阻塞寫操作把處理多個(gè)文件描述符的任務(wù)餓死。

只有當(dāng)read(2)或者write(2)返回EAGAIN時(shí)(認(rèn)為讀完)才需要掛起,等待。但這并不是說(shuō)每次read()時(shí)都需要循環(huán)讀,直到讀到產(chǎn)生一個(gè)EAGAIN才認(rèn)為此次事件處理完成,當(dāng)read()返回的讀到的數(shù)據(jù)長(zhǎng)度小于請(qǐng)求的數(shù)據(jù)長(zhǎng)度時(shí)(即小于sizeof(buf)),就可以確定此時(shí)緩沖中已沒(méi)有數(shù)據(jù)了,也就可以認(rèn)為此事讀事件已處理完成。

LT工作模式:

LT方式調(diào)用epoll接口的時(shí)候,它就相當(dāng)于一個(gè)速度比較快的poll(2),并且無(wú)論后面的數(shù)據(jù)是否被使用,因此他們具有同樣的職能。

示例

/** file epollTest.c*/#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <sys/socket.h> #include <netdb.h> #include <fcntl.h> #include <sys/epoll.h> #include <string.h> #define MAXEVENTS 64 //函數(shù): //功能:創(chuàng)建和綁定一個(gè)TCP socket //參數(shù):端口 //返回值:創(chuàng)建的socket static int create_and_bind (char *port) {  struct addrinfo hints;  struct addrinfo *result, *rp;  int s, sfd;  memset (&hints, 0, sizeof (struct addrinfo));  hints.ai_family = AF_UNSPEC;  /* Return IPv4 and IPv6 choices */  hints.ai_socktype = SOCK_STREAM; /* We want a TCP socket */  hints.ai_flags = AI_PASSIVE;  /* All interfaces */  s = getaddrinfo (NULL, port, &hints, &result);  if (s != 0)  {   fprintf (stderr, "getaddrinfo: %s/n", gai_strerror (s));   return -1;  }  for (rp = result; rp != NULL; rp = rp->ai_next)  {   sfd = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol);   if (sfd == -1)   continue;   s = bind (sfd, rp->ai_addr, rp->ai_addrlen);   if (s == 0)   {    /* We managed to bind successfully! */    break;   }   close (sfd);  }  if (rp == NULL)  {   fprintf (stderr, "Could not bind/n");   return -1;  }  freeaddrinfo (result);  return sfd; } //函數(shù) //功能:設(shè)置socket為非阻塞的 static int make_socket_non_blocking (int sfd) {  int flags, s;  //得到文件狀態(tài)標(biāo)志  flags = fcntl (sfd, F_GETFL, 0);  if (flags == -1)  {   perror ("fcntl");   return -1;  }  //設(shè)置文件狀態(tài)標(biāo)志  flags |= O_NONBLOCK;  s = fcntl (sfd, F_SETFL, flags);  if (s == -1)  {   perror ("fcntl");   return -1;  }  return 0; } //端口由參數(shù)argv[1]指定 int main (int argc, char *argv[]) {  int sfd, s;  int efd;  struct epoll_event event;  struct epoll_event *events;  if (argc != 2)  {   fprintf (stderr, "Usage: %s [port]/n", argv[0]);   exit (EXIT_FAILURE);  }  sfd = create_and_bind (argv[1]);  if (sfd == -1)  abort ();  s = make_socket_non_blocking (sfd);  if (s == -1)  abort ();  s = listen (sfd, SOMAXCONN);  if (s == -1)  {   perror ("listen");   abort ();  }  //除了參數(shù)size被忽略外,此函數(shù)和epoll_create完全相同  efd = epoll_create1 (0);  if (efd == -1)  {   perror ("epoll_create");   abort ();  }  event.data.fd = sfd;  event.events = EPOLLIN | EPOLLET;//讀入,邊緣觸發(fā)方式  s = epoll_ctl (efd, EPOLL_CTL_ADD, sfd, &event);  if (s == -1)  {   perror ("epoll_ctl");   abort ();  }  /* Buffer where events are returned */  events = calloc (MAXEVENTS, sizeof event);  /* The event loop */  while (1)  {   int n, i;   n = epoll_wait (efd, events, MAXEVENTS, -1);   for (i = 0; i < n; i++)   {    if ((events[i].events & EPOLLERR) ||     (events[i].events & EPOLLHUP) ||     (!(events[i].events & EPOLLIN)))    {     /* An error has occured on this fd, or the socket is not      ready for reading (why were we notified then?) */     fprintf (stderr, "epoll error/n");     close (events[i].data.fd);     continue;    }    else if (sfd == events[i].data.fd)    {     /* We have a notification on the listening socket, which      means one or more incoming connections. */     while (1)     {      struct sockaddr in_addr;      socklen_t in_len;      int infd;      char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];      in_len = sizeof in_addr;      infd = accept (sfd, &in_addr, &in_len);      if (infd == -1)      {       if ((errno == EAGAIN) ||        (errno == EWOULDBLOCK))       {        /* We have processed all incoming         connections. */        break;       }       else       {        perror ("accept");        break;       }      }          //將地址轉(zhuǎn)化為主機(jī)名或者服務(wù)名      s = getnameinfo (&in_addr, in_len,          hbuf, sizeof hbuf,          sbuf, sizeof sbuf,          NI_NUMERICHOST | NI_NUMERICSERV);//flag參數(shù):以數(shù)字名返回          //主機(jī)地址和服務(wù)地址      if (s == 0)      {       printf("Accepted connection on descriptor %d "         "(host=%s, port=%s)/n", infd, hbuf, sbuf);      }      /* Make the incoming socket non-blocking and add it to the       list of fds to monitor. */      s = make_socket_non_blocking (infd);      if (s == -1)      abort ();      event.data.fd = infd;      event.events = EPOLLIN | EPOLLET;      s = epoll_ctl (efd, EPOLL_CTL_ADD, infd, &event);      if (s == -1)      {       perror ("epoll_ctl");       abort ();      }     }     continue;    }    else    {     /* We have data on the fd waiting to be read. Read and      display it. We must read whatever data is available      completely, as we are running in edge-triggered mode      and won't get a notification again for the same      data. */     int done = 0;     while (1)     {      ssize_t count;      char buf[512];      count = read (events[i].data.fd, buf, sizeof(buf));      if (count == -1)      {       /* If errno == EAGAIN, that means we have read all        data. So go back to the main loop. */       if (errno != EAGAIN)       {        perror ("read");        done = 1;       }       break;      }      else if (count == 0)      {       /* End of file. The remote has closed the        connection. */       done = 1;       break;      }      /* Write the buffer to standard output */      s = write (1, buf, count);      if (s == -1)      {       perror ("write");       abort ();      }     }     if (done)     {      printf ("Closed connection on descriptor %d/n",        events[i].data.fd);      /* Closing the descriptor will make epoll remove it       from the set of descriptors which are monitored. */      close (events[i].data.fd);     }    }   }  }  free (events);  close (sfd);  return EXIT_SUCCESS; }

代碼編譯后,./epollTest 8888 ,在另外一個(gè)終端中執(zhí)行
telnet 192.168.1.161 8888 ,192.168.1.161為執(zhí)行測(cè)試程序的ip。在telnet終端敲入任何字符敲入Enter后,會(huì)在測(cè)試終端顯示敲入的字符。

總結(jié)

以上就是本文關(guān)于linux epoll機(jī)制詳解的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專題,如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
亚洲国产精品久久久男人的天堂| 欧美亚洲在线| 国产精品欧美一区二区三区奶水| 蜜桃色一区二区三区| 国产精品久久久久久久app| 2019日本中文字幕| 热re久久精品国产99热| 韩国在线视频一区| 激情 小说 亚洲 图片: 伦| b站大片免费直播| 91极品视频在线| 色综合一个色综合亚洲| gogo久久日韩裸体艺术| 不卡在线视频中文字幕| 久久久久久久久久久久久久久久久| 欧美国产在线视频| 国产乱码在线观看| 亚洲国产福利视频| 国产精品一区二区久久精品爱涩| 精品久久在线播放| 久久99精品国产自在现线| 免费av毛片在线看| 91麻豆福利| 日本伊人精品一区二区三区观看方式| 国产999精品| 丝袜熟女一区二区三区| 亚洲视频在线观看| 国产一区亚洲二区三区| 久久久噜噜噜| 暗呦丨小u女国产精品| 久久婷婷国产| 一区免费观看视频| 91精品综合久久久久久五月天| 成人av三级| 国产成人综合亚洲欧美在| 国产精品300页| 天堂av资源在线观看| 成年人影院在线观看| 黑人一区二区| 久久免费看毛片| 国产免费久久久| 亚洲成av人片在线观看无码| 51国偷自产一区二区三区的来源| 美女福利一区| 国产天堂av| 欧美日韩在线一区二区三区| 国产理论电影在线观看| 成人国产亚洲精品a区天堂华泰| a视频免费在线观看| 精品国产不卡一区二区| 久久你懂得1024| 怡红院红怡院欧美aⅴ怡春院| 久久激情中文| 秋霞网一区二区| 亚洲乱码一区| а天堂中文在线官网| 欧美日韩视频不卡| 亚洲免费二区| 亚洲伦理影院| 欧美另类高清videos| 一区二区三区四区五区在线| 黄色在线视频网站| 9久久婷婷国产综合精品性色| 国内福利写真片视频在线| 欧美+日本+国产+在线a∨观看| 久久久久成人网| 欧美日韩高清影院| 久久精品国产屋| 波多野结衣激情| 国内毛片毛片毛片毛片毛片| 制服诱惑亚洲| 最新版天堂资源在线| 亚洲熟女乱综合一区二区三区| 九九九伊在线综合永久| 久久先锋影音av鲁色资源网| caopor在线视频| 久久深夜福利免费观看| 欧美中文高清| 热久久久久久久| 日韩你懂的在线播放| 欧美一级片在线播放| 波多野结衣在线观看一区二区| 日韩欧美中文视频| 国产精品手机播放| 国内毛片毛片毛片毛片毛片| 色999日韩| 亚洲成人av| 国产精品videossex国产高清| 日韩欧美在线看| 久久亚洲国产中v天仙www| 久久综合伊人77777麻豆最新章节| 日本综合在线| 欧美艳星kaydenkross| 91麻豆产精品久久久久久夏晴子| 在线播放的av| 中文字幕av导航| 曰批又黄又爽免费视频| 成年人小视频在线观看| 九九九九九伊人| 亚洲第一免费网站| 国产婷婷色一区二区三区在线| 欧美成人国产| 久草视频国产在线| 91久久香蕉国产日韩欧美9色| 88在线观看91蜜桃国自产| 清纯唯美综合亚洲| 精品一区二区三区免费| xxxx日本免费| 尹人成人综合网| 亚洲一卡2卡三卡4卡2021四卡| 日韩一区二区在线视频| 蜜臀av性久久久久av蜜臀妖精| 欧美aaa大片视频一二区| 国产精品国产三级国产普通话蜜臀| 男女猛烈无遮挡午夜视频| 高清不卡亚洲| 九色porny极品| 青青草国产精品视频| 91精品国产乱码久久久久| 国产高清中文字幕在线| 中文av一区二区| 国产亚洲欧美日韩日本| 亚洲国产精品久久久久秋霞蜜臀| 99综合视频| 一本久久精品一区二区| 欧美在线不卡一区| 一区二区三区不卡视频| 曰韩不卡视频| 欧美成人aaaaⅴ片在线看| 中文字幕自拍偷拍| 国产91白丝在线播放| 亚洲精品视频三区| 日韩a∨精品日韩在线观看| 精品国产三区在线| 欧美亚洲日本一区| 日韩精品久久久久久久软件91| 黄a免费视频| 欧美人与物videos另类xxxxx| 成人av免费在线播放| 欧美一区二区三区在线电影| 欧美大尺度激情区在线播放| 外国成人直播| 亚洲熟妇无码av在线播放| 久久国产精品99国产精| 99热这里只有精品8| 免费观看黄一级视频| 国产精品久久婷婷| 成人公开免费视频| 国产一级特黄aaa大片| 婷婷伊人综合中文字幕| 麻豆美女网站| 视频一区二区三区国产| 久久精品国产99久久99久久久| 中国成人在线视频| 精品国产乱码久久久久久1区2匹| 在线观看亚洲大片短视频| 91丨九色丨蝌蚪富婆spa| 综合电影一区二区三区| 久久久久久久久91| 久久精品99久久香蕉国产色戒| 欧美成熟毛茸茸复古| 久久国产精品高清一区二区三区| 99久久婷婷国产精品综合| 日韩在线视频二区| 日本aⅴ精品一区二区三区| www.亚洲免费av| 伊人春色精品| 制服.丝袜.亚洲.中文.综合| 免费观看一级视频| 欧美午夜不卡影院在线观看完整版免费| 在线能看的av网址| 国产成人免费视频网站高清观看视频| 巨茎人妖videos另类| 美女视频a黄免费| 99热精品国产| 在线观看完整版免费| 波多结衣在线观看| 欧美怡春院一区二区三区| 国产爆乳无码一区二区麻豆| 丁香花免费高清完整在线播放| 国产无遮挡裸体免费久久| 国产va亚洲va在线va| 欧美一级电影网站| 欧美91看片特黄aaaa| 国产精品综合二区| 韩国免费在线视频| 婷婷亚洲图片| 午夜视频在线观看一区二区三区| 国产精品视频流白浆免费视频| 99久久免费观看| 精品97人妻无码中文永久在线| 欧美性xxxxhd| 中文字幕欧美视频| 亚洲欧美国产一本综合首页| 理论片大全免费理伦片| 香港三日本三级少妇66| 99久久久成人国产精品| 精品人伦一区二区三区| 欧美自拍小视频| 91久久久久久久| 欧美肥臀大乳一区二区免费视频| 国产精品久久久久久久天堂第1集| 国产精品人成在线观看免费| 日韩网站免费观看| 粉嫩精品一区二区三区在线观看| 久久久久久无码精品人妻一区二区| 黄色小视频在线免费看| 亚洲色图五月天| 欧美日韩高清不卡| 九九精品视频在线| 青青免费在线视频| 8888四色奇米在线观看| 国产最顶级的黄色片在线免费观看| 国产欧美日韩中文字幕| 成人在线观看网址| 亚洲卡通欧美制服中文| 免费看成人午夜电影| 久久久精品黄色| 亚洲高清福利| 亚洲清纯自拍| 图片区乱熟图片区亚洲| 欧美日韩中文字幕日韩欧美| 先锋影音在av资源看片| 国产综合视频在线观看| 亚洲精品永久免费精品| 草久在线视频| 国产福利在线观看视频| 久久视频国产| 91破解版在线观看| 午夜在线播放| 黄色在线播放| 神马久久久久久久久| 国产91九色蝌蚪| 久久国产精品亚洲人一区二区三区| 国产又粗又黄又猛| 美女国产精品久久久| 一区二区三区精品在线观看| 一本到12不卡视频在线dvd| 同性gay免费| 亚洲成色www.777999| 性欧美videosex高清少妇| 国产精品中文| 顶级网黄在线播放| 麻豆精品一区| 国产午夜免费福利| 奇米精品一区二区三区在线观看一| 99热6这里只有精品| 神马香蕉久久| 久久精品水蜜桃av综合天堂| 清纯唯美亚洲综合一区| 99视频只有精品| 精品伦精品一区二区三区视频密桃| 欧美日韩另类一区| h视频在线观看免费网站| 国产精品美女www爽爽爽| 婷婷中文字幕综合| 久久色免费在线视频| 婷婷六月国产精品久久不卡| 九色porny视频在线观看| 中文字幕色av一区二区三区| 日韩av自拍| 在线免费91| 免费一级suv好看的国产网站| 欧美亚洲精品日韩| 亚洲影院在线播放| 亚洲精品国产精品乱码| 亚洲欧洲性图库| 亚洲精品免费在线观看视频| 精品国自产拍在线观看| 亚洲另类激情图| 99精品视频在线观看免费播放| 国产日本精品| 色综合一区二区| 国产在线视频卡一卡二| 素人fc2av清纯18岁| 国产成a人亚洲精品| 久久手机视频| 性孕妇free特大另类| 在线观看污网站| 永久免费毛片在线播放不卡| 久久精品久久精品亚洲人| 春色校园综合激情亚洲| 精品久久久噜噜噜噜久久图片| 欧美日韩国产成人在线观看| 懂色av粉嫩av浪潮av| 国产欧美日韩专区| 精品国产二区三区| 国产一精品一av一免费爽爽| 亚洲第一福利社区| 国产精品美女视频网站| 久久国产亚洲精品无码| 中文av字幕在线观看| 日本少妇性高潮| 亚洲精品videosex极品| 青青青免费视频在线2| 日韩av电影中文字幕| 欧美一区二区.| 伊人久久久久久久久| 国产精品网红福利| 97超碰资源站在线观看| 成人免费一区二区三区视频| 经典三级一区二区三区视频| 亚洲精品无播放器在线播放| 不卡一区二区在线观看| 97超碰人人模人人爽人人看| 九九九在线观看视频| 成人免费在线观看视频网站| h版电影在线播放视频网站| 免费成人毛片| 国产三级电影在线| 亚洲午夜精品| 亚洲va久久久噜噜噜久久| 一插菊花综合| 久久久一区二区三区捆绑**| www.伊人久久| 久久性感美女视频| 不卡一区中文字幕| 亚洲 欧美 日韩在线| 91视频免费观看| 91手机视频在线| 国产精品男女| 亚洲国内精品视频| 四虎精品视频| 又黄又爽又色视频| 欧美成人女星排名| 亚洲在线视频播放| 精品美女一区二区三区| www一区二区|