• <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>
            隨筆-145  評(píng)論-173  文章-70  trackbacks-0
                  五一放假了,沒有到哪里去玩,雖然說還是很多事情要做,不過先做做這個(gè)再說。于是花了大概一天半的時(shí)間,搞定了這個(gè)小的程序,也算是回報(bào)吧!以后會(huì)繼續(xù)完善和補(bǔ)充的。
                  話說上次騰訊2面的時(shí)候我表現(xiàn)太不好了,傷心啊~~~所以從現(xiàn)在起,要在忙中抽時(shí)間來繼續(xù)Coding,增強(qiáng)實(shí)力。估計(jì)過段時(shí)間的百度和其他實(shí)習(xí)不會(huì)去了,研究生真的很重要,所以要好好準(zhǔn)備考研了,加油!
                   不說廢話了,上筆記:


            SMTP郵件發(fā)送剖析

            封裝之后的類如下:



            // MySmtp.cpp: implementation of the MySmtp class.
            //
            /**/
            //////////////////////////////////////////////////////////////////////
             
            #include 
            "stdafx.h"
            #include 
            "MailExam.h"
            #include 
            "MySmtp.h"
            #include 
            "ZBase64.h"
             
            #ifdef _DEBUG
            #undef THIS_FILE
            static char THIS_FILE[]=__FILE__;
            #define new DEBUG_NEW
            #endif
             
             
            #define COPYRIGHT "Smtp Client"         // 版權(quán)信息
            #define BOUNDARY "www.hust.edu.cn"                                // 邊界字符串
            /**///////////////////////////////////////////////////////////////////////
            // Construction/Destruction
            /**/
            //////////////////////////////////////////////////////////////////////
             
            MySmtp::MySmtp()
            {
             
            }
             
            MySmtp::
            ~MySmtp()
            {
             
            }
             
            bool MySmtp::CreateSocket()        //創(chuàng)建一個(gè)Socket
            {
                     
            if(WSAStartup(0x0101&m_WSADATA) != 0)        //至此socket版本是2.2,第一個(gè)參數(shù)也可以是MAKEWORD( 2, 2 )
                     {
                              ReleaseSocket();
                              
            return false;             //創(chuàng)建失敗
                     }
                     
            if( (m_SOCKET= socket(AF_INET,SOCK_STREAM, 0)) == INVALID_SOCKET){
                              ReleaseSocket();
                              
            return false;
                     }
                     
            return true;
            }
             
            //通過和比較碼比較來發(fā)現(xiàn)是否響應(yīng)成功
            bool MySmtp::CheckResponse(const char* RecvCode)
            {
                     
            //將收到的和對(duì)應(yīng)的碼字比較,判斷是否發(fā)生錯(cuò)誤
                     char buf[1024= {0};
                     
            if(recv(m_SOCKET,buf,1024,0== SOCKET_ERROR)
                              
            return false;
                     
            else 
                     {
                              
            return buf[0== RecvCode[0&& buf[1== RecvCode[1]
                              
            &&buf[2== RecvCode[2? true : false;
                     }
            }
             
            bool MySmtp::Connect(const string SmtpAddr,const int Port)
            {
                     
            if(!CreateSocket())
                              
            return false;
                     
            //得到主機(jī)(要發(fā)送給的SMTP地址如smtp.sina.com.cn)地址,并將相應(yīng)的信息寫入m_HOSTENT,
                     
            //就是在那個(gè)字符串中查找到相應(yīng)信息并且構(gòu)造一個(gè)結(jié)構(gòu)體HOSTENT(這個(gè)記錄了很多信息,不僅僅是地址)
                     if((m_HOSTENT = gethostbyname((SmtpAddr.c_str()))) == NULL) //將傳入的主機(jī)參數(shù)給m_HOSTENT
                              return false;
            //    AfxMessageBox(m_HOSTENT->h_name);    //調(diào)試用的,找到HOSTENT的結(jié)構(gòu)內(nèi)容
            //    AfxMessageBox(*m_HOSTENT->h_aliases);
                     if(m_HOSTENT->h_addr_list[0== NULL)     //地址列表為空
                     {
                              ReleaseSocket();
                              
            return false;
                     }
            //    AfxMessageBox(m_HOSTENT->h_addr_list[0]);
            //    AfxMessageBox(m_HOSTENT->h_addr_list[1]);
                     memset(&m_SOCKADDR_IN,0,sizeof(m_SOCKADDR_IN));
                     
            //將這個(gè)SOCKET和主機(jī)地址聯(lián)系起來,其實(shí)WinSoket中,m_HOSTENT 和m_SOCKADDR_IN都是表示的主機(jī)地址,也就是目的地的地址
                     
            //
                     m_SOCKADDR_IN.sin_family = AF_INET;
                     m_SOCKADDR_IN.sin_addr.S_un.S_addr 
            = *(ULONG *) m_HOSTENT->h_addr_list[0];
                     m_SOCKADDR_IN.sin_port 
            = htons(Port);
            //    u_long tmp = *(ULONG *) m_HOSTENT->h_addr_list[0];
            //     char newstring[30];
            //    sprintf(newstring,"%d",tmp);
            //    AfxMessageBox(newstring);
             
                     
            //進(jìn)行連接
                     if(connect(m_SOCKET,(sockaddr *)&m_SOCKADDR_IN,sizeof(m_SOCKADDR_IN)) == SOCKET_ERROR)
                     {
                              ReleaseSocket();
                              
            return false;
                     }
                     
            if(!CheckResponse("220")) return false;                 //服務(wù)準(zhǔn)備就緒
                     
                     
            //向服務(wù)器發(fā)送"HELO "+服務(wù)器名
                     string strTmp="HELO "+SmtpAddr+"\r\n";
                     
            if(send(m_SOCKET,strTmp.c_str(),strTmp.length(),0== SOCKET_ERROR) 
                     {
                              ReleaseSocket();
                              
            return false;
                     }
                     
            if(!CheckResponse("250")) return false;                 //請(qǐng)求操作就緒
                     
                     
            return true;
            }
             
            void MySmtp::ReleaseSocket()
            {
                     shutdown(m_SOCKET,SD_BOTH);
                     closesocket(m_SOCKET);
                     WSACleanup();
             
            }
            bool MySmtp::SendData(const string SendFrom, const string SendToList, 
                                                          
            const string SenderName, const string ReceiverName, 
                                                          
            const string Subject, const string Content )
            {
                     
            if(SendFrom.empty())
                              
            return false;    //源地址是空的
                     if(SendToList.empty()) 
                              
            return false;    //目的地址為空
                     
                     
            string strTmp;
                     ZBase64 base64;
                     
                     
            //發(fā)送MAIL FROM:<abc@xyz.com>
                     strTmp="MAIL FROM:<"+SendFrom+">\r\n";
                     
            if(send(m_SOCKET,strTmp.c_str(),strTmp.length(),0== SOCKET_ERROR)
                     {
                              ReleaseSocket();
                              
            return false;
                     }
                     
            if(!CheckResponse("250")) return false;
                     
                     
            //發(fā)送RCPT To:<abc@xyz.com>
                     strTmp="RCPT To:<"+SendToList+">\r\n";
                     
            if(send(m_SOCKET,strTmp.c_str(),strTmp.length(),0== SOCKET_ERROR)
                     {
                              ReleaseSocket();
                              
            return false;
                     }
                     
            if(!CheckResponse("250")) return false;
             
                     
                     
            //發(fā)送"DATA\r\n"
                     if(send(m_SOCKET,"DATA\r\n",strlen("DATA\r\n"),0== SOCKET_ERROR)
                     {
                              ReleaseSocket();
                              
            return false;
                     }
                     
            if(!CheckResponse("354")) return false;
                     
                     
            //"Mail From:SenderName<xxx@mail.com>\r\n"
                     strTmp="From:"+SenderName+"<"+SendFrom+">\r\n";
                     
                     
            //"Subject: 郵件主題\r\n"
                     strTmp+="Subject:"+Subject+"\r\n";
                     
                     
            //"MIME_Version:1.0\r\n"
                     strTmp+="MIME_Version:1.0\r\n";
                     
                     
            //"X-Mailer:Smtp Client By xxx"//版權(quán)信息
                     strTmp+="X-Mailer:"; strTmp+=COPYRIGHT; strTmp+="\r\n";
                     
                     
            //"MIME_Version:1.0\r\n"
                     strTmp+="MIME_Version:1.0\r\n";
                     
                     
            //"Content-type:multipart/mixed;Boundary=xxx\r\n\r\n";
                     strTmp+="Content-type:multipart/mixed;Boundary=";
                     strTmp
            +=BOUNDARY;
                     strTmp
            +="\r\n\r\n";
                     
                     
            //先將HEADER部分發(fā)送過去
                     if(send(m_SOCKET,strTmp.c_str(),strTmp.length(),0== SOCKET_ERROR)
                     {
                              ReleaseSocket();
                              
            return false;    
                     }
                     
                     
            //郵件主體
                     strTmp="--";
                     strTmp
            +=BOUNDARY;
                     strTmp
            +="\r\n";
                     strTmp
            += "Content-type:text/plain;Charset=gb2312\r\n";
                     strTmp
            +="Content-Transfer-Encoding:8bit\r\n\r\n";
                     
                     
            //郵件內(nèi)容
                     strTmp+=Content+"\r\n\r\n";
                     
                     
            //將郵件內(nèi)容發(fā)送出去
                     if(send(m_SOCKET,strTmp.c_str(),strTmp.length(),0== SOCKET_ERROR)
                     {
                              ReleaseSocket();
                              
            return false;    
                     }
                     strTmp
            ="--";
                     strTmp
            +=BOUNDARY;
                     strTmp
            +="--\r\n.\r\n";
                     
                     
            if(send(m_SOCKET,strTmp.c_str(),strTmp.length(),0== SOCKET_ERROR)
                     {
                              ReleaseSocket();
                              
            return false;
                     }
                     
            if(!CheckResponse("250")) return false;
                     
                     
            //退出
                     if(send(m_SOCKET,"QUIT\r\n",strlen("QUIT\r\n"),0== SOCKET_ERROR)
                     {
                              ReleaseSocket();
                              
            return false;
                     }
                     
            if(!CheckResponse("221")) return false;
                     
                     ReleaseSocket();
                     
            return true;
            }
            bool MySmtp::Validate(const string Username,const string Password)
            {
                     ZBase64 base64;
                     
                     
            //發(fā)送"AUTH LOGIN"
                     if(send(m_SOCKET,"AUTH LOGIN\r\n",strlen("AUTH LOGIN\r\n"),0== SOCKET_ERROR)
                     {
                              ReleaseSocket();
                              
            return false;
                     }
                     
            if(!CheckResponse("334")) return false;
                     
                     
            //發(fā)送經(jīng)base64編碼的用戶名
                     string strUserName=base64.Encode((unsigned char *)Username.c_str(),Username.length())+"\r\n";
                     
            if(send(m_SOCKET,strUserName.c_str(),strUserName.length(),0== SOCKET_ERROR)
                     {
                              ReleaseSocket();
                              
            return false;
                     }
                     
            if(!CheckResponse("334")) return false;
                     
                     
            //發(fā)送經(jīng)base64編碼的密碼
                     string strPassword=base64.Encode((unsigned char *)Password.c_str(),Password.length())+"\r\n";
                     
            if(send(m_SOCKET,strPassword.c_str(),strPassword.length(),0== SOCKET_ERROR)
                     {
                              ReleaseSocket();
                              
            return false;
                     }
                     
            if(!CheckResponse("235")) return false;
                     
                     
            return true;
            }

             

             

             

            具體如何調(diào)用的是用這個(gè)實(shí)現(xiàn):


            void CMailExamDlg::OnOK() 
            {
                     
            // TODO: Add extra validation here
                     MySmtp smtp;
                     CString strSmtpAddr,strAccount,strPasswrod;
                     GetDlgItemText(IDC_EDIT1,strSmtpAddr);
                     GetDlgItemText(IDC_EDIT2,strAccount);
                     GetDlgItemText(IDC_EDIT3,strPasswrod);
                     
            if(!smtp.Connect((LPSTR)(LPCTSTR)strSmtpAddr,25)){
                              AfxMessageBox(
            "連接服務(wù)器失敗!"); return ;    
                     }
                     
                     
            //驗(yàn)證用戶名密碼
                     if(!smtp.Validate((LPSTR)(LPCTSTR)strAccount,(LPSTR)(LPCTSTR)strPasswrod)){
                              AfxMessageBox(
            "用戶名或密碼失敗!"); return ;        
                     }
                     CString SendFrom,SendToList,SenderName,RecevierName,Subject,Content;
                     GetDlgItemText(IDC_EDIT4,SendFrom);
                     GetDlgItemText(IDC_EDIT5,SendToList);
                     GetDlgItemText(IDC_EDIT6,Content);
                     GetDlgItemText(IDC_EDIT7,SenderName);
                     GetDlgItemText(IDC_EDIT8,RecevierName);
                     GetDlgItemText(IDC_EDIT9,Subject);
                     
            //發(fā)送
                     if(!smtp.SendData((LPSTR)(LPCTSTR)SendFrom,
                              (LPSTR)(LPCTSTR)SendToList,
                              (LPSTR)(LPCTSTR)SenderName,
                              (LPSTR)(LPCTSTR)RecevierName,
                              (LPSTR)(LPCTSTR)Subject,
                              (LPSTR)(LPCTSTR)Content))
                     {
                              AfxMessageBox(
            "郵件發(fā)送失敗!"); 
                              
            return ;
                     }
                     AfxMessageBox(
            "郵件發(fā)送成功!");
            //     CDialog::OnOK();
            }

             

            實(shí)際上本質(zhì)就是,1,連接Connect,2,驗(yàn)證賬戶密碼Validate,3,發(fā)送數(shù)據(jù)

             

             

            最核心的部分:如何實(shí)現(xiàn)MySmtp?

            首先看看類視圖,看看這個(gè)封裝的類到底實(shí)現(xiàn)了哪些功能:

                                           

             

             

            在這個(gè)部分,關(guān)鍵的是:connect,Validate,checkResponse,SendData,CreateSocket這些函數(shù),分別來說明:

            CreateSocket: 創(chuàng)建Socket,利用Socket來編寫郵件客戶端,就是需要利用到Socket來作為一個(gè)門戶啊,關(guān)于socket的解釋,這里不再多說,由于是用的Windows下面的平臺(tái),所以需要用到的WinSock來編寫,對(duì)應(yīng)的就需要一定的規(guī)則。具體來說就是需要WSAStartup來

            這個(gè)函數(shù)是應(yīng)用程序應(yīng)該第一個(gè)調(diào)用的Winsock API 函數(shù),以完成一系列初始化的工作。必不可少!

            其次,就是需要完成真正的創(chuàng)建,所以調(diào)用Socket函數(shù)來實(shí)現(xiàn),創(chuàng)建后的返回值就是一個(gè)SOCKET對(duì)象,需要保存它,因此專門定義一個(gè)類成員m_SOCKET來保存這個(gè)變量,使得以后不管是發(fā)送還是接受,都可以用這個(gè)變量來實(shí)現(xiàn)(前面已經(jīng)說了,socket對(duì)象就是一個(gè)門戶,需要通過它來發(fā)送和接收)

             

             

            checkResponse :需要通過這個(gè)函數(shù)來實(shí)時(shí)的檢查狀態(tài),比如發(fā)送是否成功,并且可以得到相應(yīng)的錯(cuò)誤信息,也便于調(diào)試。

            驗(yàn)證從服務(wù)器返回的前三位代碼和傳遞進(jìn)來的參數(shù)是否一樣

                                       備注:

                                       211 幫助返回系統(tǒng)狀態(tài)

                                       214 幫助信息

                                       220 服務(wù)準(zhǔn)備就緒

                                       221 關(guān)閉連接

                                       235 用戶驗(yàn)證成功

                                       250 請(qǐng)求操作就緒

                                       251 用戶不在本地,轉(zhuǎn)寄到其他路徑

                                       334 等待用戶輸入驗(yàn)證信息

                                       354 開始郵件輸入

                                       421 服務(wù)不可用

                                       450 操作未執(zhí)行,郵箱忙

                                       451 操作中止,本地錯(cuò)誤

                                       452 操作未執(zhí)行,存儲(chǔ)空間不足

                                       500 命令不可識(shí)別或語言錯(cuò)誤

                                       501 參數(shù)語法錯(cuò)誤

                                       502 命令不支技

                                       503 命令順序錯(cuò)誤

                                       504 命令參數(shù)不支持

                                       550 操作未執(zhí)行,郵箱不可用

                                       551 非本地用戶

                                       552 中止存儲(chǔ)空間不足

                                       553 操作未執(zhí)行,郵箱名不正確

                                       554 傳輸失敗

            為此,需要從socket接收數(shù)據(jù),然后和標(biāo)準(zhǔn)的這些碼字,比如554來進(jìn)行比較,通過比較的結(jié)果來決定是否響應(yīng)正確,確定后面是否傳輸!具體的函數(shù)實(shí)際上就是一個(gè)recv來實(shí)現(xiàn)。而接收的結(jié)果,需要存放下來,然后手動(dòng)比較,就有了

            return buf[0] == RecvCode[0] && buf[1] == RecvCode[1]&&buf[2] == RecvCode[2] ? true : false;

            The recv function receives data from a connected or bound socket.

             

             

            Connect:連接部分其實(shí)也是一個(gè)很簡(jiǎn)單的功能,就是要發(fā)送一個(gè)HELO + 服務(wù)器名,但是注意這個(gè)之前,需要完成一些操作。首先,就是要建立連接,讓它知道我要連接它,用connect函數(shù)。向?qū)Ψ街鲃?dòng)提出連接請(qǐng)求。其次就是如何發(fā)送?當(dāng)然是通過socket發(fā)送,調(diào)用send函數(shù)來實(shí)現(xiàn)了(都是底層的API),但是,由于是第一次發(fā)送,所以需要?jiǎng)?chuàng)建socket,所以調(diào)用了前面的CreateSocket來創(chuàng)建,(注意,代碼中多出用到了判斷語句,因?yàn)榫W(wǎng)絡(luò)中很容易就出現(xiàn)錯(cuò)誤,所以需要實(shí)時(shí)的進(jìn)行if判斷,及時(shí)定位錯(cuò)誤,否則后面的編碼就容易出錯(cuò)而不知道如何編寫),然后就是要根據(jù)send函數(shù)的參數(shù)來調(diào)用了。對(duì)于connect函數(shù),根據(jù)API原型,需要SOCKADDR_IN類型的參數(shù),也就是記錄了遠(yuǎn)程主機(jī)(服務(wù)器)的地址信息的東西。我們可以知道的就只用smtp.sina.com.cn(這里以新浪郵箱為例),所以需要的操作就是,首先獲取主機(jī)名,得到一個(gè)HOSTENT的結(jié)構(gòu)體,調(diào)用gethostbyname,這個(gè)函數(shù)的作用就是傳入一個(gè)主機(jī)名,如上面的smtp.sina.com.cn,它會(huì)自動(dòng)的創(chuàng)建一個(gè)HOSTENT結(jié)構(gòu)體,并用相應(yīng)的主機(jī)信息來填充它。當(dāng)然,這個(gè)還不夠,需要對(duì)于SOCKADDR_IN的其它部分賦值,所以需要其它的操作,對(duì)于類變量m_SOCKADDR_IN進(jìn)行初始化,完成之后,就可以調(diào)用connect函數(shù)了,如果建立成功…………否則…………

            一般的SOCKADDR_IN初始化是:

                     m_SOCKADDR_IN.sin_family = AF_INET;

                     m_SOCKADDR_IN.sin_addr.S_un.S_addr = *(ULONG *) m_HOSTENT->h_addr_list[0];

                     m_SOCKADDR_IN.sin_port = htons(Port);

             

            完成上面的一步之后,剩下來的就是發(fā)送第一個(gè)數(shù)據(jù)報(bào)文HELO來“打個(gè)招呼”了,這個(gè)很簡(jiǎn)單,因?yàn)槭怯芯唧w的規(guī)定,所以不難得到://向服務(wù)器發(fā)送"HELO "+服務(wù)器名

            send(m_SOCKET,strTmp.c_str(),strTmp.length(),0)

            注意完成之后可以及時(shí)的調(diào)用CheckResponse來檢測(cè)結(jié)果!

             

             

             

            Validate:驗(yàn)證密碼的正確性是一個(gè)很重要的步驟。首先發(fā)送一個(gè)報(bào)文請(qǐng)求服務(wù)器響應(yīng),根據(jù)得到的信息,決定服務(wù)器是否可以連接,從而下一步操作才有可行性。如果連接失敗,那么即使用戶名和密碼都正確,也會(huì)出現(xiàn)問題。如何驗(yàn)證正確性?就是發(fā)送賬號(hào)和密碼。但是注意的是,在網(wǎng)絡(luò)SMTP傳輸中,需要使用編碼來傳輸,也就是說不是直接用的字面值,所以需要調(diào)用編碼函數(shù),先編碼,在傳輸。這里引用了外部庫ZBase64庫來實(shí)現(xiàn)編碼,解碼。先不討論這部分。發(fā)送賬號(hào)和密碼很簡(jiǎn)單,先調(diào)用加密函數(shù)編碼,然后發(fā)送,只是在這個(gè)之前,需要調(diào)用send(m_SOCKET,"AUTH LOGIN\r\n",strlen("AUTH LOGIN\r\n"),0)來發(fā)送一個(gè)報(bào)文,說是要發(fā)送賬號(hào)密碼,注意就相當(dāng)于加了一個(gè)label驗(yàn)證的作用。實(shí)際上在后面的發(fā)送數(shù)據(jù)的時(shí)候,也是按照它定義的格式,先在前面有l(wèi)abel,如Mail From,然后加上發(fā)送的內(nèi)容,注意按照標(biāo)準(zhǔn)的格式來,才能實(shí)現(xiàn)穩(wěn)定傳輸。

             

             

             

            SendData:這部分也許是最復(fù)雜的。我先來討論最簡(jiǎn)單的,就是發(fā)送文本文件,而沒有帶附件的。其實(shí),發(fā)送數(shù)據(jù)的過程和前面的Connect是一樣的(特別是第一個(gè)HELO報(bào)文的發(fā)送),但是,要具體根據(jù)RFC文檔(SMTP對(duì)應(yīng))的來決定發(fā)送的報(bào)文頭和正文格式。如果格式不正確,那么,發(fā)送也是枉然。(注意發(fā)送的數(shù)據(jù)不需要用Base64來編碼),只是,需要用一定的個(gè)數(shù),比如:

                     strTmp="MAIL FROM:<"+SendFrom+">\r\n";

                     if(send(m_SOCKET,strTmp.c_str(),strTmp.length(),0) == SOCKET_ERROR)

                     {

                              ReleaseSocket();

                              return false;

                     }

            來實(shí)現(xiàn)而已。

            這部分最好的資料就是RFC文檔,其中講到了很多實(shí)際的例子和格式要求,其它的內(nèi)容就是重復(fù)上面的代碼,很簡(jiǎn)單。

            (當(dāng)然,這部分很容易出錯(cuò),造成發(fā)送說成功,但是收不到!我開始的時(shí)候沒QUIT部分報(bào)文,所以就出現(xiàn)發(fā)送提示成功但是沒有接收到的情況!)(待續(xù)……)

             

            posted on 2010-05-02 15:59 deercoder 閱讀(3000) 評(píng)論(0)  編輯 收藏 引用 所屬分類: MFC程序設(shè)計(jì)入門
            99久久99久久精品免费看蜜桃| 中文字幕亚洲综合久久菠萝蜜| 久久久精品久久久久特色影视| 亚洲成色WWW久久网站| 久久综合色区| 国产精品成人无码久久久久久 | 精品久久久久久国产| 精品久久久久国产免费| 国产精品久久精品| 久久亚洲天堂| 久久精品国产亚洲av高清漫画| 99精品久久精品一区二区| 偷窥少妇久久久久久久久| 中文字幕久久亚洲一区| 久久国产热精品波多野结衣AV| 久久精品成人免费国产片小草| 国产精品久久久久久久久久影院| AAA级久久久精品无码片| 久久精品无码专区免费青青| 国产精品久久久久久久午夜片 | 亚洲日本va中文字幕久久| 久久99国产精品二区不卡| 国产精品福利一区二区久久| 中文精品久久久久国产网址| 91久久精品国产成人久久| 精品久久久久久中文字幕大豆网| 亚洲精品高清久久| 亚洲AV无码久久寂寞少妇| 国产精品成人99久久久久| 久久人人妻人人爽人人爽| 久久夜色精品国产噜噜麻豆| 久久久久亚洲av毛片大| 精品国产福利久久久| 日日噜噜夜夜狠狠久久丁香五月| 久久久精品无码专区不卡| 国产成人久久精品一区二区三区| 伊人久久精品影院| 久久人人爽人人爽人人片AV东京热| 97精品久久天干天天天按摩| 伊人久久大香线蕉综合影院首页| 无码任你躁久久久久久老妇|