Linux驅(qū)動開發(fā)_視頻廣告機(jī)開發(fā)、Linux進(jìn)程編程介紹

      網(wǎng)友投稿 669 2022-05-29

      昨天完成的任務(wù): Mplayer播放器安裝成功,并且實(shí)現(xiàn)基本使用。

      任務(wù)1: 學(xué)習(xí)linux下進(jìn)程編程

      1. ?進(jìn)程簡介

      進(jìn)程是操作系統(tǒng)調(diào)度的最小單元,線程是進(jìn)程內(nèi)部的執(zhí)行單元,一個(gè)進(jìn)程默認(rèn)有一個(gè)主線程。

      進(jìn)程在操作系統(tǒng)里使用PID號作為標(biāo)識符號----查看當(dāng)前終端運(yùn)行的進(jìn)程: ps 。

      每個(gè)進(jìn)程之間的資源都是獨(dú)立的。--------進(jìn)程可以自己獨(dú)立的運(yùn)行、帶main----------

      ? ?今天學(xué)習(xí)的主要任務(wù):

      1. 進(jìn)程間通信: 管道(無名管道、命名管道)、消息隊(duì)列、共享內(nèi)存、內(nèi)存映射(mmap)、信號。

      2. execl函數(shù)族: 用于啟動一個(gè)新的進(jìn)程,新的進(jìn)程開始執(zhí)行之后,會覆蓋原來進(jìn)程空間。

      3. dup2函數(shù): 復(fù)制文件表。------實(shí)現(xiàn)文件描述符重定向。 dup2(fds[1],1);

      4. 編寫廣告機(jī)播放器程序

      5. 編寫shell腳本,實(shí)現(xiàn)文件同步

      1.1 進(jìn)程創(chuàng)建

      #include

      pid_t fork(void);

      功能: 在當(dāng)前進(jìn)程里再創(chuàng)建一個(gè)子進(jìn)程。

      函數(shù)返回值: ==0 表示子進(jìn)程,>0表示父進(jìn)程,<0表示出現(xiàn)錯誤

      新創(chuàng)建的子進(jìn)程特性: 在fork成功那一刻,會將父進(jìn)程所有的資源全部拷貝一份,重新運(yùn)行。

      ? ?僵尸進(jìn)程: 子進(jìn)程先退出,父進(jìn)程沒有清理子進(jìn)程的空間。如何清理子進(jìn)程空間? wait();

      ? ?孤兒進(jìn)程: 父進(jìn)程比子進(jìn)程先退出。避免,就是父進(jìn)程要保證最后退出。

      Linux驅(qū)動開發(fā)_視頻廣告機(jī)開發(fā)、Linux進(jìn)程編程介紹

      1.2 等待子進(jìn)程退出,并且清理子進(jìn)程空間

      #include

      #include

      pid_t wait(int *status);

      函數(shù)功能: 隨機(jī)等待一個(gè)子進(jìn)程退出,并清理子進(jìn)程資源。

      返回值: 返回退出的子進(jìn)程PID號。

      函數(shù)的形參: int *status可以保存進(jìn)程退出的狀態(tài)。 exit(-1); //結(jié)束當(dāng)前進(jìn)程。

      pid_t waitpid(pid_t pid, int *status, int options);

      函數(shù): 可以指定特定的PID號。-1表示所有子進(jìn)程。

      #include

      #include

      #include

      #include

      #include

      #include

      #include

      int main(int argc,char **argv)

      {

      int pid;

      /*創(chuàng)建子進(jìn)程*/

      pid=fork();

      if(pid==0) //子進(jìn)程

      {

      printf("子進(jìn)程正常運(yùn)行!....\n");

      sleep(1);

      /*結(jié)束當(dāng)前進(jìn)程*/

      exit(0);

      }

      else if(pid>0) //父進(jìn)程

      {

      int state=0; //保存子進(jìn)程退出狀態(tài)值

      /*阻塞-等待子進(jìn)程退出*/

      wait(&state);

      printf("父進(jìn)程提示: 子進(jìn)程已經(jīng)安全退出! 子進(jìn)程退出的狀態(tài)=%d\n",state);

      }

      else

      {

      printf("進(jìn)程創(chuàng)建錯誤!");

      }

      return 0;

      }

      1.3 終止當(dāng)前進(jìn)程

      #include

      void _exit(int status);

      #include

      void _Exit(int status);

      #include

      void exit(int status);

      1.4 管道通信

      管道: FIFO文件,特性: 先入先出。

      1.4.1 無名管道: 有親緣關(guān)系之間的進(jìn)程才可以使用無名管道進(jìn)程通信。

      無名管道這個(gè)FIFO文件沒有實(shí)體。

      如果創(chuàng)建無名管道?

      #include

      int pipe(int pipefd[2]);

      函數(shù)形參: 傳入一個(gè)數(shù)組的首地址。

      管道創(chuàng)建成功之后: [0]表示(FIFO)無名管道讀端。 [1]表示(FIFO)無名管道寫端。

      #include

      #include

      #include

      #include

      #include

      #include

      #include

      #include

      int main(int argc,char **argv)

      {

      int pid;

      int pipefd[2];

      /*創(chuàng)建無名管道*/

      pipe(pipefd);

      /*創(chuàng)建子進(jìn)程*/

      pid=fork();

      if(pid==0) //子進(jìn)程

      {

      printf("子進(jìn)程正常運(yùn)行!....\n");

      sleep(1);

      char *p="1234567";

      write(pipefd[1],p,strlen(p)+1); //向管道的寫端寫入數(shù)據(jù)

      /*結(jié)束當(dāng)前進(jìn)程*/

      exit(0);

      }

      else if(pid>0) //父進(jìn)程

      {

      int state=0; //保存子進(jìn)程退出狀態(tài)值

      char buff[100];

      read(pipefd[0],buff,100); //從管道的讀端讀取數(shù)據(jù)

      printf("父進(jìn)程收到的數(shù)據(jù)=%s\n",buff);

      /*阻塞-等待子進(jìn)程退出*/

      wait(&state);

      printf("父進(jìn)程提示: 子進(jìn)程已經(jīng)安全退出! 子進(jìn)程退出的狀態(tài)=%d\n",state);

      }

      else

      {

      printf("進(jìn)程創(chuàng)建錯誤!");

      }

      return 0;

      }

      1.4.2 命名管道通信

      命名管道可以在任何進(jìn)程間通,因?yàn)槊艿朗且粋€(gè)實(shí)體文件,在磁盤可用找到該FIFO文件。

      如何在磁盤上創(chuàng)建管道文件:

      #include

      #include

      int mkfifo(const char *pathname, mode_t mode);

      管道文件不能在共享目錄下創(chuàng)建。(掛載的目錄)

      1.5 dup2函數(shù)學(xué)習(xí)

      #include

      int dup2(int oldfd, int newfd);

      示例: dup2(fds[1],1); //接下來對文件描述符1的操作都是相當(dāng)于對管道fds[1]操作。

      文件描述符在內(nèi)核里對應(yīng)的是一個(gè)文件結(jié)構(gòu)體。

      ? ?示例1:

      #include

      #include

      #include

      #include

      #include

      #include

      #include

      #include

      int main(int argc,char **argv)

      {

      int pid;

      int pipefd[2];

      /*創(chuàng)建無名管道*/

      pipe(pipefd);

      /*創(chuàng)建子進(jìn)程*/

      pid=fork();

      if(pid==0) //子進(jìn)程

      {

      printf("子進(jìn)程正常運(yùn)行!....\n");

      dup2(pipefd[1],1);

      //pipefd[1]管道寫端,1表示當(dāng)前進(jìn)程的標(biāo)準(zhǔn)輸出

      sleep(1);

      printf("---1234567---\n");

      /*結(jié)束當(dāng)前進(jìn)程*/

      exit(0);

      }

      else if(pid>0) //父進(jìn)程

      {

      int state=0; //保存子進(jìn)程退出狀態(tài)值

      char buff[100];

      read(pipefd[0],buff,100); //從管道的讀端讀取數(shù)據(jù)

      printf("父進(jìn)程收到的數(shù)據(jù)=%s\n",buff);

      /*阻塞-等待子進(jìn)程退出*/

      wait(&state);

      printf("父進(jìn)程提示: 子進(jìn)程已經(jīng)安全退出! 子進(jìn)程退出的狀態(tài)=%d\n",state);

      }

      else

      {

      printf("進(jìn)程創(chuàng)建錯誤!");

      }

      return 0;

      }

      ? ?示例2: 日志功能制作。

      #include

      #include

      #include

      #include

      #include

      #include

      #include

      #include

      int main(int argc,char **argv)

      {

      /*1.創(chuàng)建存放日志的文件*/

      int fd=open("/log.txt",O_RDWR|O_CREAT,S_IRUSR|S_IWUSR);

      /*2. 重定向(將標(biāo)準(zhǔn)輸出重定向到fd)*/

      dup2(fd,1);

      /*3. 向日志文件寫入數(shù)據(jù)*/

      printf("12345\n");

      printf("abcd\n");

      printf("日志文件測試!\n");

      /*4. 關(guān)閉日志文件*/

      close(fd);

      return 0;

      }

      1.6 execl 函數(shù)族

      #include

      extern char **environ;

      int execl(const char *path, const char *arg, ...);

      int execlp(const char *file, const char *arg, ...);

      int execle(const char *path, const char *arg,..., char * const envp[]);

      int execv(const char *path, char *const argv[]);

      int execvp(const char *file, char *const argv[]);

      execl功能介紹: 啟動新的子進(jìn)程,當(dāng)子進(jìn)程啟動成功之后會覆蓋原來的進(jìn)程空間。

      Execl函數(shù)族介紹:

      1. ?帶p表示可執(zhí)行文件可以從環(huán)境變量里獲取。

      2. ?不帶p表示,可執(zhí)行文件需要填絕對路徑。

      3. ?帶e表示最后的參數(shù),可以給新進(jìn)程設(shè)置新的環(huán)境變量。

      說明: 參數(shù)列表最后面都要加一個(gè)NULL。

      #include

      #include

      #include

      #include

      #include

      #include

      #include

      #include

      int main(int argc,char **argv)

      {

      /*以ls命令為例子,講解*/

      //execl(<可執(zhí)行程序的路徑>,<執(zhí)行的形參列表>,NULL);

      //execl("/bin/ls","ls","-l",NULL);

      //execlp("ls","ls","-l",NULL);

      //char *envp[]={"PATH1=12345",NULL};

      //execle("/bin/ls","ls","-l",NULL,envp);

      //獲取環(huán)境變量的值: getenv("PATH1");

      //char *argvs[]={"ls","-l",NULL};

      //execv("/bin/ls",argvs);

      char *argvs[]={"ls","-l",NULL};

      execvp("ls",argvs);

      printf("執(zhí)行失敗!\n");

      return 0;

      }

      //ls -l

      1.7 mplayer播放器

      Mplayer運(yùn)行有兩個(gè)模式: 1. 主模式 2.從模式

      #include

      #include

      #include

      #include

      #include

      #include

      #include

      #include

      #include

      /*

      獲取標(biāo)準(zhǔn)輸入的數(shù)據(jù)、寫給FIFO文件

      */

      void *pthread_func(void *argv)

      {

      int fd=open("/mplayer_fifo",2);

      if(fd<0)

      {

      printf("FIFO文件打開失敗!\n");

      pthread_exit(NULL); //結(jié)束當(dāng)前線程

      }

      char buff[100];

      int len;

      while(1)

      {

      printf("請輸入命令:");

      fflush(stdin); //刷新緩沖區(qū)

      fgets(buff,100,stdin); //從鍵盤上獲取數(shù)據(jù) get_percent_pos get_file_name

      len=strlen(buff); // get_file_name [0~12] [13]='\n'

      write(fd,buff,len); // get_file_name '\n'

      memset(buff,0,100);

      }

      }

      int main(int argc,char **argv)

      {

      int pid;

      /*1. 創(chuàng)建無名管道*/

      int fds[2];

      pipe(fds);

      /*2. 創(chuàng)建子進(jìn)程*/

      pid=fork();

      /*子進(jìn)程代碼: mplayer播放器*/

      if(pid==0)

      {

      /*將子進(jìn)程的標(biāo)準(zhǔn)輸出重定向到管道寫端*/

      dup2(fds[1],1);

      /*啟動子進(jìn)程*/

      execlp("mplayer","mplayer","-zoom","-x","800","-y","480","-slave","-quiet","-input","file=/mplayer_fifo","/work/video_file/Video_2018-12-11.wmv",NULL);

      }

      else /*父進(jìn)程*/

      {

      char buff[100];

      int cnt=0;

      /*創(chuàng)建新的線程: 從鍵盤上獲取輸入的數(shù)據(jù),寫給播放器的FIFO文件*/

      pthread_t threadID;

      pthread_create(&threadID,NULL,pthread_func,NULL);

      pthread_detach(threadID); //設(shè)置分離屬性

      while(1)

      {

      /*從管道的讀端讀取數(shù)據(jù): 讀取就是mplayer播放器輸出的數(shù)據(jù)*/

      cnt=read(fds[0],buff,100);

      buff[cnt]='\0';

      printf("播放器輸出的值=%s\n",buff);

      }

      }

      return 0;

      }

      任務(wù)2: 廣告機(jī)項(xiàng)目

      ? ?廣告機(jī)項(xiàng)目要求:

      廣告機(jī)應(yīng)用場景: 公交站臺、地鐵車廂、銀行前臺大廳、高速公路、公園….

      1. ?有些廣告機(jī)只有視頻播放,沒有聲音。

      2. ?廣告機(jī)都支持網(wǎng)絡(luò)視頻文件更新---->文件更新使用現(xiàn)成的服務(wù)器: FTP服務(wù)器、NFS服務(wù)器。

      (1) ?如何判斷服務(wù)器上那些文件需要下載到本地? 通過shell腳本代碼或者使用C語言。

      (2) ?更新的時(shí)間一般是固定的: 20:00 23:00 …… 通過時(shí)間函數(shù)判斷時(shí)間是否到達(dá)。

      (3) ?在視頻文件更新的時(shí)候,視頻需要停止播放,可以在屏幕上顯示提示(正在更新…..)。

      3. ?廣告機(jī)需要支持自動播放,播放一個(gè)自動切換下一個(gè)、循環(huán)播放。

      調(diào)用讀目錄、循環(huán)遍歷目錄、得到視頻文件、mplayer播放器需要使用子進(jìn)程方式啟動。

      廣告機(jī): 音量調(diào)整、選擇視頻播放…….都不是廣告機(jī)的功能---是視頻播放器的功能。

      #include #include #include #include #include #include #include #include #include #include #include #include #include /*-----------全局變量區(qū)------------*/ int log_fd; /*保存日志文件的文件描述符*/ #define LOG_FILE "/log.txt" /*日志文件存放的路徑*/ DIR *video_dir_p=NULL; /*存放視頻的目錄: 打開的目錄指針*/ int video_state=0; #define VIDEO_FILE_PATH "/work/video_file/" //存放視頻文件的目錄 #define UPDATE_HOUR 16 //更新的時(shí)間: 小時(shí) #define UPDATE_MIN 38 //更新的時(shí)間: 分鐘 #define UPDATE_SEC 00 //更新的時(shí)間: 秒 /*-------函數(shù)聲明---------*/ void DeleteListALLNode(void); /*定義鏈表使用的結(jié)構(gòu)體*/ struct VideoList { char *file_path; struct VideoList *next; }; /*鏈表頭*/ struct VideoList *ListHead=NULL; /*函數(shù): 信號處理函數(shù)*/ void exit_sighandler(int sig) { /*1. 判斷是什么信號*/ if(sig==2) { printf("用戶終止了進(jìn)程!\n"); } else if(sig==11) { printf("進(jìn)程訪問了非法內(nèi)存空間!\n"); } /*2. 殺死父進(jìn)程對應(yīng)所有子進(jìn)程*/ char cmd_buff[100]; //殺死父進(jìn)程創(chuàng)建所有子進(jìn)程,父進(jìn)程本身不受影響 sprintf(cmd_buff,"pkill -9 -P %d",getpid()); system(cmd_buff); sleep(2); /*3. 關(guān)閉打開所有的文件或者目錄*/ close(log_fd); closedir(video_dir_p); DeleteListALLNode(); /*4. 退出父進(jìn)程*/ exit(1); } /* 函數(shù)功能: 獲取本地時(shí)間,判斷是否是否到達(dá)預(yù)設(shè)的時(shí)間 */ void *Time_pthread_func(void *argv) { time_t time1; time_t time2; struct tm *system_time; char cmd_buff[100]; while(1) { time1=time(NULL); //獲取當(dāng)前系統(tǒng)的時(shí)間秒單位 if(time1!=time2) //保證if每1秒進(jìn)去一次 { time2=time1; system_time=localtime(&time1); //將秒單位時(shí)間,轉(zhuǎn)成標(biāo)準(zhǔn)時(shí)間結(jié)構(gòu) printf("%d-%d-%d\n",system_time->tm_hour,system_time->tm_min,system_time->tm_sec); /*更新的時(shí)間*/ if(system_time->tm_hour==UPDATE_HOUR && system_time->tm_min==UPDATE_MIN && system_time->tm_sec==UPDATE_SEC) { video_state=1; //表示進(jìn)程需要終止 //"pkill -9 -P <父進(jìn)程的PID>" //殺死父進(jìn)程創(chuàng)建所有子進(jìn)程,父進(jìn)程本身不受影響 sprintf(cmd_buff,"pkill -9 -P %d",getpid()); /*執(zhí)行命令*/ system(cmd_buff); printf("正在結(jié)束子進(jìn)程!\n"); pthread_exit(NULL); } } } } /* 函數(shù)功能: 掃描目錄下的所有文件,加載到鏈表里 */ void ScanDirFile() { struct dirent *dir_file; struct VideoList *head_p=ListHead; //保存鏈表頭的地址 struct VideoList *new_p=NULL; while(dir_file=readdir(video_dir_p)) { //過濾掉.和.. if(strcmp(dir_file->d_name,".")==0 || strcmp(dir_file->d_name,"..")==0) { continue; } //創(chuàng)建新節(jié)點(diǎn) new_p=(struct VideoList*)malloc(sizeof(struct VideoList)); if(new_p==NULL) { printf("創(chuàng)建新節(jié)點(diǎn)空間申請錯誤!\n"); return; } //申請存放文件名稱的空間 new_p->file_path=malloc(strlen(VIDEO_FILE_PATH)+strlen(dir_file->d_name)+1); if(new_p->file_path==NULL) { printf("申請存放文件名稱的空間錯誤!\n"); return; } //拼接路徑 strcpy(new_p->file_path,VIDEO_FILE_PATH); strcat(new_p->file_path,dir_file->d_name); printf("播放的列表:%s\n",new_p->file_path); //添加新的節(jié)點(diǎn) while(head_p->next!=NULL) { head_p=head_p->next; } head_p->next=new_p; new_p->next=NULL; } } /* 函數(shù)功能: 刪除鏈表節(jié)點(diǎn) */ void DeleteListALLNode(void) { struct VideoList *head_p=ListHead; //保存鏈表頭的地址 struct VideoList *tmp_p; struct VideoList *delete_p; if(head_p!=NULL && head_p->next==NULL) { free(head_p); //釋放鏈表頭 } else if(head_p->next!=NULL) { tmp_p=head_p->next; free(head_p); //釋放鏈表頭 while(tmp_p->next!=NULL) { delete_p=tmp_p; tmp_p=tmp_p->next; free(delete_p->file_path); free(delete_p); } free(tmp_p->file_path); free(tmp_p); } } int main(int argc,char **argv) { int pid; int state=0; struct VideoList *next_p=ListHead; /*1. 注冊將要捕獲的信號*/ signal(SIGINT,exit_sighandler); /*進(jìn)程終止信號:Ctrl+C*/ signal(SIGSEGV,exit_sighandler); /*進(jìn)程訪問了非法內(nèi)存*/ /*2. 創(chuàng)建日志文件: 保存mplayer播放器的輸出*/ log_fd=open(LOG_FILE,O_RDWR|O_CREAT,S_IRUSR|S_IWUSR); /*3. 打開目錄*/ video_dir_p=opendir(VIDEO_FILE_PATH); if(video_dir_p==NULL) { printf("%s 存放視頻的目錄打開失敗!\n",VIDEO_FILE_PATH); exit(1); } /*4. 創(chuàng)建新的線程:判斷更新時(shí)間*/ pthread_t threadID; pthread_create(&threadID,NULL,Time_pthread_func,NULL); pthread_detach(threadID); //設(shè)置分離屬性 /*5. 遍歷目錄,更新鏈表*/ //創(chuàng)建鏈表頭 ListHead=(struct VideoList*)malloc(sizeof(struct VideoList)); if(ListHead==NULL) { printf("鏈表頭創(chuàng)建失敗!\n"); exit(1); } ListHead->next=NULL; //下個(gè)節(jié)點(diǎn)為NULL //掃描目錄,并將目錄下的文件添加到鏈表 ScanDirFile(); next_p=ListHead; //鏈表頭 next_p=next_p->next; //取出數(shù)據(jù)節(jié)點(diǎn) LOOP: //該標(biāo)簽表示繼續(xù)播放下一個(gè)視頻時(shí),重復(fù)創(chuàng)建子進(jìn)程 printf("正在播放視頻名稱:%s\n",next_p->file_path); /*創(chuàng)建子進(jìn)程*/ pid=fork(); /*子進(jìn)程代碼: mplayer播放器*/ if(pid==0) { /*將子進(jìn)程的標(biāo)準(zhǔn)輸出重定向到日志文件*/ dup2(log_fd,1); /*啟動子進(jìn)程*/ execlp("mplayer","mplayer","-zoom","-x","800","-y","480","-slave","-quiet","-input","file=/mplayer_fifo",next_p->file_path,NULL); } /*父進(jìn)程代碼: 控制播放*/ else { /*等待子進(jìn)程退出*/ wait(&state); //判斷是否需要結(jié)束當(dāng)前進(jìn)程 if(video_state==1) { /*執(zhí)行外部腳本: 啟動視頻文件更新*/ system("./update_video.sh"); /*退出父進(jìn)程*/ DeleteListALLNode(); close(log_fd); closedir(video_dir_p); exit(0); } /*遍歷鏈表的下一個(gè)節(jié)點(diǎn),取出文件名稱,傳遞給子進(jìn)程*/ if(next_p->next==NULL) //表示視頻播放完畢 { printf("視頻播放完畢---->鏈表歸位!\n"); next_p=ListHead; //鏈表頭 next_p=next_p->next; //取出數(shù)據(jù)節(jié)點(diǎn) } next_p=next_p->next; //取出數(shù)據(jù)節(jié)點(diǎn) /*再次啟動子進(jìn)程,播放下一個(gè)視頻*/ goto LOOP; } return 0; }

      Linux 任務(wù)調(diào)度 視頻

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:25分鐘!一鍵部署Oracle 11GR2 HA 單機(jī)集群
      下一篇:沒有固定賽道的比拼
      相關(guān)文章
      亚洲老熟女@TubeumTV| 亚洲国产成人影院播放| 亚洲日韩一页精品发布| 亚洲国产一区二区三区| 精品亚洲成A人在线观看青青| 亚洲熟伦熟女专区hd高清| 91在线亚洲综合在线| 亚洲色精品VR一区区三区| 欧洲 亚洲 国产图片综合| 亚洲视频在线观看2018| 亚洲综合av一区二区三区| 亚洲狠狠成人综合网| 亚洲乱亚洲乱妇24p| 色欲aⅴ亚洲情无码AV蜜桃| 日本系列1页亚洲系列| 亚洲XX00视频| 久久久久噜噜噜亚洲熟女综合| 国产精品亚洲玖玖玖在线观看| 亚洲伊人久久综合影院| 国产亚洲精品AA片在线观看不加载| 国产精品V亚洲精品V日韩精品 | 中文字幕亚洲精品资源网| 亚洲丝袜美腿视频| 亚洲综合久久1区2区3区 | 亚洲Av无码国产情品久久| 色偷偷亚洲第一综合网| 亚洲色偷拍区另类无码专区| 亚洲AV日韩AV永久无码色欲| 色五月五月丁香亚洲综合网| 亚洲第一成人影院| 国产精品亚洲视频| 亚洲大尺度无码无码专区| 久久精品国产亚洲AV大全| 亚洲日韩乱码中文无码蜜桃| 亚洲人成小说网站色| 亚洲第一街区偷拍街拍| 亚洲男人av香蕉爽爽爽爽| 亚洲中文字幕在线第六区| 亚洲AV无码不卡在线播放| 亚洲成人午夜电影| 亚洲国产精品网站在线播放|