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

首頁 > 編程 > C++ > 正文

C++ socket實現miniFTP

2020-01-26 14:23:57
字體:
來源:轉載
供稿:網友

本文實例為大家分享了C++ socket實現miniFTP的方法,供大家參考,具體內容如下

客戶端:

服務端:

建立連接

        連接使用 TCP 連接,服務器和客戶端分別創建自己的套接字一端,服務器等待連接,客戶端發起連接(并指定服務器 ip)。在兩者端口號一致且不被占用的情況下,連接建立。
        在整個過程中,服務器對每一個來訪的客戶端建立一個連接,在客戶未請求與服務器斷開時,該連接一直存在,用戶可以不斷向服務器發出請求。(持久性、流水線型連接 )
        客戶端斷開后,關閉客戶端的套接字部分,服務器繼續等待新的連接。服務器一次只能處理一個客戶端的連接,不支持并發訪問。

PDU 格式

        由于 ftp 應當支持幾乎任意類型文件,而幾乎所有類型文件都能用二進制來解析,所以我們采用了二進制的格式來讀取以及寫入文件。在整個過程中,我們并不關心文件的具體內容,也無需在程序中解析文件,而是將其當作數據流看待。
        受到緩存區大小的限制,我們無法一次性傳輸整個文件,所以我們將文件按緩存區大小拆分成數據包分批發送,我們可以將數據及時從緩存區寫入文件,這樣就讓出了緩存區空間。數據包僅僅包含數據,不包含頭部或尾部信息。
        此外,接收文件時,recv()函數將會循環調用,因此,我們需要一個信號來通知什么時候發送完畢。
        一個想法是發送終止信號,這是可行的,但更好的方法是在一開始發送文件總字節數,讓接收方根據剩余字節大小判斷什么時候接收完畢。因為在寫入文件時,我們需要指定寫入的字節數,尤其是在發來的數據流字節數不等于緩沖區大小時。寫入字節數的錯誤會導致文件受損。

接收確認

        我們知道 TCP 是可靠傳輸協議,它采取了一系列措施來保證傳輸不會出錯。所以在使用 TCP 連接時,我們相信數據在鏈路層上沒有出差錯,它一定會成功發送到對方手上。但是在客戶端接收服務器發來的文件的時候,我們仍然需要服務器發來確認信息。原因在于,雖然我們可以保證鏈路層不出錯,但是我們無法保證應用層不出錯。例如,客戶端可能會給出錯誤的文件名,因為接收不到服務器發來的信息,所以會陷入空等狀態。

ftpClient.h

#pragma  #include<winsock.h> class ftpClient { private:   enum {     SERVER_PORT = 9999,     BUFFER_SIZE = 4096   };   sockaddr_in serverChannel;   char buffer[BUFFER_SIZE];   int serverSocket;   int clientSocket;   bool isConnect;   char name[50];    bool getFile();   bool putFile();   bool acknowledge();   bool sendRequest(char* instruction);   bool connect2Host(const char* hostName);   bool getWorkDir();  public:   ftpClient();   ~ftpClient();   void start(); }; 

ftpClient.cpp

