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

在Linux環境下select函數的初體驗

運維 系統運維 Linux
在linux中, 主要的 IO復用方式中, 有epoll, poll 和select, 這次先來學習下select。select 能夠同時監視多個文件描述符的變法, 也支持超時返回。

[[184930]]

select介紹

在linux中, 主要的 IO復用方式中, 有epoll, poll 和select, 這次先來學習下select.

select 能夠同時監視多個文件描述符的變法, 也支持超時返回.

先來看下select函數的定義

  1. /* /usr/include/sys/select.h */ 
  2. extern int select (int __nfds,               // 最大文件描述符+1 
  3.            fd_set *__restrict __readfds,     // 讀狀態文件集 
  4.            fd_set *__restrict __writefds,    // 寫狀態文件集 
  5.            fd_set *__restrict __exceptfds,   // 異常狀態文件集 
  6.            struct timeval *__restrict __timeout);  // 超時時間  

如上圖函數聲明所示, 不管我們關注什么狀態, 我們都應該把同一類狀態的文件描述符存到同一個fd_set集合,以便select能夠相應的位置打上標簽, 以便后續我們來判斷該文件描述符是否已經準備好

這些傳遞給select函數的參數, 將告訴內核:

  • 我們需要監聽的文件描述符
  • 對于每個文件描述符, 我們所關心的狀態 (讀/寫/異常)
  • 我們要等待多長時間 (無限長/超時返回)

而內核也會通過select的返回, 告知我們一些信息:

  • 已經準備好的文件描述符個數
  • 那三種狀態分別是哪些文件描述符

我們可以通過以下方式將關注的文件描述符加入相應的文件集:

  1. int socket_test; 
  2. socket_test = socket(...);      //創建socket文件描述符 
  3. connent(socket_test,..);        //連接服務端 
  4. FD_SET(socket_test, &rdfds);    //加入讀狀態文件集 
  5. FD_SET(socket_test, &wdfds);    //加入寫狀態文件集 
  6. ....  

select原理

select函數執行順序是: SYSCALL_DEFINE5 (sys_select) -> core_sys_select -> do_select

我們都知道, select 支持監聽三個文件集: 讀文件集, 寫文件集, 異常文件集;

在我們調用FD_SET(socket_test, &rdfds)時, 實際上執行的操作是: 在rdfds成員數組中, 將__FDELT (d)位置的值 設成 __FDMASK (d), 直接說會有點疑惑, 先看下相關的函數,宏定義是怎樣定義的吧:

  1. /* 取自: /usr/include/sys/select.h */ 
  2. #define FD_SET(fd, fdsetp)  __FD_SET (fd, fdsetp) 
  3. typedef long int __fd_mask; 
  4.  
  5. /* 取自: /usr/include/bits/select.h  */ 
  6.  
  7. #define __NFDBITS   (8 * (int) sizeof (__fd_mask)) 
  8. #define __FDELT(d)  ((d) / __NFDBITS) 
  9. #define __FDMASK(d) ((__fd_mask) 1 << ((d) % __NFDBITS)) 
  10.  
  11. #define __FD_SET(d, set)    (__FDS_BITS (set)[__FDELT (d)] |= __FDMASK (d)) 
  12.  
  13. typedef struct 
  14.   { 
  15.     /* XPG4.2 requires this member name.  Otherwise avoid the name 
  16.        from the global namespace.  */ 
  17. #ifdef __USE_XOPEN 
  18.     __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS]; 
  19. # define __FDS_BITS(set) ((set)->fds_bits) 
  20. #else 
  21.     __fd_mask __fds_bits[__FD_SETSIZE / __NFDBITS]; 
  22. # define __FDS_BITS(set) ((set)->__fds_bits) 
  23. #endif 
  24.   } fd_set; 
  25.  
  26. /* /usr/include/linux/posix_types.h */ 
  27. #define __FD_SETSIZE    1024  

