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

首頁 > 學院 > 操作系統 > 正文

高級I/O之STREAMS

2024-06-28 13:28:00
字體:
來源:轉載
供稿:網友
高級I/O之STREAMS

http://en.wikipedia.org/wiki/STREAMS

STREAMS(流)是系統V提供的構造內核設備驅動程序和網絡協議包的一種通用方法,對STREAMS進行討論的目的是為了理解系統V的終端接口、I/O多路轉接中poll(輪詢)函數的使用 以及基于STREAMS的管道和命名管道的實現。

請注意不要將這里說明的STREAMS(流)與標準I/O庫(http://www.CUOXin.com/nufangrensheng/p/3505254.html)中使用的流(stream)相混淆。流機制是由Dennis Ritchie開發的,其目的是用通用、靈活的方法改寫傳統的字符I/O系統(c-list)并與網絡協議相適應,后來稍加增強,名稱改用大寫字母,成為STREAMS機制,被加入到SVR3。在linux中,STREAMS子系統是可用的,但是用戶必須自行將該子系統安裝到系統中,通常它默認為不包括在系統中。

流在用戶進程和設備驅動程序之間提供了一條全雙工通路。流無需和實際硬件設備直接會話,流也可以用來構造偽設備驅動程序。圖14-5示出了包含一個處理模塊的流。各方框之間用兩根帶箭頭的線連接,以突出流的全雙工特征,并強調兩個方向的處理是相互獨立進行的。

index images

圖14-4 一個簡單的流 圖14-5 具有處理模塊的流

任意數量的處理模塊可以壓入流。我們使用術語壓入,是因為每一新模塊總是插入到流首之下,而將以前的模塊下壓。(這類似于后進先出的棧。)圖14-5標出來流的兩側,分別稱為順流(downstream)和逆流(upstream)。寫到流首的數據將順流而下傳送,由設備驅動程序讀到的數據則逆流而上傳送。

STREAMS模塊是作為內核的一部分執行的,這類似于設備驅動程序。當構造內核時,STREAMS模塊聯編進入內核。如果系統支持動態可裝入的內核模塊(Linux和Solaris是這樣做的),則我們可以試圖將沒有聯編進內核的STREAMS模塊壓入一個流;但不保證STREAMS模塊和驅動程序的任意組合將能正常工作。

用文件I/O中說明的函數訪問流,它們是:open、close、read、write和ioctl。另外,在SVR3內核中增加了3個支持流的新函數(getmsg、putmsg和poll),在SVR4中又加了兩個處理流內不同優先級波段消息的函數(getpmsg和putpmsg)。

打開(open)流時使用的路徑名參數通常在/dev目錄之下。僅僅用ls -l查看設備名,不能判斷該設備是不是STREAMS設備。所有STREAMS設備都是字符特殊文件。

雖然某些有關STREAMS的文獻暗示我們可以編寫處理模塊,并且不加細究地就可將它們壓入流中,但是編寫這些模塊如果編寫設備驅動程序一樣,需要專門的技術。通常只有特殊的應用程序或函數才壓入和彈出STREAMS模塊。

1、STREAMS消息

STREAMS的所有輸入和輸出都基于消息。流首和用戶進程使用read、write、ioctl、getmsg、getpmsg、putmsg和putpmsg交換消息。在流首、各處理模塊和設備驅動程序之間,消息可以順流而下,也可以逆流而上。

在用戶進程和流首之間,消息由下列幾部分組成:消息類型、可選擇的控制信息以及可選擇的數據。表14-4列出了對應于write、putmsg和putpmsg的不同參數所產生的不同消息類型??刂菩畔⒑蛿祿蓅trbuf結構指定:

struct strbuf{    int    maxlen;    /* size of buffer */    int    len;       /* number of bytes currently in buffer */    char   *buf;      /* pointer to buffer */};

2697937651789066508

注:n/aN/A是英語“不適用”(Not applicable)等類似單詞的縮寫,??稍诟鞣N表格中看到。N/A比較多用在填寫表格的時候,表示“本欄目(對我)不適用”。在沒有東西可填寫,但空格也不允許此項留白的時候,可以寫N/A。在英語國家,也會用n/a或者n.a.來表達,都是同一個意思。

當用putmsg或putpmsg發送消息時,len指定緩沖區中數據的字節數。當用getmsg或getpmsg接收消息時,maxlen指定緩沖區長度(使內核不會溢出緩沖區),而len則由內核設置為存放在緩沖區中的數據量。消息長度為0是允許的,len為-1說明沒有控制信息或數據。

為什么需要傳送控制信息和數據兩者呢?提供這兩者使我們可以實現用戶進程和流之間的服務接口??赡茏顬槿肆私獾姆战涌谑窍到yV的傳輸層接口(Transport Layer Interface,TLI),它提供了網絡系統接口。

控制信息的另一個例子是發送一個無連接的網絡消息(數據報)。為了發送該消息,需要說明消息的內容(數據)和該消息的目的地址(控制消息)。如果不能將數據和控制一起發送,那么就要某種專門設計的方案。例如,可以用ioctl說明地址,然后用write發送數據。另一種技術可能要求地址占用數據的前N個字節,而數據是write寫的。將控制信息與數據分開,并且提供處理兩者的函數(putmsg和getmsg)是處理這種問題的比較清晰的方法。

有約25種不同類型的消息,但是只有少數幾種用于用戶進程和流首之間,其余的只在內核中順流、逆流傳送。(對于編寫流處理模塊的人員而言,這些消息是非常有用的,但是對編寫用戶級代碼的人員而言,它們可以忽略。)在我們所使用的函數(read、write、getmsg、getpmsg、putmsg和putpmsg)中,只涉及三種消息類型,它們是:

  • M_DATA (I/O的用戶數據)。
  • M_PROTO (協議控制信息)。
  • M_PCPROTO (高優先級協議控制信息)。

流中的消息都有一個排隊優先級:

  • 高優先級消息(最高優先級)。
  • 優先級波段消息。
  • 普通消息(最低優先級)。

普通消息是優先級波段為0的消息。優先級波段消息的波段可在1-255之間,波段愈高,優先級也愈高。高優先級消息的特殊性在于,在任何時候流首只有一個高優先級消息排隊。在流首讀隊列已有一個高優先級消息時,另外的高優先級消息會被丟棄。

每個STREAMS模塊有兩個輸入隊列。一個接收來自它上面模塊的消息,這種消息從流首向驅動程序順序傳送。另一個接收來自它下面模塊的消息,這種消息從驅動程序向流首逆流傳送。在輸入隊列中的消息按優先級從高到低排列。

2、putmsg和putpmsg函數

putmsg和putpmsg函數用于將STREAMS消息(控制信息或數據,或兩者)寫至流中。這兩個函數的區別是后者允許對消息指定一個優先級波段。

#include <stropts.h>int putmsg(int filedes, const struct strbuf *ctlptr,          const struct strbuf *dataptr, int flag);int putpmsg(int filedes, const struct strbuf *ctlptr,           const struct strbuf *dataptr, int band, int flag);兩個函數返回值:若成功則返回0,若出錯則返回-1

對流也可以使用write函數,它等效于不帶任何控制信息、flag為0的putmsg。

這兩個函數可以產生三種不同優先級的消息:普通、優先級波段和高優先級。表14-4詳細列出了這兩個函數中幾個參數的各種可能組合,以及所產生的不同類型的消息。

在表14-4中,N/A表示不適用。消息控制列中的“否”對應于空ctlptr參數,或ctlptr->len為-1。該列中的“是”對應于ctlptr非空,以及ctlptr->len大于等于0。這些說明同樣適用于消息的數據部分(用dataptr代替ctlptr)。

3、STREAMS ioctl操作

http://www.CUOXin.com/nufangrensheng/p/3500358.html中曾提到過ioctl函數,它能做其他I/O函數不處理的事情。STREAMS系統繼承了這種傳統。

在Linux和Solaris中,使用ioctl可對流執行將近40種不同的操作。頭文件<stropts.h>應包括在使用這些操作的C代碼中。ioctl的第二個參數request說明執行哪一個操作。對流執行操作的所有request都以 I_ 開始。第三個參數的作用與request有關,有時它是一個整型值,有時它是一個指向一個整型或一個數據結構的指針。

實例:isastream函數

有時需要判斷一個描述符是否引用一個流。這與調用isatty函數來判斷一個描述符是否引用一個終端設備相類似(見終端I/O之終端標識)。Linux和Solaris為此提供了isastream函數。

#include <stropts.h>int isastream(int filedes);返回值:若為STREAMS設備則返回1,否則返回0

與isatty類似,它通常是用一個只對STREAMS設備才有效的ioctl函數來進行測試的。程序清單14-7是該函數的一種可能的實現。它使用I_CANPUT ioctl來測試由第三個參數說明的優先級波段(本實例中為0)是否可寫。如果該ioctl執行成功,則它對所涉及的流并未作任何改變。

程序清單14-7 檢查描述符是否引用STREAMS設備

#include <stropts.h>#include <unistd.h>intisastream(int fd){    return(ioctl(fd, I_CANPUT, 0) != -1);}

程序清單14-8可用于測試此函數。

程序清單14-8 測試isastream函數

#include "apue.h"#include <fcntl.h>int main(int argc, char *argv[]){    int    i, fd;    for(i=1; i<argc; i++)    {        if((fd = open(argv[i], O_RDONLY)) < 0)        {            err_ret("%s: can't open", argv[i]);            continue;        }                if(isastream(fd) == 0)            err_ret("%s: not a stream", argv[i]);        else            err_msg("%s: streams device", argv[i]);    }    exit(0);}

實例

如果ioctl的參數request是I_LIST,則系統返回已壓入該流所有模塊的名字,包括最頂端的驅動程序(指明最頂端的原因是,在多路轉接驅動程序的情況下,有多個驅動程序)。其第三個參數應當是指向str_list結構的指針。

struct str_list{    int                 sl_nmods;        /* number of entries in array */    struct str_mlist    *sl_modlist;     /* ptr to first element of array */};

應將sl_modlist設置為指向str_mlist結構數組的第一個元素,將sl_nmods設置為該數組中的項數:

struct str_mlist{    char    l_name[FMNAMESZ+1];    /* null-terminated module name */};

常量FMNAMESZ在頭文件<sys/conf.h>中定義,其值常常是8。l_name的實際長度是FMNAMESZ+1,增加1個字節是為了存放null終止符。

如果ioctl的第三個參數是0,則該函數返回值是模塊數,而不是模塊名。我們將先用這種ioctl調用確定模塊數,然后再分配所要求的str_mlist結構數。

程序清單14-9例示了I_LIST操作。由ioctl返回的名字列表并不對模塊和驅動程序進行區分,但是考慮到該列表的最后一項是處于流底的驅動程序,所以在打印時將其表明為驅動程序。

程序清單14-9 列表流中的模塊名

#include "apue.h"#include <fcntl.h>#include <stropts.h>intmain(int argc, char *argv[]){    int        fd, i, nmods;    struct str_list list;        if(argc != 2)        err_quit("usage: %s <pathname>", argv[0]);    if((fd = open(argv[1], O_RDONLY)) < 0)        err_sys("can't open %s", argv[1]);    if(isastream(fd) == 0)        err_quit("%s is not a stream", argv[1]);    /*    * Fetch number of modules.    */    if((nmods = ioctl(fd, I_LIST, (void *) 0)) < 0)        err_sys("I_LIST error for nmods");    printf("#modules = %d/n", nmods);    /*    * Allocate storage for all the module names.    */    list.sl_modlist = calloc(nmods, sizeof(struct str_mlist));    if(list.sl_modlist == NULL)        err_sys("calloc error");    list.sl_nmods = nmods;    /*    * Fetch the module names.    */    if(ioctl(fd, I_LIST, &list) < 0)        err_sys("I_LIST error for list");    /*    * Print the names.    */    for(i=1; i<=nmods; i++)        printf(" %s: %s/n", (i == nmods) ? "driver" : "module",             list.sl_modlist++->l_name);    exit(0);}

4、寫(write)至STREAMS設備

在表14-4中可以看到寫至STREAMS設備產生一個M_DATA消息。一般情況確實如此,但是也還有一些細節需要考慮。首先,流中最頂部的一個處理模塊規定了可順流傳送的最小、最大數據報長度(無法查詢該模塊中規定的這些值)。如果寫的數據長度超過最大值,則流首將這一數據按最大長度分解成若干數據包。最后一個數據包的長度可能不到最大值。

接著要考慮的是:如果向流寫0個字節,又將如何呢?除非流引用管道或FIFO,否則就順流發送0長度消息。對于管道和FIFO,為與以前版本兼容,系統的默認處理方式是忽略0長度write。可以用ioctl設置管道和FIFO流的寫模式,從而更改這種默認處理方式。

5、寫模式

可以用兩個ioctl命令取得和設置一個流的寫模式。如果將request設置為I_GWROPT,第三個參數設置為指向一個整型變量的指針,則該流的當前寫模式在該整型量中返回。如果將request設置為I_SWROPT,第三個參數是一個整型值,則其值成為該流新的寫模式。如同處理文件描述符標志和文件狀態標志(見http://www.CUOXin.com/nufangrensheng/p/3500350.html)一樣,總是應當先取當前寫模式值,然后修改它,而不只是將寫模式設置為某個絕對值(很可能會關閉某些原來打開的位)。

目前,只定義了兩個寫模式值。

SNDZERO 對管道和FIFO的0長度write會造成順流傳送一個0長度消息。按系統默認,0長度寫不發送消息。

SNDPIPE 在流上已出錯后,若調用write或putmsg,則向調用進程發送SIGPIPE信號。

流也有讀模式,我們先說明getmsg和getpmsg函數,然后再說明讀模式。

6、getmsg和getpmsg函數

使用read、getmsg或getpmsg函數從流首讀STREAMS消息。

#incldue <stropts.h>int getmsg(int filedes, struct strbuf *restrict ctlptr,           struct strbuf *restrict dataptr, int *restrict flagptr);int getpmsg(int filedes, struct strbuf *restrict ctlptr,           struct strbuf *restrict dataptr, int *restrict bandptr,           int *restrict flagptr);兩個函數返回值:若成功則返回非負值,若出錯則返回-1

注意,flagptr和bandptr是指向整型的指針。在調用之前,這兩個指針所指向的整型單元中應設置成所希望的消息類型;在返回時,此整型量設置為所讀到的消息的類型。

如果flagptr指向的整型單元的值是0,則getmsg返回流首讀隊列中的下一個消息。如果下一個消息是高優先級消息,則在返回時,flagptr所指向的整型單元設置為RS_HIPRI。如果希望只接收高優先級消息,則在調用getmsg之前必須將flagptr所指向的整型單元設置為RS_HIPRI。

getpmsg使用一個不同的常量集。為了只接收高優先級消息,我們可以將flagptr指向的整型單元設置為MSG_HIPRI。為了只接收某個優先級波段或以上波段(包括高優先級消息)的消息,我們可將該整型單元設置為MSG_BAND,然后將bandptr指向的整型單元設置為該波段的非0優先級值。如果只希望接收第1個可用消息,則可將flagptr指向的整型單元設置為MSG_ANY;在返回時,該整型值將改寫為MSG_HIPRI或MSG_BAND,這取決于接收到的消息的類型。如果取到的消息并非高優先級消息,那么bandptr指向的整型將包括消息的優先級波段值。

如果ctlptr是null,或ctlptr->maxlen是-1,那么消息的控制部分仍保留在流首讀隊列中,我們將不處理它。類似地,如果dataptr是null,或者dataptr->maxlen是-1,那么消息的數據部分仍保留在流首讀隊列中,我們也不處理它。否則,將按照緩沖區的容量取到消息中盡可能多的控制和數據部分,余下部分仍留在隊首,等待下次取用。

如果getmsg和getpmsg調用取到一消息,那么返回值是0。如果消息控制部分中有一些余留在流首讀隊列中,那么返回常量MORECTL。類似地,如果消息數據中有一些余留在流首讀隊列中,那么返回常量MOREDATA。如果控制和數據都有一些余留在流首讀隊列中,那么返回常量值是(MORECTL|MOREDATA)。

7、讀模式

如果讀(read)STREAMS設備會發生什么呢?有兩個潛在的問題:

(1)如果讀到流中消息的記錄邊界將會怎樣?

(2)如果調用read,而流中下一個消息有控制信息又將如何?

對第一種情況的默認處理模式稱為字節流模式。read從流中取數據直至滿足了所要求的字節數,或者已經不再有數據。在這種模式中,忽略流中消息的邊界。對第二種情況的默認處理是,如果在隊列的前端有控制消息,則read出錯返回??梢愿淖冞@兩種默認處理模式。

調用ioctl時,若將request設置為I_GRDOPT,第三個參數又是指向一個整型單元的指針,則對該流的當前讀模式在該整型單元中返回。如果將request設置為I_SRDOPT,第三個參數是整型值,則將該流的讀模式設置為該值。讀模式值可由下列三個常量指定:

RNORM 普通,字節流模式,如上所述這是默認模式。

RMSGN 消息不丟棄模式。read從流中去數據直至讀到所要求的字節數,或達到消息邊界。如果某次read只用了消息的一部分,則其余下部分仍留在流中,供下次讀。

RMSGD 消息丟棄模式。這與不丟棄模式的區別是,如果某次讀只用了消息的一部分,則余下部分就被丟棄,不再使用。

在讀模式中還可指定另外三個常量,以便設置在讀到流中包含協議控制信息的消息時read的處理方法:

RPROTNORM 協議-普通模式。read出錯返回,errno設置為EBADMSG。這是默認模式。

RPROTDAT 協議-數據模式。read將控制部分作為數據返回給調用者。

RPROTDIS 協議-丟棄模式。read丟棄消息中的控制信息,但是返回消息中的數據。

任一時刻,只能設置一種消息讀模式以及一種協議讀模式。默認讀模式是(RNORM|RPROTNORM)。

實例

程序清單14-10是在程序清單3-3(http://www.CUOXin.com/nufangrensheng/p/3498248.html)的基礎上改寫的,它用getmsg代替了read。

程序清單14-10 用getmsg將標準輸入復制到標準輸出

#include "apue.h"#include <stropts.h>#define BUFFSIZE    4096int main(void){    int              n, flag;    char             ctlbuf[BUFFSIZE], datbuf[BUFFSIZE];    struct strbuf    ctl, dat;    ctl.buf = ctlbuf;    ctl.maxlen = BUFFSIZE;    dat.buf = datbuf;    dat.maxlen = BUFFSIZE;    for( ; ; )    {        flag = 0;    /* return any message */        if ((n = getmsg(STDIN_FILENO, &ctl, &dat, &flag)) < 0)            err_sys("getmsg error");        fprintf(stderr, "flag = %d, ctl.len = %d, dat.len = %d/n",             flag, ctl.len, dat.len);        if (dat.len == 0)            exit(0);        else if (dat.len > 0)            if (write(STDOUT_FILENO, dat.buf, dat.len) != dat.len)                err_sys("write error");    }}

本篇博文內容摘自《UNIX環境高級編程》(第二版),僅作個人學習記錄所用。關于本書可參考:http://www.apuebook.com/。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产成人福利视频| 人人澡人人澡人人看欧美| 亚洲摸下面视频| 成人乱色短篇合集| 日韩av在线网| 亚洲国产高潮在线观看| 欧美黑人又粗大| 国产精品成人一区二区三区吃奶| 日韩性xxxx爱| 最近日韩中文字幕中文| 欧美大秀在线观看| 亚洲成人久久网| www.久久久久久.com| 久久亚洲国产精品| 成人中文字幕+乱码+中文字幕| 欧美日韩亚洲视频| 国产97色在线| 亚洲第一福利视频| 亚洲摸下面视频| 色av中文字幕一区| 91在线中文字幕| 亚洲福利在线观看| 亚洲国产精品成人av| 亚洲色图欧美制服丝袜另类第一页| 成人精品在线视频| 成人亚洲欧美一区二区三区| 欧美极品少妇与黑人| 91九色单男在线观看| 亚洲欧美日韩中文在线| 国产精品免费在线免费| 日本精品性网站在线观看| 精品久久久免费| 久久天天躁夜夜躁狠狠躁2022| 伊人av综合网| 欧美国产极速在线| 性欧美长视频免费观看不卡| 欧美激情第6页| 亚洲欧洲自拍偷拍| 久久久国产视频91| 国产欧美日韩综合精品| 欧美精品免费播放| 麻豆一区二区在线观看| 精品国产欧美一区二区三区成人| 欧美又大又硬又粗bbbbb| 久久精品青青大伊人av| 精品自拍视频在线观看| 国产一区二区三区在线看| 精品无人区乱码1区2区3区在线| 最新国产精品亚洲| 热久久这里只有| 欧美超级乱淫片喷水| 九九九久久久久久| 成人免费淫片aa视频免费| 亚洲成人性视频| 久久成人免费视频| 欧美二区乱c黑人| 国产欧美在线观看| 欧美午夜电影在线| 日韩精品在线视频| 欧美激情一区二区三区高清视频| 欧美性资源免费| 精品国产一区二区三区久久久| 中文字幕亚洲欧美一区二区三区| 欧美色videos| 国产欧美一区二区三区在线看| 日韩av第一页| 这里精品视频免费| 国产热re99久久6国产精品| 色综合男人天堂| 日韩av在线免费看| 91色p视频在线| 亚洲天堂精品在线| 欧美日韩国产一区二区| 欧美日韩999| 国产精品久久久久久久av大片| 久久夜色精品国产亚洲aⅴ| 不卡av电影在线观看| 精品女同一区二区三区在线播放| 国产精品视频区| 久久中文字幕视频| 精品亚洲一区二区三区在线播放| 亚洲人午夜精品| 国产精品第二页| 26uuu另类亚洲欧美日本一| 成人久久一区二区三区| 91久久精品一区| 欧美日韩亚洲视频一区| 欧美丰满少妇xxxxx做受| 国产日韩av在线播放| 日本精品va在线观看| 国产有码在线一区二区视频| 色妞色视频一区二区三区四区| 日韩中文字幕在线观看| 久久成人精品电影| 欧美专区福利在线| 日韩精品视频观看| 日韩视频在线一区| 国产综合在线看| 欧美精品国产精品日韩精品| 亚洲国产精品久久精品怡红院| 国产精品欧美激情在线播放| 欧美性一区二区三区| 日本久久久久久| 欧美裸体男粗大视频在线观看| 欧美激情在线观看| 久久国产精品影片| 久久久久久久久91| 亚洲第一页中文字幕| 久久久精品国产一区二区| 亚洲第一综合天堂另类专| 欧美视频中文在线看| 欧美激情久久久久久| 亚洲精品少妇网址| 亚洲91精品在线观看| 国产日韩在线看| 中日韩美女免费视频网站在线观看| 亚洲欧美激情一区| 神马国产精品影院av| 久久成人av网站| 91av网站在线播放| 欧美午夜性色大片在线观看| 51色欧美片视频在线观看| 日韩精品在线免费观看视频| 欧美国产第一页| 国产精品国产福利国产秒拍| 久久高清视频免费| 综合欧美国产视频二区| www.日韩免费| 最近免费中文字幕视频2019| 最近2019中文免费高清视频观看www99| 精品国产一区二区三区久久| 91爱视频在线| 亚洲欧美日韩另类| 亚洲图片欧美日产| 韩国三级日本三级少妇99| 亚洲奶大毛多的老太婆| 欧美午夜精品久久久久久浪潮| 亚洲国产私拍精品国模在线观看| 午夜美女久久久久爽久久| 欧美精品电影在线| 色噜噜狠狠色综合网图区| 在线观看精品自拍私拍| 久久午夜a级毛片| 国产精品你懂得| 亚洲欧美在线播放| 欧美在线影院在线视频| 国产精品女主播视频| 欧美电影免费观看高清完整| 国产99久久精品一区二区 夜夜躁日日躁| 中文字幕av一区二区三区谷原希美| 久久人人爽亚洲精品天堂| 欧美日韩亚洲91| 久久777国产线看观看精品| 亚洲欧美精品伊人久久| 黑人欧美xxxx| 国产精品日韩在线播放| 国产亚洲精品美女久久久| 欧美做爰性生交视频| 国产99久久久欧美黑人| 午夜精品久久久久久久99热浪潮| 亚洲va欧美va国产综合剧情| 日韩电影视频免费| 中文字幕日本欧美| 国产精品久久婷婷六月丁香|