#define _CRT_SECURE_NO_WARNINGS #include"ftpClient.h" #include<cstdio> #include<io.h> #include<cstring> #include<fstream>  ftpClient::ftpClient() {   WORD wVersionRequested;   WSADATA wsaData;   int ret;    //WinSock初始化:   wVersionRequested = MAKEWORD(2, 2);//希望使用的WinSock DLL的版本   ret = WSAStartup(wVersionRequested, &wsaData);   if (ret != 0)   {     printf("WSAStartup() failed!/n");   }   //確認WinSock DLL支持版本2.2:   if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)   {     WSACleanup();     printf("Invalid Winsock version!/n");   }   isConnect = false; }  void ftpClient::start() {   char c[100];   char d[100];   printf("這里是FTP客戶端,您可以輸入help查看操作方法,輸入quit退出客戶端/n");    while (1) {     scanf("%s", c);     if (strcmp(c, "help") == 0) {       printf("get [fileName]  --  下載文件/n"         "put [fileName]  --  上傳文件/n"         "ftp [ip]     --  登錄FTP/n"         "pwd        --  顯示服務器當前工作文件夾/n"         "cd [dirName]   --  更改當前文件夾/n"         "close       --  關閉與當前ftp的連接/n"         "quit       --  退出客戶端/n"         );     }     else if (strcmp(c, "get") == 0) {       scanf("%s", d);       strcat(c, " ");       strcat(c, d);       if (!isConnect) {         printf("you haven't connected to any server!/n");       }       else sendRequest(c);     }     else if (strcmp(c, "put") == 0) {       scanf("%s", d);       strcat(c, " ");       strcat(c, d);       if (!isConnect) {         printf("you haven't connected to any server!/n");       }       else sendRequest(c);     }     else if (strcmp(c, "ftp") == 0) {       scanf("%s", d);       if (!isConnect&&connect2Host(d)) {         isConnect = true;       }       else if(isConnect){         printf("you have already connected to server/n"           "please close the connection before connect to a new server/n");       }     }     else if (strcmp(c, "pwd") == 0) {       if (!isConnect) {         printf("you haven't connected to any server!/n");       }       else sendRequest(c);     }     else if (strcmp(c, "cd") == 0) {       scanf("%s", d);       strcat(c, " ");       strcat(c, d);       if (!isConnect) {         printf("you haven't connected to any server!/n");       }       else sendRequest(c);     }     else if (strcmp(c, "quit") == 0) {       if (isConnect) {         strcpy(c, "close");         isConnect = false;         send(clientSocket, c, strlen(c) + 1, 0);         closesocket(clientSocket);       }       break;     }     else if (strcmp(c, "close") == 0) {       if (isConnect) {         isConnect = false;         send(clientSocket, c, strlen(c) + 1, 0);         closesocket(clientSocket);       }     }     else {       printf("syntex error/n");     }   } }  bool ftpClient::connect2Host(const char* hostName) {   //創建socket   clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);    if (clientSocket < 0) {     printf("cannot create socket/n");     return false;   }   else printf("successfully create socket/n");   memset(&serverChannel, 0, sizeof(serverChannel));//初始化為0    serverChannel.sin_family = AF_INET;//channel協議家族AF_INET   serverChannel.sin_addr.S_un.S_addr = inet_addr(hostName);//地址   serverChannel.sin_port = htons(SERVER_PORT);//服務器端口                          //建立連接   serverSocket = connect(clientSocket, (sockaddr*)&serverChannel, sizeof(serverChannel));    if (serverSocket < 0) {     printf("cannot connect to the host/n");     return false;   }   else {     printf("successfully connect to the host/n");     return true;   } }  bool ftpClient::sendRequest(char* instruction) {   int r = send(clientSocket, instruction, strlen(instruction) + 1, 0);   if (r == SOCKET_ERROR) {     printf("request failed/n");     return false;   }   else {     printf("request success/n");     char opt[5];     int i = 0, j = 0;     while (instruction[i] != ' '&&instruction[i] != '/0') {       opt[i] = instruction[i];       i++;     }     opt[i] = '/0';     i++;     while (instruction[i] != '/0') {       name[j] = instruction[i];       i++, j++;     }     name[j] = '/0';     if (strcmp(opt, "get") == 0) {       if (getFile()) {         printf("successfully download/n");       }       else printf("download failed/n");     }     else if (strcmp(opt, "put") == 0) {       if (putFile()) {         printf("successfully upload/n");       }       else printf("upload failed/n");     }     else if (strcmp(opt, "pwd") == 0) {       if (!getWorkDir())         printf("get work directory failed/n");     }     else if (strcmp(opt, "cd") == 0) {       printf("operation finished/n");     }     else {       printf("syntex error/n");       return false;     }     return true;   } }  bool ftpClient::getFile() {   memset(buffer, 0, sizeof(buffer));   int ret;   char length[20];   ret = recv(clientSocket, length, sizeof(length), 0);   if (ret == SOCKET_ERROR) {     return false;   }   else if (strcmp(length, "NAK") == 0) {     return false;   }   int size = atoi(length);   std::ofstream out;    out.open(name, std::ios::binary);   if (!out) {     printf("cannot save the file/n");     return false;   }   while (size>0) {     ret = recv(clientSocket, buffer, BUFFER_SIZE, 0);     int s = size < BUFFER_SIZE ? size : BUFFER_SIZE;     if (ret == SOCKET_ERROR) {       out.close();       return false;     }     else if (strcmp(buffer, "NAK") == 0) {       out.close();       return false;     }     else {       out.write(buffer, s);     }     size -= BUFFER_SIZE;   }   out.close();   return acknowledge(); }  bool ftpClient::putFile() {   std::ifstream in;   //打開文件   in.open(name, std::ios::binary);   if (!in) {     printf("cannot open the file/n");     return false;   }   memset(buffer, 0, sizeof(buffer));   //得到文件的字節數   in.seekg(0, std::ios_base::end);   int sp = in.tellg();   int total_size = 0;   int r;   char length[20];   sprintf(length, "%d", sp);    //發送字節   r = send(clientSocket, length, sizeof(length), 0);   if (r == SOCKET_ERROR) {     return false;   }   while (sp > 0) {     in.clear();     in.seekg(total_size, std::ios_base::beg);     memset(buffer, 0, sizeof(buffer));     //讀取文件     in.read(buffer, sizeof(buffer));     int size = sp < BUFFER_SIZE ? sp : BUFFER_SIZE;     total_size += size;     //發送文件     r = send(clientSocket, buffer, size, 0);      sp -= size;     if (r == SOCKET_ERROR) {       in.close();       return false;     }   }   in.close(); }  bool ftpClient::getWorkDir() {   printf("getWorkDir/n");   memset(buffer, 0, sizeof(buffer));   int ret;   char length[20];   ret = recv(clientSocket, length, sizeof(length), 0);   if (ret == SOCKET_ERROR) {     return false;   }   int size = atoi(length);   while (size>0) {     ret = recv(clientSocket, buffer, BUFFER_SIZE, 0);     if (ret == SOCKET_ERROR) {       return false;     }     else {       printf("%s", buffer);     }     size -= BUFFER_SIZE;   }   return true; }  bool ftpClient::acknowledge() {   int ret = recv(clientSocket, buffer, BUFFER_SIZE, 0);   if (ret > 0) {     if (strcmp(buffer, "NAK") == 0)return false;     else if (strcmp(buffer, "ACK") == 0)return true;   } }  ftpClient::~ftpClient() {   if (isConnect) {     isConnect = false;     char c[6];     strcpy(c, "close");     send(clientSocket, c, strlen(c) + 1, 0);     closesocket(clientSocket);   } } 