舉個栗子, 假設 fd=3, 當我們執行FD_SET(fd, &rdfds)時:

  1. 算出 __FDELT(d) 和 __FDMASK(d)的值, 通過上面的宏定義, 可以分別得出結果: 3/(8*8), 1<<3%(8*8), 也就是0 和 二進制的 0000 0100
  2. 然后分別將值存入 rdfds.__fds_bits第0個位置, 值為十進制的8
  3. 我們可以將__fds_bit的每個索引看成是一個聚合的過程, 每個值8字節, 也就是有64位, 可以存64個fd, 在我的系統上, 算出數組的長度是__FD_SETSIZE / __NFDBITS = 1024/8=128個, 也就是大概能容納 128*64=8192(如果理解錯誤請指出)

經過上面的運算, 我們將需要關注的文件描述關聯到 rdfds文件集了, 對于寫文件集, 異常文件集都是同樣的運算, 等這些步驟都進行完了, 接下來就是進入core_sys_select函數了:

  1. 執行到 core_sys_select 時, 定義一個fd_set_bits結構體: fds.
  2. 分別為fds的成員(in, out, ex, res_in, res_out, res_ex)申請內存
  3. 將我們傳給select的 rdfds, wrfds, exfds分別賦值給 in, out, ex, 這樣fds就能記錄三個集合的結果了
  4. 初始化那個三個成員之后, 將執行do_select(n, &fds, end_time)
  5. 在do_select中, 函數將進入死循環,其中還有兩個循環, 分別是針對 "最大文件描述符數" 和 fd_set_bits數組中單個值位數. 從上面我們已經知道, 在fd_set_bits每個值都代表所關注的文件描述符, 每個值是__NFDBITS(8 *8字節)大小,也就是64位, 所以在上面循環內, 還要再循環64次
  6. 看到這里其實大家都應該有個底了, 為什么要循環那么多次, 因為我們需要通過每個文件描述符對應的file_operations結構體的接口f_op->poll來得知是否已經準備好了

簡單介紹 file_operations

我們都知道,當我們打開一些設備或者文件時, 總是返回一個文件描述符, 其實通過這個文件描述符, 我們通過fget_light 來獲得對應的file結構體, 為什么還要反查這個file, 因為通過這個file結構體可以得到: file_operations結構體

