• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            面對現(xiàn)實,超越自己
            逆水行舟,不進則退
            posts - 269,comments - 32,trackbacks - 0
            匿名管道
              管道(Pipe)是一種具有兩個端點的通信通道:有一端句柄的進程可以和有另一端句柄的進程通信。管道可以是單向-一端是只讀的,另一端點是只寫的;也可以是雙向的一管道的兩端點既可讀也可寫。
              匿名管道(Anonymous Pipe)是在父進程和子進程之間,或同一父進程的兩個子進程之間傳輸數(shù)據(jù)的無名字的單向管道。通常由父進程創(chuàng)建管道,然后由要通信的子進程繼承通道的讀端點句柄或?qū)懚它c句柄,然后實現(xiàn)通信。父進程還可以建立兩個或更多個繼承匿名管道讀和寫句柄的子進程。這些子進程可以使用管道直接通信,不需要通過父進程。
              匿名管道是單機上實現(xiàn)子進程標(biāo)準(zhǔn)I/O重定向的有效方法,它不能在網(wǎng)上使用,也不能用于兩個不相關(guān)的進程之間。
            命名管道
              命名管道(Named Pipe)是服務(wù)器進程和一個或多個客戶進程之間通信的單向或雙向管道。不同于匿名管道的是命名管道可以在不相關(guān)的進程之間和不同計算機之間使用,服務(wù)器建立命名管道時給它指定一個名字,任何進程都可以通過該名字打開管道的另一端,根據(jù)給定的權(quán)限和服務(wù)器進程通信。
              命名管道提供了相對簡單的編程接口,使通過網(wǎng)絡(luò)傳輸數(shù)據(jù)并不比同一計算機上兩進程之間通信更困難,不過如果要同時和多個進程通信它就力不從心了。

            匿名管道的使用

            匿名管道主要用于本地父進程和子進程之間的通信,

            在父進程中的話,首先是要創(chuàng)建一個匿名管道,

            在創(chuàng)建匿名管道成功后,可以獲取到對這個匿名管道的讀寫句柄,

            然后父進程就可以向這個匿名管道中寫入數(shù)據(jù)和讀取數(shù)據(jù)了,

            但是如果要實現(xiàn)的是父子進程通信的話,那么還必須在父進程中創(chuàng)建一個子進程,

            同時,這個子進程必須能夠繼承和使用父進程的一些公開的句柄,

            為什么呢?

            因為在子進程中必須要使用父進程創(chuàng)建的匿名管道的讀寫句柄,

            通過這個匿名管道才能實現(xiàn)父子進程的通信,所以必須繼承父進程的公開句柄。

            同時在創(chuàng)建子進程的時候,

            必須將子進程的標(biāo)準(zhǔn)輸入句柄設(shè)置為父進程中創(chuàng)建匿名管道時得到的讀管道句柄,

            將子進程的標(biāo)準(zhǔn)輸出句柄設(shè)置為父進程中創(chuàng)建匿名管道時得到的寫管道句柄。

            然后在子進程就可以讀寫匿名管道了。

            匿名管道的創(chuàng)建

            BOOL WINAPI CreatePipe(
                      __out   PHANDLE hReadPipe,
                      __out   PHANDLE hWritePipe,
                      __in    LPSECURITY_ATTRIBUTES lpPipeAttributes,
                      __in    DWORD nSize );

            參數(shù) hReadPipe 為輸出參數(shù),該句柄代表管道的讀取句柄。

            參數(shù) hWritePipe 為輸出參數(shù),該句柄代表管道的寫入句柄。

            參數(shù) lpPipeAttributes 為一個輸入?yún)?shù),指向一個 SECURITY_ATTRIBUTES 的結(jié)構(gòu)體指針,

            其檢測返回的句柄是否能夠被子進程繼承,如果此參數(shù)為 NULL ,則表明句柄不能被繼承,

            在匿名管道中,由于匿名管道要在父子進程之間進行通信,

            而子進程如果想要獲得匿名管道的讀寫句柄,則其只能通過從父進程繼承獲得,

            當(dāng)一個子進程從其父進程處繼承了匿名管道的讀寫句柄以后,

            子進程和父進程之間就可以通過這個匿名管道的讀寫句柄進行通信了。

            所以在這里必須構(gòu)建一個 SECURITY_ATTRIBUTES 的結(jié)構(gòu)體,

            并且該結(jié)構(gòu)體的第三個結(jié)構(gòu)成員變量 bInheritHandle 參數(shù)必須設(shè)置為 TRUE 

            從而讓子進程可以繼承父進程所創(chuàng)建的匿名管道的讀寫句柄。

            typedef struct _SECURITY_ATTRIBUTES {
             
                DWORD nLength;
             
                LPVOID lpSecurityDescriptor;
             
                BOOL bInheritHandle;
             
            } SECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;

            參數(shù) nSize 用來指定緩沖區(qū)的大小,

            如果此參數(shù)設(shè)置為 ,則表明系統(tǒng)將使用默認的緩沖區(qū)大小。一般將該參數(shù)設(shè)置為 即可。

            子進程的創(chuàng)建

            BOOL  CreateProcess( 
                    LPCWSTR pszImageName,  LPCWSTR pszCmdLine, 
                    LPSECURITY_ATTRIBUTES psaProcess, 
                    LPSECURITY_ATTRIBUTES psaThread, 
                    BOOL fInheritHandles,  DWORD fdwCreate, 
                    LPVOID pvEnvironment,  LPWSTR pszCurDir, 
                    LPSTARTUPINFOW psiStartInfo, 
                    LPPROCESS_INFORMATION pProcInfo );

            參數(shù) pszImageName 是一個指向 NULL 終止的字符串,用來指定可執(zhí)行程序的名稱。

            參數(shù) pszCmdLine 用來指定傳遞給新進程的命令行字符串,一般做法是在 pszImageName 中傳遞可執(zhí)行文件的名稱,

            在 pszCmdLine 中傳遞命令行參數(shù)。

            參數(shù) psaProcess 即代表當(dāng) CreateProcess 函數(shù)創(chuàng)建進程時,需要給進程對象設(shè)置一個安全性。

            參數(shù) psaThread 代表當(dāng) CreateProcess 函數(shù)創(chuàng)建新進程后,需要給該進程的主線程對象設(shè)置一個安全性。

            參數(shù) fInheritHandles 用來指定父進程隨后創(chuàng)建的子進程是否能夠繼承父進程的對象句柄,

            如果該參數(shù)設(shè)置為 TRUE ,則父進程的每一個可繼承的打開句柄都將被子進程所繼承,

            繼承的句柄與原始的句柄擁有同樣的訪問權(quán)。

            在匿名管道的使用中,因為子進程需要使用父進程中創(chuàng)建的匿名管道的讀寫句柄,

            所以應(yīng)該將這個參數(shù)設(shè)置為 TRUE ,從而可以讓子進程繼承父進程創(chuàng)建的匿名管道的讀寫句柄。

            參數(shù) fdwCreate 用來指定控件優(yōu)先級類和進程創(chuàng)建的附加標(biāo)記。

            如果只是為了啟動子進程,則并不需要設(shè)置它創(chuàng)建的標(biāo)記,可以將此參數(shù)設(shè)置為 0,

            對于這個參數(shù)的具體取值列表可以參考 MSDN 。

            參數(shù) pvEnvironment 代表指向環(huán)境塊的指針,

            如果該參數(shù)設(shè)置為 NULL ,則默認將使用父進程的環(huán)境。通常給該參數(shù)傳遞 NULL。

            參數(shù) pszCurDir 用來指定子進程當(dāng)前的路徑,

            這個字符串必須是一個完整的路徑名,其包括驅(qū)動器的標(biāo)識符,

            如果此參數(shù)設(shè)置為 NULL ,那么新的子進程將與父進程擁有相同的驅(qū)動器和目錄。

            參數(shù) psiStartInfo 指向一個 StartUpInfo 的結(jié)構(gòu)體的指針,用來指定新進程的主窗口如何顯示。

            typedef struct _STARTUPINFOA {
                DWORD cb;
                LPSTR lpReserved;
                LPSTR lpDesktop;
                LPSTR lpTitle;
                DWORD dwX;
                DWORD dwY;
                DWORD dwXSize;
                DWORD dwYSize;
                DWORD dwXCountChars;
                DWORD dwYCountChars;
                DWORD dwFillAttribute;
                DWORD dwFlags;
                WORD wShowWindow;
                WORD cbReserved2;
                LPBYTE lpReserved2;
                HANDLE hStdInput;
                HANDLE hStdOutput;
                HANDLE hStdError;
            } STARTUPINFOA, *LPSTARTUPINFOA;

            對于 dwFlags 參數(shù)來說,如果其設(shè)置為 STARTF_USESTDHANDLES ,

            則將會使用該 STARTUPINFO 結(jié)構(gòu)體中的 hStdInput , hStdOutput , hStdError 成員,

            來設(shè)置新創(chuàng)建的進程的標(biāo)準(zhǔn)輸入,標(biāo)準(zhǔn)輸出,標(biāo)準(zhǔn)錯誤句柄。

            參數(shù) pProcInfo 為一個輸出參數(shù),

            指向一個 PROCESS_INFORMATION 結(jié)構(gòu)體的指針,用來接收關(guān)于新進程的標(biāo)識信息。

            typedef struct _PROCESS_INFORMATION 
            {             
                HANDLE hProcess;             
                HANDLE hThread;             
                DWORD dwProcessId;              
                DWORD dwThreadId; 
             
            }PROCESS_INFORMATION;

            其中 hProcess 和 hThread 分別用來標(biāo)識新創(chuàng)建的進程句柄和新創(chuàng)建的進程的主線程句柄。

            dwProcessId 和 dwThreadId 分別是全局進程標(biāo)識符和全局線程標(biāo)識符。

            前者可以用來標(biāo)識一個進程,后者用來標(biāo)識一個線程。

            示例代碼:
            父進程:

             1 void CParentView::OnPipeCreate() 
             2 {
             3     // TODO: Add your command handler code here
             4     SECURITY_ATTRIBUTES sa;
             5 
             6     sa.bInheritHandle = TRUE;
             7     sa.lpSecurityDescriptor = NULL;
             8     sa.nLength = sizeof(SECURITY_ATTRIBUTES);
             9 
            10     if(!CreatePipe(&hRead,&hWrite,&sa,0))
            11     {
            12         MessageBox("創(chuàng)建匿名管道失敗!");
            13         return;
            14     }
            15 
            16     STARTUPINFO sui;
            17     PROCESS_INFORMATION pi;
            18 
            19     ZeroMemory(&sui,sizeof(STARTUPINFO));
            20 
            21     sui.cb = sizeof(STARTUPINFO);
            22     sui.dwFlags = STARTF_USESTDHANDLES;
            23     sui.hStdInput = hRead;
            24     sui.hStdOutput = hWrite;
            25     sui.hStdError = GetStdHandle(STD_ERROR_HANDLE);
            26 
            27     if(!CreateProcess("..\\Child\\Debug\\Child.exe",NULL,NULL,NULL,TRUE,0,NULL,NULL,&sui,&pi))
            28     {
            29         CloseHandle(hRead);
            30         CloseHandle(hWrite);
            31         hRead = NULL;
            32         hWrite = NULL;
            33         MessageBox("創(chuàng)建子進程失敗!");
            34         return;
            35     }
            36     else
            37     {
            38         CloseHandle(pi.hProcess);
            39         CloseHandle(pi.hThread);
            40     }
            43 }
            44 
            45 void CParentView::OnPipeRead() 
            46 {
            47     // TODO: Add your command handler code here
            48     char buf[100];
            49     DWORD dwRead;
            50     if(!ReadFile(hRead,buf,100,&dwRead,NULL))
            51     {
            52         MessageBox("讀取數(shù)據(jù)失??!");
            53         return;
            54     }
            55     MessageBox(buf);    
            56 }
            57 
            58 void CParentView::OnPipeWrite() 
            59 {
            60     // TODO: Add your command handler code here
            61     char buf[] = "http:\\www.hit.edu.cn";
            62     DWORD dwWrite;
            63     if(!WriteFile(hWrite,buf,strlen(buf)+1,&dwWrite,NULL))
            64     {
            65         MessageBox("寫入數(shù)據(jù)失??!");
            66         return;
            67     }
            68 }

            子進程:
             1 void CChildView::OnPipeRead() 
             2 {
             3     // TODO: Add your command handler code here
             4     char buf[100];
             5     DWORD dwRead;
             6     if(!ReadFile(hRead,buf,100,&dwRead,NULL))
             7     {
             8         MessageBox("讀取數(shù)據(jù)失??!");
             9         return;
            10     }
            11     MessageBox(buf);    
            12 }
            13 
            14 void CChildView::OnPipeWrite() 
            15 {
            16     // TODO: Add your command handler code here
            17     char buf[] = "匿名管道測試程序";
            18     DWORD dwWrite;
            19     if(!WriteFile(hWrite,buf,strlen(buf)+1,&dwWrite,NULL))
            20     {
            21         MessageBox("寫入數(shù)據(jù)失敗!");
            22         return;
            23     }
            24 }
            25 
            26 void CChildView::OnInitialUpdate() 
            27 {
            28     CView::OnInitialUpdate();
            29     
            30     // TODO: Add your specialized code here and/or call the base class
            31     hRead = GetStdHandle(STD_INPUT_HANDLE);
            32     hWrite = GetStdHandle(STD_OUTPUT_HANDLE);    
            33 }

            命名管道的實現(xiàn):    
            1.命名管道ServerClient間通信的實現(xiàn)流程    
            (1)建立連接:服務(wù)端通過函數(shù)CreateNamedPipe創(chuàng)建一個命名管道的實例并返回用于 今后操作的句柄,或為已存在的管道創(chuàng)建新的實例。如果在已定義超時值變?yōu)榱阋郧?,?/span> 一個實例管道可以使用,則創(chuàng)建成功并返回管道句柄,并用以偵聽來自客戶端的連接請求, 該功能通過ConnectNamedPipe函數(shù)實現(xiàn)。 

                  另一方面,客戶端通過函數(shù)WaitNamedPipe使服務(wù)進程等待來自客戶的實例連接,如 果在超時值變?yōu)榱阋郧?,有一個管道可以為連接使用,則WaitNamedPipe將返回True,并 通過調(diào)用CreateFileCallNamedPipe來呼叫對服務(wù)端的連接。此時服務(wù)端將接受客戶端 的連接請求,成功建立連接,服務(wù)端ConnectNamedPipe返回True,客戶端CreateFile將返 回一指向管道文件的句柄。

                  從時序上講,首先是客戶端通過WaitNamedPipe使服務(wù)端的CreateFile在限時時間內(nèi) 創(chuàng)建實例成功,然后雙方通過ConnectNamedPipeCreateFile成功連接,并返回用以通信 的文件句柄,此時雙方即可進行通信。    
            (2)通信實現(xiàn):建立連接之后,客戶端與服務(wù)器端即可通過ReadFileWriteFile 利用得到的管道文件句柄,彼此間進行信息交換。   
            (3)連接終止:當(dāng)客戶端與服務(wù)端的通信結(jié)束,或由于某種原因一方需要斷開時,客 戶端應(yīng)調(diào)用CloseFile,而服務(wù)端應(yīng)接著調(diào)用DisconnectNamedPipe。當(dāng)然服務(wù)端亦可通 過單方面調(diào)用DisconnectNamedPipe終止連接。最后應(yīng)調(diào)用函數(shù)CloseHandle來關(guān)閉該管道。

            2.命名管道服務(wù)器端和客戶端代碼實現(xiàn)


            服務(wù)端:
             1 void CTestServiceDlg::OnBnClickedBtncon()
             2 {
             3     // TODO: 在此添加控件通知處理程序代碼
             4     m_strPipeName = _T("\\\\.\\Pipe\\mypipe");
             5     m_hPipe = CreateNamedPipeW(
             6         m_strPipeName,//管道名稱
             7         PIPE_ACCESS_DUPLEX,
             8         PIPE_TYPE_MESSAGE|    //消息流類型的管道
             9         PIPE_READMODE_BYTE|    //消息流讀模式
            10         PIPE_WAIT,            //阻塞模式
            11         PIPE_UNLIMITED_INSTANCES,    //允許最大管道實例個數(shù)
            12         BUF_SIZE,//輸出緩沖
            13         BUF_SIZE,//輸入緩沖
            14         0,        //客戶端超時時間
            15         NULL    //默認的安全屬性
            16         );
            17     if(m_hPipe == INVALID_HANDLE_VALUE)
            18     {
            19         AfxMessageBox(_T("創(chuàng)建命名管道失敗!"));
            20         PostQuitMessage(-8);
            21         return;
            22     }
            23     if (ConnectNamedPipe(m_hPipe,NULL))
            24     {
            25         SetDlgItemText(IDC_LblRead,"");
            26         GetDlgItem(IDC_BtnRead)->EnableWindow(TRUE);
            27         GetDlgItem(IDC_BtnSend)->EnableWindow(TRUE);
            28         AfxMessageBox("連接成功!");
            29     }
            30     else
            31     {
            32         CloseHandle(m_hPipe);
            33         m_hPipe = NULL;
            34         AfxMessageBox("連接失敗!");
            35         PostQuitMessage(-8);
            36         return;
            37     }
            38 }
            39 
            40 void CTestServiceDlg::OnBnClickedBtnread()
            41 {
            42     TCHAR buff[BUF_SIZE];
            43     DWORD dwRead;
            44     if (!ReadFile(m_hPipe,buff,BUF_SIZE,&dwRead,NULL))
            45     {
            46         CString errMsg;
            47         errMsg.Format("讀取發(fā)生錯誤:%d",GetLastError());
            48         AfxMessageBox(errMsg);
            49         return;
            50     }
            51     else
            52     {
            53         buff[dwRead] = '\0';//結(jié)束符
            54         CString strRead(buff);
            55         SetDlgItemText(IDC_LblRead, strRead);
            56     }
            57 }
            58 
            59 void CTestServiceDlg::OnBnClickedBtnsend()
            60 {
            61     // TODO: 在此添加控件通知處理程序代碼
            62     UpdateData(TRUE);
            63     DWORD dwWrite;
            64     bool rt = WriteFile(m_hPipe,
            65         m_TxtSend,(m_TxtSend.GetLength()+1)*sizeof(TCHAR),
            66         &dwWrite,NULL);
            67     if(!rt)
            68     {
            69         CString errMsg;
            70         errMsg.Format("寫入文件失敗,錯誤信息%d",::GetLastError());
            71         AfxMessageBox(errMsg);
            72         return;
            73     }
            74     else
            75     {
            76         SetDlgItemText(IDC_LblRead,"發(fā)送成功!");
            77         m_TxtSend = L"";
            78         UpdateData(FALSE);
            79     }
            80 }

            客戶端:
             1 void CTestClientDlg::OnBnClickedBtnconnect()
             2 {
             3     // TODO: 在此添加控件通知處理程序代碼
             4     //查詢是否有管道實例可用
             5     m_strPipeName = _T("\\\\.\\Pipe\\mypipe");
             6     if(!WaitNamedPipe(m_strPipeName,NMPWAIT_USE_DEFAULT_WAIT))
             7     {
             8         AfxMessageBox(_T("連接到服務(wù)器端失敗!"));
             9         return;
            10     }
            11     hPipe = CreateFileW(
            12         m_strPipeName,    //管道名稱
            13         GENERIC_READ|    //以可讀寫模式打開
            14         GENERIC_WRITE,
            15         0,                //不支持共享
            16         NULL,            //默認安全屬性
            17         OPEN_EXISTING,    //只打開已存在的管道
            18         0,
            19         NULL);
            20     if(hPipe != INVALID_HANDLE_VALUE)
            21     {
            22         GetDlgItem(IDC_BtnConnect)->EnableWindow(FALSE);
            23         GetDlgItem(IDC_BtnRec)->EnableWindow(TRUE);
            24         GetDlgItem(IDC_BtnSend)->EnableWindow(TRUE);
            25         ///GetDlgItem(idc)
            26     }
            27     if(GetLastError()!= ERROR_PIPE_BUSY)//如果連接不是忙碌
            28     {
            29         AfxMessageBox(L"連接到服務(wù)端成功!");
            30         return;
            31     }
            32 }
            33 
            34 void CTestClientDlg::OnBnClickedBtnsend()
            35 {
            36     // TODO: 在此添加控件通知處理程序代碼
            37     UpdateData(TRUE);
            38     DWORD dwWrite;
            39     if (!WriteFile(hPipe,m_Send,(m_strPipeName.GetLength()+1)*sizeof(TCHAR),&dwWrite,NULL))
            40     {
            41         CString errMsg;
            42         errMsg.Format(L"發(fā)送失敗:%d",GetLastError());
            43         return;
            44     }
            45     m_Rec = L"發(fā)送成功!";
            46     UpdateData(TRUE);
            47 }
            48 
            49 void CTestClientDlg::OnBnClickedBtnrec()
            50 {
            51     // TODO: 在此添加控件通知處理程序代碼
            52     TCHAR buff[BUF_SIZE];
            53     DWORD dwRead;
            54     if(!ReadFile(hPipe,buff,BUF_SIZE,&dwRead,NULL))
            55     {
            56         CString errMsg;
            57         errMsg.Format(L"讀取失敗,錯誤信息%d",GetLastError());
            58         return;
            59     }    
            60     else
            61     {
            62         buff[dwRead] = _T('\0');
            63         CStringW strRead(buff);
            64         m_Rec = strRead;
            65         UpdateData(FALSE);
            66     }
            67 }

            命名管道程序設(shè)計的注意事項    
            1.如果命名管道客戶端已打開,函數(shù)將會強迫關(guān)閉管道,用DisconnectNamedPipe關(guān)閉 的管道,其客戶端還必須用CloseHandle來關(guān)閉最后的管道。    
            2. ReadFileWriteFilehFile句柄是由CreateFileConnectNamedPipe返回得到。   
            3.一個已被某客戶端連接的管道句柄在被另一客戶通過ConnectNamedPipe建立連接之前,服務(wù)端必須用DisconnectNamedPipe函數(shù)對已存在的連接進行強行拆離。服務(wù)端拆離管道會造成管道中數(shù)據(jù)的丟失,用FlushFileBuffers函數(shù)可以保證數(shù)據(jù)不被丟失。
            4.命名管道服務(wù)端可以通過新創(chuàng)建的管道句柄或已被連接過其他客戶的管道句 柄來使用ConnectNamedPipe函數(shù),但在連接新的客戶端之前,服務(wù)端必須用函數(shù) DisconnectNamedPipe切斷之前的客戶句柄,否則ConnectNamedPipe 將會返回False    
            5.阻塞模式,這種模式僅對字節(jié)傳輸管道"操作有效,并且要求客戶端與服務(wù)端不 在同一機器上。如果用這種模式,則只有當(dāng)函數(shù)通過網(wǎng)絡(luò)向遠端計算機管道緩沖器寫數(shù) 據(jù)成功時,才能有效返回。如果不用這種模式,系統(tǒng)會運行缺省方式以提高網(wǎng)絡(luò)的工作效率。    
            6.用戶必須用FILE—CREATE—PIPE—INSTANCE 來訪問命名管道對象。新的命名管 道建立后,來自安全參數(shù)的訪問控制列表定義了訪問該命名管道的權(quán)限。所有命名管道 實例必須使用統(tǒng)一的管道傳輸方式、管道模式等參數(shù)??蛻舳宋磫?,管道服務(wù)端不能 執(zhí)行阻塞讀操作,否則會發(fā)生空等的阻塞狀態(tài)。當(dāng)最后的命名管道實例的最后一個句柄 被關(guān)閉時,就應(yīng)該刪除該命名管道。


            匿名管道示例     命名管道示例

            本文相關(guān)鏈接:http://www.cnblogs.com/BoyXiao/archive/2011/01/01/1923828.html
                                             http://bbs.csdn.net/topics/300267497
                                             http://wenku.baidu.com/view/09ffacd43186bceb19e8bb39.html

             

             

             

             

            posted on 2012-11-20 16:35 王海光 閱讀(6626) 評論(0)  編輯 收藏 引用 所屬分類: MFC
            亚洲狠狠久久综合一区77777| 日本精品一区二区久久久| 久久久久亚洲AV成人片| 久久国产精品99国产精| 丁香五月综合久久激情| 区亚洲欧美一级久久精品亚洲精品成人网久久久久 | 精品久久国产一区二区三区香蕉| 久久国产精品视频| 久久久久久久女国产乱让韩| 久久99精品国产99久久6男男| 久久精品亚洲福利| 亚洲国产另类久久久精品小说| 久久国产高清字幕中文| 久久久久久免费视频| 久久亚洲国产中v天仙www| 亚洲精品国产字幕久久不卡| 国产成人综合久久精品尤物| 天天爽天天狠久久久综合麻豆| 久久97久久97精品免视看秋霞| 久久99国产综合精品女同| 日本精品久久久久久久久免费| 69久久精品无码一区二区| 久久精品国产亚洲AV久| 久久综合亚洲色HEZYO国产| 久久国产精品久久国产精品| 中文国产成人精品久久不卡| 日韩久久久久中文字幕人妻| 久久福利青草精品资源站| 欧美噜噜久久久XXX| 亚洲精品美女久久777777| 久久亚洲精品国产亚洲老地址 | 久久青青草视频| 久久精品无码一区二区日韩AV| 亚洲精品国产成人99久久| 狠狠色丁香婷婷综合久久来| av无码久久久久久不卡网站| 色综合久久综合中文综合网| 久久久久人妻一区二区三区 | 超级碰碰碰碰97久久久久| 狠狠色丁香婷婷久久综合五月| 久久青青草原精品国产软件|