main.cpp

#define _CRT_SECURE_NO_WARNINGS #define _WINSOCK_DEPRECATED_NO_WARNINGS #pragma(lib,"ws2_32.lib") #include"ftpClient.h" #include<stdio.h>  int main() {   ftpClient a;   a.start();   return 0; } 

ftpServer.h

#pragma once #include<winsock.h>  class ftpServer { private:   enum {     SERVER_PORT = 9999,     BUFFER_SIZE = 4096,     QUEUE_SIZE = 10   };   char buffer[BUFFER_SIZE];   sockaddr_in serverChannel;   char name[50];   char workDir[100]; //store like C:/Users MARK:字符串末沒有斜線?。?  int serverSocket; //socket   int clientSocket;   bool sendFile();   bool receiveFile();   bool doPwd();   bool doCd();   bool isValidPath(char* path); public:   ftpServer();   bool start();//開啟服務器 }; ftpServer.cpp

#define _CRT_SECURE_NO_WARNINGS  #include"ftpServer.h" #include<cstdio> #include<cstdlib> #include<fstream> #include<cstring>  ftpServer::ftpServer() {   WORD wVersionRequested;   WSADATA wsaData;   int ret;    //WinSock初始化:   wVersionRequested = MAKEWORD(2, 2);//希望使用的WinSock DLL的版本   ret = WSAStartup(wVersionRequested, &wsaData);   if (ret != 0)   {     printf("WSAStartup() failed!/n");   }   //確認WinSock DLL支持版本2.2:   if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)   {     WSACleanup();     printf("Invalid Winsock version!/n");   }   //workDir初始化為當前路徑   system("cd > tempFile");   std::ifstream in("tempFile", std::ifstream::in);   in >> workDir;   in.close(); }  bool ftpServer::start() {   int on = 1;    //初始化服務器   memset(&serverChannel, 0, sizeof(serverChannel));   serverChannel.sin_family = AF_INET;   serverChannel.sin_addr.s_addr = htonl(INADDR_ANY);   serverChannel.sin_port = htons(SERVER_PORT);    //創建套接字   this->serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);   if (serverSocket < 0) {     printf("cannot create socket/n");     return false;   }   else printf("successfully create socket/n");   setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR,     (char*)&on, sizeof(on));    //綁定   int b = bind(serverSocket, (sockaddr*)&serverChannel,     sizeof(serverChannel));   if (b < 0) {     printf("bind error/n");     return false;   }   else printf("successfully bind/n");   //監聽   int l = listen(serverSocket, QUEUE_SIZE);   if (l < 0) {     printf("listen failed/n");     return false;   }   else printf("successfully listen/n");   int len = sizeof(serverChannel);   //服務器等待連接   while (1) {     printf("waiting for connection.../n");     //接受一個連接     clientSocket = accept(serverSocket, (sockaddr*)&serverChannel,       &len);     if (clientSocket < 0) {       printf("accept failed/n");     }     else {       printf("successfully connect/n");       while (1) {         memset(buffer, 0, sizeof(buffer));         int ret;          ret = recv(clientSocket, buffer, BUFFER_SIZE, 0);          if (ret == SOCKET_ERROR) {           printf("receive failed/n");         }         else {           char opt[50];           printf("successfully receive/n");           int i = 0, j = 0;           printf("buffer = %s/n", buffer);           while (buffer[i] != ' '&&buffer[i] != '/0') {             opt[i] = buffer[i];             i++;           }           opt[i] = '/0';           if (buffer[i] != '/0') {             i++;           }           while (buffer[i] != '/0') {             name[j] = buffer[i];             i++, j++;           }           name[j] = '/0';            if (strcmp(opt, "get") == 0) {             char ret[4];             if (!sendFile()) {               strcpy(ret, "NAK");               send(clientSocket, ret, sizeof(ret), 0);             }             else {               strcpy(ret, "ACK");               send(clientSocket, ret, sizeof(ret), 0);             }           }           else if (strcmp(opt, "put") == 0) {             receiveFile();           }           else if (strcmp(opt, "pwd") == 0) {             doPwd();           }           else if (strcmp(opt, "cd") == 0) {             doCd();           }           else if (strcmp(opt, "close") == 0) {             break;           }           else {             printf("syntex error/n");           }         }       }     }   }   return true; }  bool ftpServer::sendFile() {   std::ifstream in;   char path[100];   strcpy(path, workDir);   strcat(path, "http://");   strcat(path, name);    in.open(path, std::ios::binary);   if (!in) {     printf("cannot open the file/n");     return false;   }   memset(buffer, 0, sizeof(buffer));   in.seekg(0, std::ios_base::end);   int sp = in.tellg();   int total_size = 0;   int r;   char length[20];   sprintf(length, "%d", sp);      r = send(clientSocket, length, sizeof(length), 0);    if (r == SOCKET_ERROR) {     printf("send failed/n");     return false;   }   else {     printf("send success/n");   }    while (sp > 0) {     in.clear();     in.seekg(total_size, std::ios_base::beg);     memset(buffer, 0, sizeof(buffer));     in.read(buffer, sizeof(buffer));     int size = sp < BUFFER_SIZE ? sp : BUFFER_SIZE;     total_size += size;     r = send(clientSocket, buffer, size, 0);      sp -= size;     if (r == SOCKET_ERROR) {       printf("send failed/n");       return false;     }     else {       printf("send success/n");     }   }   in.close();   return true; }  bool ftpServer::receiveFile() {   char path[100];   strcpy(path, workDir);   strcat(path, "http://");   strcat(path, name);   memset(buffer, 0, sizeof(buffer));   int ret;   char length[20];   ret = recv(clientSocket, length, sizeof(length), 0);   if (ret == SOCKET_ERROR) {     printf("receive failed/n");     return false;   }   else {     printf("successfully receive/n");   }   int size = atoi(length);   std::ofstream out;    out.open(path, std::ios::binary);   if (!out) {     printf("cannot save the file/n");     return false;   }   while (size>0) {     int s = size < BUFFER_SIZE ? size : BUFFER_SIZE;     ret = recv(clientSocket, buffer, BUFFER_SIZE, 0);     if (ret == SOCKET_ERROR) {       printf("receive failed/n");       break;     }     else {       printf("successfully receive/n");       out.write(buffer, s);     }     size -= BUFFER_SIZE;   }   out.close();   return true; }  bool ftpServer::doPwd() {   char temCMD[150];   memset(temCMD, 0, sizeof(temCMD));   strcat(temCMD, "echo ");   strcat(temCMD, workDir);   strcat(temCMD, " > tempFile");   system(temCMD);   memset(temCMD, 0, sizeof(temCMD));   strcat(temCMD, "dir /b ");   strcat(temCMD, workDir);   strcat(temCMD, " >> tempFile");   system(temCMD);    std::ifstream in("tempFile", std::fstream::in);   if (!in) {     printf("cannot open the file/n");     return false;   }   memset(buffer, 0, sizeof(buffer));   in.seekg(0, std::ios_base::end);   int sp = in.tellg();   int total_size = 0;   int r;   char length[20];   sprintf(length, "%d", sp);   r = send(clientSocket, length, sizeof(length), 0);    if (r == SOCKET_ERROR) {     printf("send failed/n");     return false;   }   else {     printf("send success/n");   }   while (sp > 0) {     in.clear();     in.seekg(total_size, std::ios_base::beg);     memset(buffer, 0, sizeof(buffer));     in.read(buffer, sizeof(buffer));     int size = sp < BUFFER_SIZE ? sp : BUFFER_SIZE;     total_size += size;     printf("transfer size = %d/n", total_size);     r = send(clientSocket, buffer, size, 0);      sp -= size;     if (r == SOCKET_ERROR) {       printf("send failed/n");       return false;     }     else {       printf("send success/n");     }   }   in.close();   return true; }  bool ftpServer::isValidPath(char* path) {   char temCMD[100];   memset(temCMD, 0, sizeof(temCMD));   strcat(temCMD, "cd ");   strcat(temCMD, path);   int res = system(temCMD);   return res == 0; }  bool ftpServer::doCd() {   for (int i = 0; name[i] != '/0'; ++i) {     if (name[i] == '/')       name[i] = '//';   }   if (name[0] == '.'&&name[1] == '.') {     char temDir[100];     strcpy(temDir, workDir);     for (int i = sizeof(temDir); i >= 0; --i) {       if (temDir[i] == '//') {         temDir[i] = '/0';         break;       }     }     strcat(temDir, name + 2);     if (isValidPath(temDir)) {       strcpy(workDir, temDir);     }     else {       return false;     }   }   else if (name[0] == '.'&&name[1] != '.') {     char temDir[100];     strcpy(temDir, workDir);     strcat(temDir, name + 1);     if (isValidPath(temDir)) {       strcpy(workDir, temDir);     }     else {       return false;     }   }   else if (name[1] == ':') {     if (isValidPath(name)) {       strcpy(workDir, name);     }     else {       return false;     }   }   else {     char temDir[100];     strcpy(temDir, workDir);     strcat(temDir, "http://");     strcat(temDir, name);     if (isValidPath(temDir)) {       strcpy(workDir, temDir);     }     else {       return false;     }   }   return true; } 