file_operations結構體: 用來存儲驅動內核模塊提供的對 設備進行各種操作的函數的指針。該結構體的每個域都對應著驅動內核模塊用來處理某個被請求的 事務的函數的地址。

  1. /* linux-2.6.32/include/linux/fs.h */ 
  2. struct file_operations { 
  3.    ... 
  4.     unsigned int (*poll) (struct file *, struct poll_table_struct *);    // select通過這個來獲取狀態 
  5.    ...(其他接口忽略)  

do_select 循環體源碼:

  1. /* select.c/do_select() */ 
  2. for (;;) { 
  3.         unsigned long *rinp, *routp, *rexp, *inp, *outp, *exp; 
  4.  
  5.         inp = fds->in; outp = fds->out; exp = fds->ex; 
  6.         rinp = fds->res_in; routp = fds->res_out; rexp = fds->res_ex; 
  7.  
  8.         for (i = 0; i < n; ++rinp, ++routp, ++rexp) {       
  9.             unsigned long inout, ex, all_bits, bit = 1, mask, j; 
  10.             unsigned long res_in = 0, res_out = 0, res_ex = 0; 
  11.             const struct file_operations *f_op = NULL
  12.             struct file *file = NULL
  13.  
  14.             in = *inp++; out = *outp++; ex = *exp++; 
  15.             all_bits = in | out | ex; 
  16.             if (all_bits == 0) { 
  17.                 i += __NFDBITS; 
  18.                 continue
  19.             } 
  20.  
  21.             for (j = 0; j < __NFDBITS; ++j, ++i, bit <<= 1) {   // 遍歷64位 
  22.                 int fput_needed; 
  23.                 if (i >= n) 
  24.                     break; 
  25.                 if (!(bit & all_bits)) 
  26.                     continue
  27.  
  28.                 //在當前進程的struct files_struct中根據所謂的用戶空間文件描述符fd來獲取文件描述符 
  29.                 file = fget_light(i, &fput_needed);             
  30.                 if (file) { 
  31.                     f_op = file->f_op;          // file_operations結構體 
  32.                     mask = DEFAULT_POLLMASK; 
  33.                     if (f_op && f_op->poll) { 
  34.                         wait_key_set(wait, inoutbit); 
  35.                         mask = (*f_op->poll)(file, wait); 
  36.                     } 
  37.                     fput_light(file, fput_needed); 
  38.                     if ((mask & POLLIN_SET) && (in & bit)) {    //判斷讀狀態 
  39.                         res_in |= bit
  40.                         retval++; 
  41.                         wait = NULL
  42.                     } 
  43.                     if ((mask & POLLOUT_SET) && (out & bit)) {  //判斷寫狀態 
  44.                         res_out |= bit
  45.                         retval++; 
  46.                         wait = NULL
  47.                     } 
  48.                     if ((mask & POLLEX_SET) && (ex & bit)) {    //判斷異常狀態 
  49.                         res_ex |= bit
  50.                         retval++; 
  51.                         wait = NULL
  52.                     } 
  53.                 } 
  54.             } 
  55.             if (res_in) 
  56.                 *rinp = res_in; 
  57.             if (res_out) 
  58.                 *routp = res_out; 
  59.             if (res_ex) 
  60.                 *rexp = res_ex; 
  61.             cond_resched(); 
  62.         } 
  63.         wait = NULL
  64.         if (retval || timed_out || signal_pending(current)) 
  65.             break; 
  66.         if (table.error) { 
  67.             retval = table.error; 
  68.             break; 
  69.         } 
  70.  
  71.         /* 
  72.          * If this is the first loop and we have a timeout 
  73.          * given, then we convert to ktime_t and set the to 
  74.          * pointer to the expiry value. 
  75.          */ 
  76.         if (end_time && !to) { 
  77.             expire = timespec_to_ktime(*end_time); 
  78.             to = &expire; 
  79.         } 
  80.  
  81.         if (!poll_schedule_timeout(&table, TASK_INTERRUPTIBLE, 
  82.                        to, slack)) 
  83.             timed_out = 1; 
  84.     }  

當select經歷完上面的流程, 將會有以下結果:

  • >0: 準備好的文件描述符個數
  • 0: 超時
  • -1: 出錯或者接收到信號

那我們接下來要做的就是,

  • 通過行FD_ISSET()判斷之前綁定的文件fd, 如果為真, 則進行相應操作
  • 因為select返回后, 之前存好的rdfds, wdfds, exfds都會被清空, 所以需要用FD_SET()重新加入

select實戰

上面已經學習到關于select的相關知識, 那么我們應該要來實戰下:

這次我們需要實現的目標是:

一個程序, 同時連接3個socket_server, 并且將socket_server發送的消息打印出來(不需要響應, 也不需要交互)

程序代碼:

  1. /* filename: test_select.c */ 
  2.  
  3. #include <stdio.h> 
  4. #include <stdlib.h> 
  5. #include <sys/socket.h> 
  6. #include <sys/select.h> 
  7. #include <sys/types.h> 
  8. #include <netinet/in.h> 
  9. #include <unistd.h> 
  10. #include <fcntl.h> 
  11. void main() 
  12.     // socket1 
  13.     int socketd; 
  14.     char buffer[1025];  
  15.     struct sockaddr_in seraddr; 
  16.     socketd = socket(AF_INET, SOCK_STREAM, 0); 
  17.     seraddr.sin_family = AF_INET; 
  18.     seraddr.sin_port = htons(9997); 
  19.     inet_pton(AF_INET, "127.0.0.1", &seraddr.sin_addr); 
  20.     if (connect(socketd, (struct sockaddr *) &seraddr, sizeof(seraddr))<0) 
  21.     { 
  22.         printf("socketd1 connect failed\n"); 
  23.         exit(3); 
  24.     } 
  25.  
  26.     // socket2 
  27.     int socketd2; 
  28.     char buffer2[1025]; 
  29.     struct sockaddr_in seraddr2; 
  30.     socketd2 = socket(AF_INET, SOCK_STREAM, 0); 
  31.     seraddr2.sin_family = AF_INET; 
  32.     seraddr2.sin_port = htons(9998); 
  33.     inet_pton(AF_INET, "127.0.0.1", &seraddr2.sin_addr); 
  34.     if (connect(socketd2, (struct sockaddr *) &seraddr2, sizeof(seraddr))<0) 
  35.     { 
  36.         printf("socketd2 connect failed\n"); 
  37.         exit(3); 
  38.     } 
  39.  
  40.     // scoket3 
  41.     int socketd3; 
  42.     char buffer3[1025]; 
  43.     struct sockaddr_in seraddr3; 
  44.     socketd3 = socket(AF_INET, SOCK_STREAM, 0); 
  45.     seraddr3.sin_family = AF_INET; 
  46.     seraddr3.sin_port = htons(9999); 
  47.     inet_pton(AF_INET, "127.0.0.1", &seraddr3.sin_addr); 
  48.     if (connect(socketd3, (struct sockaddr *) &seraddr3, sizeof(seraddr))<0) 
  49.     { 
  50.         printf("socketd3 connect failed\n"); 
  51.         exit(3); 
  52.     } 
  53.  
  54.     int maxfdp;   
  55.     fd_set fds;                      // select需要的文件描述符集合  
  56.     maxfdp = socketd3 + 1;           // select 第一個形參就是打開的最大文件描述符+1 
  57.     struct timeval timeout = {3, 0}; // 超時設置 
  58.     while(1) 
  59.     { 
  60.         FD_ZERO(&fds);               // 初始化文件描述符集合 
  61.         FD_SET(socketd, &fds);       // 分別添加以上三個需要監聽的文件描述符 
  62.         FD_SET(socketd2, &fds); 
  63.         FD_SET(socketd3, &fds); 
  64.         select(maxfdp, &fds, NULLNULL, &timeout); 
  65.         // 通過FD_ISSET 來分別判斷 監聽的文件描述符在fds有沒有被設置成1 
  66.         if (FD_ISSET(socketd, &fds)) 
  67.         { 
  68.             read(socketd, buffer, 1024); 
  69.             printf("1 %s\n",buffer); 
  70.         } 
  71.         if(FD_ISSET(socketd2, &fds)) 
  72.         { 
  73.             read(socketd2, buffer2, 1024); 
  74.             printf("2 %s\n",buffer2); 
  75.              
  76.         } 
  77.         if(FD_ISSET(socketd3, &fds)) 
  78.         { 
  79.             read(socketd3, buffer3, 1024); 
  80.             printf("3 %s\n",buffer3); 
  81.              
  82.         } 
  83.     } 
  84.  

為了快速建立簡單的測試服務端, 所以用python實現簡單socket_server:

  1. # socket1.py 
  2.  
  3. import socket 
  4. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
  5. s.bind(('localhost', 9997)) 
  6. s.listen(2) 
  7. rint 'Socket1 is on ready!' 
  8. client, info = s.accept() 
  9. print info 
  10. while 1: 
  11.     message = raw_input('input: '
  12.     client.send(message) 
  13. s.close() 
  14.  
  15. ------------------------------- 
  16. # socket2.py 
  17.  
  18. import socket 
  19. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
  20. s.bind(('localhost', 9998)) 
  21. s.listen(2) 
  22. rint 'Socket2 is on ready!' 
  23. client, info = s.accept() 
  24. print info 
  25. while 1: 
  26.     message = raw_input('input: '
  27.     client.send(message) 
  28. s.close() 
  29.  
  30. ------------------------------- 
  31. # socket3.py 
  32.  
  33. import socket 
  34. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
  35. s.bind(('localhost', 9999)) 
  36. s.listen(2) 
  37. rint 'Socket3 is on ready!' 
  38. client, info = s.accept() 
  39. print info 
  40. while 1: 
  41.     message = raw_input('input: '
  42.     client.send(message) 
  43. s.close()  

分別運行 socket1.py, socket2.py, socket3.py將會看到如下結果:

  1. # 運行 socket1.py 
  2. [root@iZ23pynfq19Z ~]# python socket1.py  
  3. Socket1 is on ready! 
  4.  
  5. ---------------------- 
  6. # 運行 socket1.py 
  7. [root@iZ23pynfq19Z ~]# python socket2.py  
  8. Socket2 is on ready! 
  9.  
  10. ---------------------- 
  11. # 運行 socket1.py 
  12. [root@iZ23pynfq19Z ~]# python socket3.py  
  13. Socket3 is on ready!  

當我們編譯 test_select.c 并運行時, 將會看到三個服務端都出現了相應的響應:

  1. # 運行 socket1.py 
  2. [root@iZ23pynfq19Z ~]# python socket1.py  
  3. Socket1 is on ready! 
  4. ('127.0.0.1', 55951)  # 客戶端連接的信息, 端口不一定相同 
  5. input: 
  6.  
  7. ---------------------- 
  8. # 運行 socket1.py 
  9. [root@iZ23pynfq19Z ~]# python socket2.py  
  10. Socket2 is on ready! 
  11. ('127.0.0.1', 55921) 
  12. input: 
  13.  
  14. ---------------------- 
  15. # 運行 socket1.py 
  16. [root@iZ23pynfq19Z ~]# python socket3.py  
  17. Socket3 is on ready! 
  18. ('127.0.0.1', 55933) 
  19. input:  

那么我們來嘗試三個服務端分別發送消息到select程序吧:

  1. # socket1.py 
  2. [root@iZ23pynfq19Z ~]# python socket1.py  
  3. Socket1 is on ready! 
  4. ('127.0.0.1', 55951)  # 客戶端連接的信息, 端口不一定相同 
  5. input: asd 
  6. input: qwe 
  7. input: as 
  8. input:  
  9. ---------------------- 
  10. # socket1.py 
  11. [root@iZ23pynfq19Z ~]# python socket2.py  
  12. Socket2 is on ready! 
  13. ('127.0.0.1', 55921) 
  14. input: asd 
  15. input: asd 
  16. input: asd 
  17. input: as 
  18. input: s 
  19. input:  
  20.  
  21. ---------------------- 
  22. # socket1.py 
  23. [root@iZ23pynfq19Z ~]# python socket3.py  
  24. Socket3 is on ready! 
  25. ('127.0.0.1', 55933) 
  26. input: asd 
  27. input: qwe 
  28. input: a 
  29. input:   

將看到select程序都能輸出三個socket_server發出的消息:

 

 

 

 

需要注意的是:

  • 前面的數字是socket_server的編號, 因為server發送消息的順序是亂的, 所以輸出的編號也是亂的
  • 這次只為驗證select, 所以并沒對程序的健壯性作較好的設計, 所以如果服務端/客戶端刷屏了, 直接ctrl-c終止吧

經過上述的實驗, 我們應該能夠簡單的了解select的用法和效果, 通過select實現IO多路復用, 可以讓我們一定程度上避免多線程/多進程的繁瑣, 在我們日常工作上, 有必要的話嘗試這種方式也不失一種偷懶的方法. 

責任編輯:龐桂玉 來源: Lin_R的博客
相關推薦

2011-06-20 14:58:53

QT BasicExcel

2010-03-23 15:24:45

Linux shell

2013-12-12 11:33:31

iOS 7API

2009-02-16 17:10:17

OpenSolarisLinux 挑戰

2009-08-01 09:06:35

UbuntuOneLinux開源操作系統

2009-03-09 15:12:39

XenServer安裝

2023-07-15 08:01:38

2010-09-17 11:01:05

Java運行環境

2010-11-22 10:31:17

Sencha touc

2011-05-30 15:12:10

App Invento 初體驗

2010-06-28 15:38:01

MeeGo

2010-04-09 13:44:38

Ubuntu 10.0

2010-03-11 10:26:15

Ubuntu的初體驗

2011-01-14 11:27:02

Linux制作網頁

2013-06-08 10:15:29

Outlook 201Outlook 201

2011-11-01 10:30:36

Node.js

2010-12-13 11:39:39

2011-08-02 10:26:59

iOS 多線程 線程

2011-09-15 15:03:10

2025-03-18 07:30:41

點贊
收藏

51CTO技術棧公眾號

性欧美lx╳lx╳| 人人超在线公开视频| 日本美女视频一区二区| 日韩亚洲欧美成人| 99九九精品视频| 91超碰在线免费| 亚洲国产精品ⅴa在线观看| 91久久偷偷做嫩草影院| 国产成人无码av| 中文字幕亚洲综合久久五月天色无吗''| 精品999在线播放| 亚洲无吗一区二区三区| ririsao久久精品一区| 中文字幕欧美激情一区| 国产一区免费在线| 91精品国产乱码久久久久| 在线精品福利| 美女av一区二区| 亚洲色成人网站www永久四虎| 精品国产欧美| 日本久久电影网| 精品国偷自产一区二区三区| 香蕉视频在线播放| 91日韩一区二区三区| 2022国产精品| 亚洲天堂网视频| 久久精品亚洲| 91av网站在线播放| 久久久久久久久久久97| 四虎8848精品成人免费网站| 亚洲毛片在线免费观看| 精品国产乱码久久久久夜深人妻| 日日夜夜一区| 欧美主播一区二区三区| www.中文字幕在线| 欧美xxxx做受欧美88bbw| 国产精品福利一区| 日韩aⅴ视频一区二区三区| 天堂中文字幕av| 国产v综合v亚洲欧| 91亚洲精品丁香在线观看| 国产精品毛片一区二区在线看舒淇 | 日韩午夜激情| 久久久久久国产三级电影| 91精品国产闺蜜国产在线闺蜜| 精品免费视频| 在线播放日韩专区| 日韩精品无码一区二区三区久久久 | 人妖欧美1区| 夜夜操天天操亚洲| 女女同性女同一区二区三区按摩| 瑟瑟视频在线| 亚洲欧洲国产专区| 一级黄色片播放| 色女人在线视频| 亚洲观看高清完整版在线观看 | 三级福利片在线观看| 亚洲精品视频在线看| 日本一区二区三区四区五区六区| 九七久久人人| 亚洲精选免费视频| 菠萝蜜视频在线观看入口| 免费在线观看的电影网站| 一区二区三区在线视频播放| 日本久久久网站| 超碰97免费在线| 亚洲成人自拍一区| 国内自拍在线观看| 激情亚洲影院在线观看| 欧洲在线/亚洲| 国产成人美女视频| 色悠久久久久综合先锋影音下载| 精品999在线播放| 97伦伦午夜电影理伦片| 成人一区而且| 久久亚洲私人国产精品va| 久久老司机精品视频| 亚洲日本久久| 国产精品美女av| 中文字幕av网站| 国产成人综合自拍| 久久精品日产第一区二区三区| 国产精品影院在线| 亚洲女厕所小便bbb| 国产原创中文在线观看 | 欧美日韩亚洲一区二区| 成人在线免费播放视频| 在线成人免费| 日韩精品一区二区三区在线观看 | 国产精品色哟哟网站| 97超碰人人爱| 亚洲美女久久精品| 正在播放亚洲一区| 最新在线黄色网址| 国产精品二区不卡| 欧美一级免费视频| 国产精品伦理一区| 久久久99免费| 欧美一级爱爱视频| 亚洲精品一级二级| 日韩欧美电影一二三| 美女被到爽高潮视频| 欧美人成在线| 国产三级精品网站| 人人九九精品| 亚洲精品国产无套在线观| 麻豆av免费在线| 一区二区三区高清在线观看| 亚洲最大在线视频| 91精品国产乱码久久久张津瑜| 美女www一区二区| 欧美精品123| 激情在线视频播放| 欧美日韩国产在线观看| www.88av| 亚洲无线视频| 亚洲va欧美va国产综合剧情| 国产视频精选在线| 精品久久在线播放| 一级全黄裸体片| 91九色精品| 国产精品网址在线| 欧美欧美欧美| 婷婷成人综合网| 国产精品91av| 一区二区国产在线| 国产裸体写真av一区二区 | 欧美日韩国产91| 国产又粗又猛又爽又黄的视频一| 久久精品男人天堂av| heyzo亚洲| 国产香蕉精品| 久久久亚洲国产| 粉嫩av一区二区夜夜嗨| 亚洲三级电影全部在线观看高清| 8x8x最新地址| 成人情趣视频| 国产精品老牛影院在线观看| 高清美女视频一区| 在线看日韩精品电影| 97人妻精品一区二区免费| 一本色道久久综合亚洲精品高清| 成人3d动漫一区二区三区91| 日本片在线观看| 精品久久久三级丝袜| 国产一级免费av| jiyouzz国产精品久久| 成人性免费视频| 国产精品色在线网站| 久久久亚洲影院| 农村少妇久久久久久久| 精品久久久国产| 五级黄高潮片90分钟视频| 亚洲制服少妇| 日韩中文字幕一区| av久久网站| 久久精品国亚洲| 国产福利资源在线| 亚洲成人综合在线| 一本色道久久综合亚洲精品图片 | 一区二区三区蜜桃| 亚洲图片欧美另类| 国产亚洲精品v| 日韩欧美电影一区二区| 精品久久久网| 欧美人成在线视频| 午夜福利理论片在线观看| 色香色香欲天天天影视综合网| 日本性高潮视频| 精品一区免费av| 国产又粗又猛又爽又黄的网站 | 亚洲福利视频网站| 天堂а√在线中文在线新版| 欧美国产欧美亚州国产日韩mv天天看完整 | 羞羞网站在线免费观看| 精品国产乱码久久久久久1区2区| 日韩少妇裸体做爰视频| 久久精品日产第一区二区三区高清版| 久久久精品麻豆| 欧美精品成人| 女同一区二区| 精品视频成人| 日本国产一区二区三区| 黄色网址在线免费观看| 亚洲国产成人精品一区二区 | 日韩视频永久免费| 久久久久久久黄色片| 国产精品久久久久影院亚瑟| 精品人妻在线视频| 久久一区二区三区超碰国产精品| 这里只有精品66| 美腿丝袜亚洲图片| 国产免费观看久久黄| 91九色美女在线视频| www亚洲精品| 黄色一级大片在线免费看国产一 | 日本少妇一区二区三区| 午夜影院日韩| 免费极品av一视觉盛宴| 日韩成人激情| 鲁丝片一区二区三区| 精品一区二区三区视频在线播放 | 久久女同精品一区二区| 人妻精品久久久久中文字幕69| 国产日韩欧美| 可以在线看黄的网站| 激情五月色综合国产精品| 国产精华一区| www.久久爱.com| 国产精品第一第二| 国产精品电影| 欧美黑人xxxx| 黄网站在线免费| 伊人久久综合97精品| 婷婷av一区二区三区| 欧美一区二区三区在线视频| 黄色污污视频软件| 午夜电影一区二区| 久久久久久久久久网站| 国产精品你懂的在线| 国产熟妇搡bbbb搡bbbb| 成人高清av在线| 亚洲熟女一区二区三区| 国产一区二区三区四| 亚洲国产高清av| 久久综合图片| 97av视频在线观看| 在线综合视频| 草b视频在线观看| 亚洲午夜久久久久久尤物 | 欧美videos另类精品| 久久精品2019中文字幕| 91在线观看| 中文字幕在线日韩 | 国产成人精品一区二区无码呦| 欧美性猛片aaaaaaa做受| 黄色一级视频免费看| 欧美视频免费在线观看| 成年人视频在线免费看| 精品久久久香蕉免费精品视频| 亚洲国产精一区二区三区性色| 一区二区欧美在线观看| 精品99在线观看| 又紧又大又爽精品一区二区| 国产精品白嫩白嫩大学美女| 亚洲男同1069视频| 草视频在线观看| 亚洲一区中文日韩| 国产无套在线观看| 精品久久久视频| 亚洲另类在线观看| 在线视频一区二区三区| 免费看av在线| 欧美日本韩国一区二区三区视频| 中文字幕一区二区免费| 欧美久久久久久久久久 | 日韩成人在线视频| 亚洲欧美丝袜中文综合| 亚洲欧美精品一区| 成人动漫在线播放| 色狠狠久久aa北条麻妃| 久久精品视频观看| 精品中文字幕在线观看| 91破解版在线观看| 日本精品久久久久影院| 91伊人久久| 亚洲japanese制服美女| 成人线上播放| 免费久久一级欧美特大黄| 不卡一区2区| 精品国产一区二区三区在线| 亚洲精品男同| 91在线视频观看免费| 国产综合久久久久久久久久久久 | 粉嫩久久久久久久极品| 欧美不卡在线一区二区三区| 久久人人99| 国产午夜大地久久| 日本aⅴ免费视频一区二区三区| 99久久99精品| 99国产欧美久久久精品| 男人舔女人下部高潮全视频| 亚洲蜜臀av乱码久久精品| 日韩网红少妇无码视频香港| 欧美在线|欧美| 亚洲成人一二三区| 亚洲片国产一区一级在线观看| 免费在线你懂的| **欧美日韩vr在线| 91麻豆精品| 欧美性色黄大片人与善| 欧美激情aⅴ一区二区三区| 那种视频在线观看| 国产一区二区免费在线| 中文字幕 自拍| 亚洲激情图片一区| 久久久久久无码午夜精品直播| 久久精品一区二区三区中文字幕| 无码精品国产一区二区三区免费| 国内精品视频一区二区三区八戒| 国产二级一片内射视频播放 | 国产一区在线观看视频| 成人手机在线免费视频| 自拍偷在线精品自拍偷无码专区| 日韩精品国产一区二区| 777xxx欧美| 黄色在线免费观看大全| 欧美激情在线播放| 日韩黄色在线| 欧美自拍资源在线| 亚洲人妖在线| 男人女人拔萝卜视频| 国产清纯美女被跳蛋高潮一区二区久久w| 91视频综合网| 色视频一区二区| 视频一区 中文字幕| 欧美另类69精品久久久久9999| 视频一区在线免费看| 精品无人区一区二区三区| 你懂的亚洲视频| 午夜免费看视频| 亚洲国产精品成人久久综合一区| 国产精品午夜影院| 精品国免费一区二区三区| а√天堂8资源在线官网| 国产精品视频网| 免费av一区二区三区四区| 鲁一鲁一鲁一鲁一色| youjizz久久| 中文字幕一区二区三区手机版| 欧美成人一级视频| av电影免费在线观看| 成人在线一区二区| 久久久久久免费视频| av在线网址导航| 国产精品第13页| 亚洲一区二区视频在线播放| 一区二区三区视频免费在线观看| 在线成人av观看| 欧美激情视频一区二区三区| 久久久精品日韩| 波多野在线播放| 在线观看成人小视频| av大片在线播放| 国产美女久久精品| 伊人情人综合网| 亚洲天堂小视频| 亚洲一区二区三区中文字幕在线| www.国产精品视频| 欧美精品电影在线| 国产精品白丝av嫩草影院| 久久久久久久久久久99| 99re这里只有精品6| 特级西西444www大精品视频免费看| 日韩成人激情视频| 美女100%一区| 亚洲精品一区二区三区av| 经典三级在线一区| 人妻少妇精品一区二区三区| 精品国产一区二区亚洲人成毛片| 国产第一页在线视频| 精品国产乱码久久久久久108| 先锋a资源在线看亚洲| 黄大色黄女片18免费| 日韩一区二区免费在线观看| bl在线肉h视频大尺度| 麻豆av福利av久久av| 日本不卡一区二区三区高清视频| 日韩在线观看免| 欧美精品一区二区三区很污很色的| 国产在线观看www| 亚洲二区三区四区| 国产精品一区二区三区乱码| 日本一区二区不卡在线| 亚洲视屏在线播放| 成人亚洲精品| 一二三四视频社区在线| 国产亚洲女人久久久久毛片| 国产色片在线观看| 97人洗澡人人免费公开视频碰碰碰| 国产尤物久久久| 日韩av影视大全| 色94色欧美sute亚洲13| 怡红院红怡院欧美aⅴ怡春院| 久久精品国产精品青草色艺| 久久 天天综合| 日本黄色片视频| www欧美日韩| 日韩美女精品| 手机在线国产视频| 丰满岳妇乱一区二区三区| 男人资源在线播放| 久久久7777| 国产精品亚洲视频| 黄色一级视频免费看| 欧美极品美女视频网站在线观看免费 | 91麻豆精品91久久久久久清纯| av资源中文在线天堂| 亚洲第一页在线视频| 久久综合久色欧美综合狠狠|