main.cpp

#include"ftpServer.h" #pragma(lib,"ws2_32.lib") int main() {  ftpServer f;  f.start(); } 

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美午夜视频在线观看| 69久久夜色精品国产69乱青草| 欧美成人精品不卡视频在线观看| 亚洲福利精品在线| 538国产精品视频一区二区| 亚洲综合中文字幕在线观看| 国产精品久久电影观看| 91美女片黄在线观| 色偷偷偷综合中文字幕;dd| 欧美黄色片在线观看| 色哟哟入口国产精品| 亚洲伦理中文字幕| 日韩欧美高清在线视频| 国产成人精品av在线| 欧美一级片一区| 这里只有精品在线观看| xvideos亚洲人网站| 国产91精品网站| 欧美福利视频在线| 日韩网站在线观看| 午夜精品蜜臀一区二区三区免费| 久久久久久九九九| 欧美性少妇18aaaa视频| 日日噜噜噜夜夜爽亚洲精品| 亚洲精品久久久久久久久久久| 在线亚洲午夜片av大片| 久久精品国产成人精品| 午夜精品久久久久久久99黑人| 精品久久久久久久久久久久久久| 亚洲国内精品视频| 欧美性猛交xxx| 亚洲free嫩bbb| 97成人在线视频| 青青在线视频一区二区三区| 91九色视频在线| 国产精品久久999| 亚洲国产免费av| 国产成人精品a视频一区www| 最好看的2019的中文字幕视频| 一本色道久久88综合亚洲精品ⅰ| 日韩精品免费在线播放| 狠狠躁夜夜躁人人躁婷婷91| 国产精品91久久久久久| 亚洲精品中文字幕av| 日本一区二区在线免费播放| 一本一道久久a久久精品逆3p| 欧美国产中文字幕| 久久中文久久字幕| 亚洲国产日韩欧美在线图片| 性金发美女69hd大尺寸| 欧美性一区二区三区| 欧美日韩国产第一页| 国产精品九九久久久久久久| 国产一区玩具在线观看| 久久久精品中文字幕| 亚洲欧洲在线视频| 黑人巨大精品欧美一区二区三区| 在线精品视频视频中文字幕| 亚洲天堂开心观看| 中文字幕久久亚洲| 精品国产91久久久| 91午夜在线播放| 亚洲欧洲黄色网| 国产一区二中文字幕在线看| 日韩在线观看免费全集电视剧网站| 亚洲国产97在线精品一区| 日韩高清电影免费观看完整版| 欧美成人亚洲成人日韩成人| 国产亚洲欧美视频| 91免费高清视频| 欧美性生活大片免费观看网址| 久久九九亚洲综合| 欧美精品久久久久久久久久| 精品日本高清在线播放| 国产美女精彩久久| 国内精品国产三级国产在线专| 国模精品视频一区二区| 91精品国产自产在线观看永久| 亚洲少妇激情视频| 亚洲xxxxx电影| 国产欧美一区二区白浆黑人| 免费成人高清视频| 亚洲自拍偷拍视频| 一色桃子一区二区| 国产在线a不卡| 蜜月aⅴ免费一区二区三区| 日韩暖暖在线视频| 亚洲视频免费一区| 亚洲黄色免费三级| 精品久久久久久久中文字幕| 国产精品亚洲一区二区三区| 久久综合色影院| 伊人亚洲福利一区二区三区| 亚洲韩国日本中文字幕| 黄色精品一区二区| 久久久免费观看视频| 中文字幕欧美精品日韩中文字幕| 国产成人精品一区二区三区| 超碰精品一区二区三区乱码| 日韩在线免费视频观看| 91视频国产高清| 欧美裸体xxxxx| 日韩www在线| 91精品久久久久久久久不口人| 欧美一区二区影院| 成人免费福利在线| 国产福利视频一区二区| 色99之美女主播在线视频| 久久精品夜夜夜夜夜久久| 国产精品一区二区三区久久| 日本一区二区三区在线播放| 亚洲bt天天射| 91高清免费在线观看| 国产欧美一区二区白浆黑人| 欧美极品xxxx| 精品在线小视频| 中文字幕亚洲欧美日韩在线不卡| 久久久国产视频91| 亚洲网站在线看| 久久青草精品视频免费观看| 国产女人18毛片水18精品| 欧美裸体男粗大视频在线观看| 国产一区二区三区在线| 国产亚洲欧洲黄色| 日韩高清中文字幕| 亚洲精品资源在线| 高清一区二区三区四区五区| 久久影视免费观看| 午夜精品一区二区三区在线视| 国产精品视频自在线| 国产一区二区在线免费| 欧美亚洲成人xxx| 国产精品丝袜白浆摸在线| 91色视频在线观看| 欧美亚洲另类视频| 精品日韩视频在线观看| 久久久久国产精品免费| 欧美性xxxxx极品娇小| 日韩一区二区三区在线播放| 国产精品爽黄69| 亚洲男人7777| 97视频在线观看成人| 国产精品极品美女粉嫩高清在线| 亚洲人在线观看| 欧美日本精品在线| 国产精品成人一区二区三区吃奶| 国产成人一区二区三区小说| 91精品免费看| 欧美国产在线电影| 日本欧美一级片| 国产日韩欧美自拍| 性欧美暴力猛交69hd| 国产在线一区二区三区| 日韩在线精品一区| 久久全国免费视频| 久久久精品日本| 亚洲系列中文字幕| 亚洲欧美在线看| 久久精品亚洲热| 国产欧美在线视频| 免费91在线视频| 色青青草原桃花久久综合| 欧美日韩国产一中文字不卡| 在线视频亚洲欧美|